diff --git a/WebContent/resources/view.js b/WebContent/resources/view.js
index 29bc08d3f6..aa2d285508 100644
--- a/WebContent/resources/view.js
+++ b/WebContent/resources/view.js
@@ -62,6 +62,10 @@ mango.view.setMessages = function(state) {
var warningNode = $("c"+ state.id +"Warning");
if (warningNode && state.messages != null) {
$set("c"+ state.id +"Messages", state.messages);
+ var warningIconNode = $("c"+ state.id +"WarningIcon");
+ if(warningIconNode) {
+ $set("c"+ state.id +"WarningIcon", state.warningIcon);
+ }
if (state.messages)
show(warningNode);
else
diff --git a/build.gradle b/build.gradle
index eb9a134bfb..d4ef81117f 100644
--- a/build.gradle
+++ b/build.gradle
@@ -235,6 +235,8 @@ test {
includeTestsMatching "com.serotonin.mango.vo.report.ImageChartUtilsTestsSuite"
includeTestsMatching "org.scada_lts.serorepl.utils.StringUtilsTestsSuite"
includeTestsMatching "org.scada_lts.monitor.ConcurrentMonitoredValuesTest"
+ includeTestsMatching "com.serotonin.mango.rt.dataSource.DataPointUnreliableUtilsTest"
+ includeTestsMatching "com.serotonin.mango.rt.dataSource.InitializeDataSourceRtTestsSuite"
includeTestsMatching "com.serotonin.mango.util.AddLimitIfWithoutSqlDataSourceUtilsTest"
includeTestsMatching "com.serotonin.mango.util.StartStopDataPointsUtilsTestsSuite"
includeTestsMatching "org.scada_lts.utils.BlockingQueuesUtilsTest"
@@ -242,9 +244,11 @@ test {
includeTestsMatching "org.scada_lts.web.security.XssUtilsTest"
}
+ failFast = true
+
testLogging {
- //exceptionFormat = "full"
+ exceptionFormat = "full"
showStandardStreams = true
afterTest { desc, result ->
diff --git a/src/br/org/scadabr/api/dao/MangoDaoImpl.java b/src/br/org/scadabr/api/dao/MangoDaoImpl.java
index 065dddef6d..a001e19970 100644
--- a/src/br/org/scadabr/api/dao/MangoDaoImpl.java
+++ b/src/br/org/scadabr/api/dao/MangoDaoImpl.java
@@ -1237,7 +1237,7 @@ public int configureDataPoint(int dataSourceId,
mangoPoint.setPointLocator(mangoLocator);
DwrResponseI18n validate = new DwrResponseI18n();
validate(mangoPoint, validate);
- mangoLocator.validate(validate);
+ mangoLocator.validate(validate, point.getId());
if (validate.getHasMessages()) {
throw new ScadaBRAPIException(new APIError(
ErrorCode.INVALID_PARAMETER,
diff --git a/src/br/org/scadabr/rt/dataSource/alpha2/Alpha2DataSource.java b/src/br/org/scadabr/rt/dataSource/alpha2/Alpha2DataSource.java
index d8d427c075..6e92af5a81 100644
--- a/src/br/org/scadabr/rt/dataSource/alpha2/Alpha2DataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/alpha2/Alpha2DataSource.java
@@ -22,10 +22,14 @@
import com.serotonin.mango.rt.dataImage.SetPointSource;
import com.serotonin.mango.rt.dataImage.types.MangoValue;
import com.serotonin.mango.rt.dataSource.PollingDataSource;
+import com.serotonin.mango.util.LoggingUtils;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
public class Alpha2DataSource extends PollingDataSource {
+ private static final Log LOG = LogFactory.getLog(Alpha2DataSource.class);
public static final int POINT_READ_EXCEPTION_EVENT = 1;
public static final int POINT_WRITE_EXCEPTION_EVENT = 2;
public static final int DATA_SOURCE_EXCEPTION_EVENT = 3;
@@ -65,6 +69,7 @@ protected void doPoll(long time) {
MangoValue value = MangoValue.stringToValue(deviceValue
.getValue(), rt.getDataTypeId());
rt.updatePointValue(new PointValueTime(value, time));
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, rt);
}
}
@@ -131,18 +136,18 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
master.runController();
else
master.stopController();
- } else
+ } else {
master.write(devices);
- } catch (Exception e) {
- treatException(POINT_WRITE_EXCEPTION_EVENT, e, System
- .currentTimeMillis());
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ }
+ } catch (Throwable e) {
+ treatException(POINT_WRITE_EXCEPTION_EVENT, e, System.currentTimeMillis(), dataPoint);
}
}
@Override
public void initialize() {
- super.initialize();
SerialParameters parameters = new SerialParameters();
parameters.setBaudRate(vo.getBaudRate());
@@ -155,10 +160,13 @@ public void initialize() {
try {
master.init();
master.lineCheck();
- } catch (Exception e) {
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
treatException(DATA_SOURCE_EXCEPTION_EVENT, e, System
.currentTimeMillis());
+ return;
}
+ super.initialize();
}
@@ -166,13 +174,19 @@ public void initialize() {
public void terminate() {
super.terminate();
try {
- master.terminate();
- } catch (Exception e) {
- e.printStackTrace();
+ if(master != null)
+ master.terminate();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this), e);
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
}
}
- private void treatException(int exceptionType, Exception e, long time) {
+ private void treatException(int exceptionType, Throwable e, long time) {
+ LOG.warn(LoggingUtils.info(e, this), e);
if (e instanceof COMMException) {
raiseEvent(exceptionType, time, true, new LocalizableMessage(
"alpha2.commException", vo.getName(), e.getMessage()));
@@ -190,37 +204,22 @@ private void treatException(int exceptionType, Exception e, long time) {
}
}
- // public static void main(String[] args) {
- // List
lista = new ArrayList();
- //
- // for (int i = 0; i < 250; i++) {
- // lista.add("device " + i);
- // }
- //
- // final int maxNum = 82;
- // List> messages = new ArrayList>();
- //
- // int numMessages = lista.size() % maxNum == 0 ? ((int) (lista.size() /
- // maxNum))
- // : ((int) (lista.size() / maxNum)) + 1;
- //
- // for (int i = 0; i < numMessages; i++) {
- // List temp;
- // if (i == numMessages - 1) {
- // temp = lista.subList(0 + (i * (maxNum)), lista.size());
- // } else {
- // int init = 0 + (i * (maxNum));
- // int end = (maxNum) + ((maxNum) * i);
- // temp = lista.subList(init, end);
- //
- // }
- // messages.add(temp);
- // }
- // System.out.println("Enviar " + messages.size() + " mensagens!");
- // for (List list : messages) {
- // System.out.println("Mensagem: " + list.size());
- // }
- //
- // }
-
+ private void treatException(int exceptionType, Throwable e, long time, DataPointRT dataPointRT) {
+ LOG.warn(LoggingUtils.info(e, this), e);
+ if (e instanceof COMMException) {
+ raiseEvent(exceptionType, time, true, new LocalizableMessage(
+ "alpha2.commException", vo.getName(), e.getMessage()), dataPointRT);
+ } else if (e instanceof InvalidFrameReceivedException) {
+ raiseEvent(exceptionType, time, true, new LocalizableMessage(
+ "alpha2.invalidFrameException", vo.getName(), e
+ .getMessage()), dataPointRT);
+ } else if (e instanceof ErrorMessageReceivedException) {
+ raiseEvent(exceptionType, time, true, new LocalizableMessage(
+ "alpha2.errorMessageException", vo.getName(), e
+ .getMessage()), dataPointRT);
+ } else {
+ raiseEvent(exceptionType, time, true, new LocalizableMessage(
+ "alpha2.unknownException", vo.getName(), e.getMessage()), dataPointRT);
+ }
+ }
}
diff --git a/src/br/org/scadabr/rt/dataSource/asciiFile/ASCIIFileDataSource.java b/src/br/org/scadabr/rt/dataSource/asciiFile/ASCIIFileDataSource.java
index 3a5c220aa5..0255a7ed9c 100644
--- a/src/br/org/scadabr/rt/dataSource/asciiFile/ASCIIFileDataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/asciiFile/ASCIIFileDataSource.java
@@ -7,6 +7,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,6 +44,7 @@ protected void doPoll(long time) {
new LocalizableMessage("event.exception2", vo.getName(),
"Arquivo não encontrado!"));
} else {
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, time);
String arquivo = readFile(file);
for (DataPointRT dataPoint : dataPoints) {
@@ -58,19 +60,21 @@ protected void doPoll(long time) {
} catch (Exception e) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
- vo.getName(), e.getMessage()));
+ vo.getName(), e.getMessage()), dataPoint);
timestamp = time;
+ return;
}
}
dataPoint.updatePointValue(new PointValueTime(value,
timestamp));
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
} catch (Exception e) {
+ LOG.error(LoggingUtils.info(e, this), e);
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2", vo
- .getName(), e.getMessage()));
- e.printStackTrace();
+ .getName(), e.getMessage()), dataPoint);
}
}
@@ -143,7 +147,7 @@ private String readFile(File file) {
} while (c != -1);
reader.close();
} catch (Exception e) {
- e.printStackTrace();
+ LOG.error(LoggingUtils.info(e, this), e);
}
return sb.toString();
}
diff --git a/src/br/org/scadabr/rt/dataSource/asciiSerial/ASCIISerialDataSource.java b/src/br/org/scadabr/rt/dataSource/asciiSerial/ASCIISerialDataSource.java
index 6a1968f973..5bae2f06ba 100644
--- a/src/br/org/scadabr/rt/dataSource/asciiSerial/ASCIISerialDataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/asciiSerial/ASCIISerialDataSource.java
@@ -1,5 +1,6 @@
package br.org.scadabr.rt.dataSource.asciiSerial;
+import com.serotonin.mango.util.LoggingUtils;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
@@ -26,6 +27,7 @@
import com.serotonin.mango.rt.dataSource.DataSourceUtils;
import com.serotonin.mango.rt.dataSource.PollingDataSource;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.scada_lts.serial.gnu.io.ScadaCommPortIdentifier;
public class ASCIISerialDataSource extends PollingDataSource {
@@ -44,10 +46,6 @@ public ASCIISerialDataSource(ASCIISerialDataSourceVO> vo) {
setPollingPeriod(vo.getUpdatePeriodType(), vo.getUpdatePeriods(),
vo.isQuantize());
- portList = CommPortIdentifier.getPortIdentifiers();
- getPort(vo.getCommPortId());
- configurePort(getsPort());
-
}
private boolean reconnect() {
@@ -55,7 +53,7 @@ private boolean reconnect() {
try {
while (true) {
Thread.sleep(5000);
- portList = CommPortIdentifier.getPortIdentifiers();
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
SerialPort p = getPort(vo.getCommPortId());
if (p != null) {
configurePort(getsPort());
@@ -63,7 +61,8 @@ private boolean reconnect() {
return true;
}
}
- } catch (Exception e) {
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
return false;
}
@@ -75,7 +74,7 @@ protected void doPoll(long time) {
try {
// nao tem dados
- if (getInSerialStream().available() == 0) {
+ if (getInSerialStream() == null || getInSerialStream().available() == 0) {
for (DataPointRT dataPoint : dataPoints) {
ASCIISerialPointLocatorVO dataPointVO = dataPoint.getVO()
@@ -93,6 +92,7 @@ protected void doPoll(long time) {
new LocalizableMessage("event.exception2",
vo.getName(), "Sem dados disponíveis !"));
} else if (getInSerialStream().available() > 0) {
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, time);
byte[] readBuffer = new byte[vo.getBufferSize()];
try {
@@ -176,7 +176,7 @@ protected void doPoll(long time) {
new LocalizableMessage(
"event.exception2", vo
.getName(), e
- .getMessage()));
+ .getMessage()), dataPoint);
timestamp = time;
}
@@ -184,30 +184,49 @@ protected void doPoll(long time) {
dataPoint.updatePointValue(new PointValueTime(
value, timestamp));
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
} catch (Exception e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
- vo.getName(), e.getMessage()));
+ vo.getName(), e.getMessage()), dataPoint);
// e.printStackTrace();
}
}
- } catch (Exception e) {
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
}
}
} catch (IOException io) {
- getsPort().close();
- reconnect();
- } catch (Exception e) {
+ LOG.warn(LoggingUtils.info(io, this), io);
+ try {
+ getsPort().close();
+ reconnect();
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(io, this), e);
+ }
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
}
}
@Override
public void initialize() {
+ try {
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
+ getPort(vo.getCommPortId());
+ configurePort(getsPort());
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ return;
+ }
super.initialize();
-
}
private MangoValue getValue(ASCIISerialPointLocatorVO point, String arquivo)
@@ -260,7 +279,17 @@ private long getTimestamp(ASCIISerialPointLocatorVO point, String arquivo)
@Override
public void terminate() {
super.terminate();
- getsPort().close();
+ try {
+ SerialPort serialPort = getsPort();
+ if(serialPort != null) {
+ serialPort.close();
+ }
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ }
}
@Override
@@ -274,7 +303,8 @@ public void configurePort(SerialPort port) {
try {
setInSerialStream(port.getInputStream());
setOutSerialStream(port.getOutputStream());
- } catch (Exception e) {
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
}
port.notifyOnDataAvailable(true);
@@ -282,7 +312,8 @@ public void configurePort(SerialPort port) {
try {
port.setSerialPortParams(vo.getBaudRate(), vo.getDataBits(),
vo.getStopBits(), vo.getParity());
- } catch (Exception e) {
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
}
}
@@ -298,8 +329,8 @@ public SerialPort getPort(String port) {
serialPort = (SerialPort) portId.open(this.getName(),
10000);
setsPort(serialPort);
- } catch (Exception e) {
- System.out.println("Erro ao abrir a porta !");
+ } catch (Throwable e) {
+ LOG.error("Erro ao abrir a porta ! :" + LoggingUtils.info(e, this));
}
}
}
diff --git a/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java b/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java
index 828acf6b10..39414d9715 100644
--- a/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java
+++ b/src/br/org/scadabr/rt/dataSource/dnp3/DNP3Master.java
@@ -2,6 +2,7 @@
import java.util.List;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,8 +44,10 @@ public void initSerial(int sourceAddress, int slaveAddress, String com,
user.init();
} catch (Error e) {
log.fatal(e.getMessage(), e);
+ throw e;
} catch (Exception e) {
log.error(e.getMessage(), e);
+ throw e;
}
}
@@ -52,18 +55,24 @@ public void initSerial(int sourceAddress, int slaveAddress, String com,
public void doPoll() throws Exception {
if (reconnecting) {
- log.debug("[DNP3Master] Trying to reconnect...");
+ log.warn("[DNP3Master] Trying to reconnect...");
timeoutCount = 0;
try {
try {
user.init();
reconnecting = false;
- log.debug("[DNP3Master] Reconnected!");
- } catch (Exception | Error e) {
- log.warn(e.getMessage(), e);
- terminate();
+ log.warn("[DNP3Master] Reconnected!");
+ } catch (Throwable e) {
+ log.warn(LoggingUtils.exceptionInfo(e));
+ try {
+ terminate();
+ } catch (Throwable ex) {
+ log.warn(LoggingUtils.exceptionInfo(ex));
+ throw ex;
+ }
}
} catch (Exception e) {
+ log.error(LoggingUtils.exceptionInfo(e));
throw e;
}
} else {
@@ -72,10 +81,13 @@ public void doPoll() throws Exception {
log.debug("[DNP3Master] Conexão falhou. Terminar Conexão.");
terminate();
log.debug("[DNP3Master] Conexão terminada.");
- throw new Exception("[DNP3Master] Poll failed!");
+ throw new Exception("[DNP3Master] Poll failed! User: " + this.user + ", pollingCount: " + this.pollingCount
+ + ", relativePollingPeriod: " + this.relativePollingPeriod
+ + ", timeoutCount: " + this.timeoutCount
+ + ", reconnecting: " + this.reconnecting);
} else {
try {
- log.debug("[DNP3Master] Poll " + pollingCount + " / "
+ log.warn("[DNP3Master] Poll " + pollingCount + " / "
+ relativePollingPeriod);
if (pollingCount == 0) {
user.sendSynch(user.buildReadStaticDataMsg());
@@ -87,10 +99,11 @@ public void doPoll() throws Exception {
pollingCount = 0;
}
timeoutCount = 0;
- } catch (Exception e) {
- log.debug("[DNP3Master] Poll failed! (Error: "
+ } catch (Throwable e) {
+ log.warn("[DNP3Master] Poll failed! (Error: "
+ e.getMessage() + ")");
timeoutCount++;
+ throw e;
}
}
diff --git a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java
index 8a28831d8b..d74766a225 100644
--- a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3DataSource.java
@@ -2,9 +2,9 @@
import java.net.ConnectException;
import java.util.Calendar;
-import java.util.Date;
import java.util.List;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -21,12 +21,16 @@
import com.serotonin.messaging.TimeoutException;
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataSourceUtils.checkInitialized;
+
+
public class Dnp3DataSource extends PollingDataSource {
private final Log LOG = LogFactory.getLog(Dnp3DataSource.class);
public static final int POINT_READ_EXCEPTION_EVENT = 1;
public static final int DATA_SOURCE_EXCEPTION_EVENT = 2;
+ public static final int POINT_WRITE_EXCEPTION_EVENT = 3;
private DNP3Master dnp3Master;
private final Dnp3DataSourceVO> vo;
@@ -42,13 +46,12 @@ public Dnp3DataSource(Dnp3DataSourceVO> vo) {
protected void doPoll(long time) {
try {
+ checkInitialized(dnp3Master, this);
dnp3Master.doPoll();
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, time);
- } catch (Exception e) {
- LOG.warn(e.getMessage(), e);
- raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true,
- new LocalizableMessage("event.exception2", vo.getName(), e
- .getMessage()));
+ } catch (Throwable e) {
+ LOG.warn(LoggingUtils.info(e, this), e);
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true, getLocalExceptionMessage(e));
return;
}
@@ -81,12 +84,12 @@ protected void initialize(DNP3Master dnp3Master) {
public void terminate() {
super.terminate();
try {
- dnp3Master.terminate();
- } catch (Exception e) {
- raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true,
- new LocalizableMessage("event.exception2", vo.getName(), e
- .getMessage()));
- LOG.error(e.getMessage(), e);
+ if(dnp3Master != null)
+ dnp3Master.terminate();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this), e);
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, getLocalExceptionMessage(e));
}
}
@@ -100,6 +103,7 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
int index = pointLocator.getIndex();
try {
+ checkInitialized(dnp3Master, this);
if (dataType == 0x10) {
dnp3Master.controlCommand(valueTime.getValue().toString(),
index, pointLocator.getControlCommand(), pointLocator
@@ -108,12 +112,14 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
dnp3Master
.sendAnalogCommand(index, valueTime.getIntegerValue());
}
- } catch (Exception e) {
- e.printStackTrace();
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this), e);
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, getLocalExceptionMessage(e), dataPoint);
}
}
- protected LocalizableMessage getLocalExceptionMessage(Exception e) {
+ protected LocalizableMessage getLocalExceptionMessage(Throwable e) {
if (e instanceof Exception) {
Throwable cause = e.getCause();
if (cause instanceof TimeoutException)
diff --git a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3IpDataSource.java b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3IpDataSource.java
index 1ae960efe9..f090d5fa5d 100644
--- a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3IpDataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3IpDataSource.java
@@ -1,12 +1,16 @@
package br.org.scadabr.rt.dataSource.dnp3;
-import java.util.Date;
import br.org.scadabr.vo.dataSource.dnp3.Dnp3IpDataSourceVO;
+import com.serotonin.mango.util.LoggingUtils;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
public class Dnp3IpDataSource extends Dnp3DataSource {
+
+ private static final Log LOG = LogFactory.getLog(Dnp3IpDataSource.class);
private final Dnp3IpDataSourceVO configuration;
public Dnp3IpDataSource(Dnp3IpDataSourceVO configuration) {
@@ -23,11 +27,13 @@ public void initialize() {
configuration.getSlaveAddress(), configuration.getHost(),
configuration.getPort(), configuration
.getStaticPollPeriods());
- } catch (Exception e) {
- e.printStackTrace();
- raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true,
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this));
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
new LocalizableMessage("event.exception2", configuration
.getName(), e.getMessage()));
+ return;
}
super.initialize(dnp3Master);
diff --git a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3SerialDataSource.java b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3SerialDataSource.java
index 25524adbeb..a493f8d92b 100644
--- a/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3SerialDataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/dnp3/Dnp3SerialDataSource.java
@@ -1,5 +1,6 @@
package br.org.scadabr.rt.dataSource.dnp3;
+import com.serotonin.mango.util.LoggingUtils;
import gnu.io.NoSuchPortException;
import java.util.Date;
@@ -8,8 +9,12 @@
import com.serotonin.mango.rt.dataSource.DataSourceRT;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
public class Dnp3SerialDataSource extends Dnp3DataSource {
+
+ private static final Log LOG = LogFactory.getLog(Dnp3SerialDataSource.class);
private final Dnp3SerialDataSourceVO configuration;
public Dnp3SerialDataSource(Dnp3SerialDataSourceVO configuration) {
@@ -26,18 +31,18 @@ public void initialize() {
configuration.getSlaveAddress(), configuration
.getCommPortId(), configuration.getBaudRate(),
configuration.getStaticPollPeriods());
- } catch (Exception e) {
- e.printStackTrace();
- raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true,
- new LocalizableMessage("event.exception2", configuration
- .getName(), e.getMessage()));
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this));
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true, getLocalExceptionMessage(e));
+ return;
}
super.initialize(dnp3Master);
}
@Override
- protected LocalizableMessage getLocalExceptionMessage(Exception e) {
+ protected LocalizableMessage getLocalExceptionMessage(Throwable e) {
if (e instanceof Exception) {
Throwable cause = e.getCause();
if (cause instanceof NoSuchPortException)
diff --git a/src/br/org/scadabr/rt/dataSource/drStorageHt5b/DrStorageHt5bDataSource.java b/src/br/org/scadabr/rt/dataSource/drStorageHt5b/DrStorageHt5bDataSource.java
index c72fa89441..7d87efceab 100644
--- a/src/br/org/scadabr/rt/dataSource/drStorageHt5b/DrStorageHt5bDataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/drStorageHt5b/DrStorageHt5bDataSource.java
@@ -1,5 +1,6 @@
package br.org.scadabr.rt.dataSource.drStorageHt5b;
+import com.serotonin.mango.util.LoggingUtils;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
@@ -19,10 +20,11 @@
import com.serotonin.mango.rt.dataImage.SetPointSource;
import com.serotonin.mango.rt.dataSource.PollingDataSource;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.scada_lts.serial.gnu.io.ScadaCommPortIdentifier;
public class DrStorageHt5bDataSource extends PollingDataSource {
- private final Log LOG = LogFactory.getLog(DrStorageHt5bDataSource.class);
+ private final static Log LOG = LogFactory.getLog(DrStorageHt5bDataSource.class);
public static final int POINT_READ_EXCEPTION_EVENT = 1;
public static final int DATA_SOURCE_EXCEPTION_EVENT = 2;
private final DrStorageHt5bDataSourceVO> vo;
@@ -39,11 +41,6 @@ public DrStorageHt5bDataSource(DrStorageHt5bDataSourceVO> vo) {
this.vo = vo;
setPollingPeriod(vo.getUpdatePeriodType(), vo.getUpdatePeriods(), vo
.isQuantize());
-
- portList = CommPortIdentifier.getPortIdentifiers();
- getPort(vo.getCommPortId());
- configurePort(getsPort());
- setValuesHt5b(new ArrayList());
}
@Override
@@ -51,7 +48,7 @@ protected void doPoll(long time) {
try {
- if (getInSerialStream().available() == 0) {
+ if (getInSerialStream() == null || getInSerialStream().available() == 0) {
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
@@ -89,12 +86,13 @@ protected void doPoll(long time) {
dataPoint.updatePointValue(new PointValueTime(
hum, System.currentTimeMillis()));
}
-
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
} catch (Exception e) {
+ LOG.error(LoggingUtils.info(e, this));
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
- vo.getName(), e.getMessage()));
- e.printStackTrace();
+ vo.getName(), e.getMessage()), dataPoint);
+
}
}
@@ -102,12 +100,12 @@ protected void doPoll(long time) {
getValuesHt5b().clear();
} catch (Exception e) {
- e.printStackTrace();
+ LOG.error(LoggingUtils.info(e, this));
}
}
} catch (Exception e) {
- e.printStackTrace();
+ LOG.error(LoggingUtils.info(e, this));
}
}
@@ -122,7 +120,16 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
@Override
public void terminate() {
super.terminate();
- getsPort().close();
+ try {
+ SerialPort serialPort = getsPort();
+ if(serialPort != null)
+ serialPort.close();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ }
}
private String getTemperature(ArrayList ht5bValues) {
@@ -232,19 +239,22 @@ private void toStringHexa(byte[] bytes) {
}
public static String getHexString(byte[] b) throws Exception {
- String result = "";
- System.out.println("INICIO");
+ LOG.info("INICIO");
+
+ StringBuilder result = new StringBuilder("");
for (int i = 0; i < b.length; i++) {
- System.out.println(Integer.toString((b[i] & 0xff) + 0x100, 16)
- .substring(1));
- result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
+ String value = Integer.toString((b[i] & 0xff) + 0x100, 16)
+ .substring(1);
+ LOG.info(value);
+
+ result.append(value);
}
- System.out.println("FIM");
+ LOG.info("FIN");
- return result;
+ return result.toString();
}
public static String getHex(byte[] raw) {
@@ -292,9 +302,9 @@ public SerialPort getPort(String port) {
serialPort = (SerialPort) portId.open(this.getName(),
10000);
setsPort(serialPort);
- } catch (Exception e) {
- System.out.println("Error opening port "
- + serialPort.getName() + "!");
+ } catch (Throwable e) {
+ LOG.error("Error opening port " + serialPort.getName() + "! : "
+ + LoggingUtils.info(e, this));
}
}
}
@@ -343,4 +353,20 @@ public void setsPort(SerialPort sPort) {
this.sPort = sPort;
}
+ @Override
+ public void initialize() {
+ try {
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
+ getPort(vo.getCommPortId());
+ configurePort(getsPort());
+ setValuesHt5b(new ArrayList<>());
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ return;
+ }
+ super.initialize();
+ }
}
diff --git a/src/br/org/scadabr/rt/dataSource/iec101/IEC101DataSource.java b/src/br/org/scadabr/rt/dataSource/iec101/IEC101DataSource.java
index 9a324cf954..73d6cc0578 100644
--- a/src/br/org/scadabr/rt/dataSource/iec101/IEC101DataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/iec101/IEC101DataSource.java
@@ -4,6 +4,7 @@
import java.util.Date;
import java.util.List;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -38,12 +39,16 @@ public IEC101DataSource(IEC101DataSourceVO> vo) {
@Override
protected void doPoll(long time) {
try {
+ if(iec101Master == null)
+ throw new IllegalStateException("Data source is not initialized!");
iec101Master.doPoll();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
} catch (Exception e) {
- raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true,
+ LOG.error(LoggingUtils.info(e, this));
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
new LocalizableMessage("event.exception2", vo.getName(), e
.getMessage()));
- e.printStackTrace();
+ return;
}
for (DataPointRT dataPoint : dataPoints) {
@@ -58,8 +63,15 @@ protected void doPoll(long time) {
.getValue(), pointLocator.getDataTypeId());
Calendar ts = Calendar.getInstance();
ts.setTimeInMillis(dataElement.getTimestamp());
- dataPoint.updatePointValue(new PointValueTime(value, ts
- .getTimeInMillis()));
+ try {
+ dataPoint.updatePointValue(new PointValueTime(value, ts
+ .getTimeInMillis()));
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Exception e) {
+ raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2", vo.getName(), e
+ .getMessage()), dataPoint);
+ }
}
}
}
@@ -85,11 +97,12 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
iec101Master.setPointCommand(ioa, select, qualifier, valueTime
.getIntegerValue());
}
- } catch (Exception e) {
- raiseEvent(POINT_WRITE_EXCEPTION_EVENT, new Date().getTime(), true,
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this, dataPoint), e);
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
new LocalizableMessage("event.exception2", vo.getName(), e
- .getMessage()));
- e.printStackTrace();
+ .getMessage()), dataPoint);
}
}
@@ -112,11 +125,13 @@ protected void initialize(IEC101Master iec101Master) {
this.iec101Master = iec101Master;
try {
iec101Master.init(vo.getGiRelativePeriod());
- } catch (Exception e) {
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this), e);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true,
new LocalizableMessage("event.exception2", vo.getName(), e
.getMessage()));
- e.printStackTrace();
+ return;
}
super.initialize();
}
@@ -125,12 +140,14 @@ protected void initialize(IEC101Master iec101Master) {
public void terminate() {
super.terminate();
try {
- iec101Master.terminate();
- } catch (Exception e) {
+ if(iec101Master != null)
+ iec101Master.terminate();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this), e);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, new Date().getTime(), true,
new LocalizableMessage("event.exception2", vo.getName(), e
.getMessage()));
- e.printStackTrace();
}
}
diff --git a/src/br/org/scadabr/rt/dataSource/iec101/IEC101Master.java b/src/br/org/scadabr/rt/dataSource/iec101/IEC101Master.java
index d9c83c4568..8563d476f9 100644
--- a/src/br/org/scadabr/rt/dataSource/iec101/IEC101Master.java
+++ b/src/br/org/scadabr/rt/dataSource/iec101/IEC101Master.java
@@ -47,9 +47,11 @@ public void doPoll() throws Exception {
reconnecting = false;
} else {
terminate();
+ throw new Exception("Trying to reconnect failed.");
}
} catch (Exception e) {
- e.printStackTrace();
+ Thread.sleep(100);
+ throw e;
}
} else {
diff --git a/src/br/org/scadabr/rt/dataSource/nodaves7/NodaveS7DataSource.java b/src/br/org/scadabr/rt/dataSource/nodaves7/NodaveS7DataSource.java
index e3dc448a08..373dd7f27d 100644
--- a/src/br/org/scadabr/rt/dataSource/nodaves7/NodaveS7DataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/nodaves7/NodaveS7DataSource.java
@@ -7,6 +7,7 @@
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -66,7 +67,7 @@ protected void doPoll(long time) {
} catch (Exception e) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
- vo.getName(), e.getMessage()));
+ vo.getName(), e.getMessage()), dataPoint);
timestamp = time;
}
@@ -74,14 +75,15 @@ protected void doPoll(long time) {
dataPoint.updatePointValue(new PointValueTime(value,
timestamp));
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
} catch (Exception e) {
+ LOG.error(LoggingUtils.info(e, this, dataPoint));
raiseEvent(
POINT_READ_EXCEPTION_EVENT,
time,
true,
new LocalizableMessage("event.exception2", vo
- .getName(), e.getMessage()));
- e.printStackTrace();
+ .getName(), e.getMessage()), dataPoint);
}
}
@@ -138,37 +140,31 @@ private long getTimestamp(NodaveS7PointLocatorVO point, String arquivo)
public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
SetPointSource source) {
- System.out.println("WRITE datapoint to S7 :");
+ LOG.info("WRITE datapoint to S7 :");
- System.out.println("Command: " + this.vo.getNodaveWriteBaseCmd());
+ LOG.info("Command: " + this.vo.getNodaveWriteBaseCmd());
- System.out
- .println("AREA "
+ LOG.info("AREA "
+ ((NodaveS7PointLocatorVO) dataPoint.getVO()
.getPointLocator()).getS7writeMemoryArea());
- System.out
- .println("DBNUM "
+ LOG.info("DBNUM "
+ ((NodaveS7PointLocatorVO) dataPoint.getVO()
.getPointLocator()).getS7writeDBNUM());
- System.out
- .println("BYTES "
+ LOG.info("BYTES "
+ ((NodaveS7PointLocatorVO) dataPoint.getVO()
.getPointLocator()).getS7writeBytesQty());
- System.out
- .println("STARTS "
+ LOG.info("STARTS "
+ ((NodaveS7PointLocatorVO) dataPoint.getVO()
.getPointLocator()).getS7writeStarts());
- System.out
- .println("BIT "
+ LOG.info("BIT "
+ ((NodaveS7PointLocatorVO) dataPoint.getVO()
.getPointLocator()).getS7writeBitOffset());
- System.out
- .println("TYPE "
+ LOG.info("TYPE "
+ ((NodaveS7PointLocatorVO) dataPoint.getVO()
.getPointLocator()).getDataType());
- System.out.println(valueTime.toString());
+ LOG.info(valueTime.toString());
// datatype 1 => binario
// datatype 2 => multistate
@@ -210,7 +206,7 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
break;
}
}
- System.out.println("Writing binary - converted to " + converted);
+ LOG.info("Writing binary - converted to " + converted);
}
diff --git a/src/br/org/scadabr/rt/dataSource/opc/OPCDataSource.java b/src/br/org/scadabr/rt/dataSource/opc/OPCDataSource.java
index b2485dcabc..b3f84c3074 100644
--- a/src/br/org/scadabr/rt/dataSource/opc/OPCDataSource.java
+++ b/src/br/org/scadabr/rt/dataSource/opc/OPCDataSource.java
@@ -3,6 +3,7 @@
import java.util.ArrayList;
import java.util.logging.Level;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jinterop.dcom.common.JISystem;
@@ -36,14 +37,11 @@ public OPCDataSource(OPCDataSourceVO> vo) {
this.vo = vo;
setPollingPeriod(vo.getUpdatePeriodType(), vo.getUpdatePeriods(),
vo.isQuantize());
-
- this.opcMaster = new RealOPCMaster();
- JISystem.getLogger().setLevel(Level.OFF);
}
@Override
protected void doPoll(long time) {
- ArrayList enabledTags = new ArrayList();
+ ArrayList enabledTags = new ArrayList<>();
for (DataPointRT dataPoint : dataPoints) {
OPCPointLocatorVO dataPointVO = dataPoint.getVO().getPointLocator();
@@ -53,7 +51,7 @@ protected void doPoll(long time) {
try {
if (timeoutCount >= timeoutsToReconnect) {
- System.out.println("[OPC] Trying to reconnect !");
+ LOG.error("[OPC] Trying to reconnect ! :" + LoggingUtils.dataSourceInfo(this));
timeoutCount = 0;
initialize();
} else {
@@ -62,7 +60,8 @@ protected void doPoll(long time) {
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, time);
}
- } catch (Exception e) {
+ } catch (Throwable e) {
+ LOG.error("[OPC] Poll Failed ! :" + LoggingUtils.info(e, this));
raiseEvent(
DATA_SOURCE_EXCEPTION_EVENT,
time,
@@ -70,7 +69,7 @@ protected void doPoll(long time) {
new LocalizableMessage("event.exception2", vo.getName(), e
.getMessage()));
timeoutCount++;
- System.out.println("[OPC] Poll Failed !");
+ return;
}
for (DataPointRT dataPoint : dataPoints) {
@@ -85,10 +84,11 @@ protected void doPoll(long time) {
dataPointVO.getDataTypeId());
dataPoint
.updatePointValue(new PointValueTime(mangoValue, time));
- } catch (Exception e) {
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
+ } catch (Throwable e) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
- vo.getName(), e.getMessage()));
+ vo.getName(), e.getMessage()), dataPoint);
}
}
}
@@ -110,18 +110,28 @@ else if (dataPoint.getDataTypeId() == DataTypes.MULTISTATE)
try {
opcMaster.write(tag, value);
- } catch (Exception e) {
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this, dataPoint), e);
raiseEvent(
POINT_WRITE_EXCEPTION_EVENT,
System.currentTimeMillis(),
true,
new LocalizableMessage("event.exception2", vo.getName(), e
- .getMessage()));
- e.printStackTrace();
+ .getMessage()), dataPoint);
}
}
public void initialize() {
+ if(opcMaster != null) {
+ try {
+ opcMaster.terminate();
+ } catch (Exception e) {
+ LOG.warn(LoggingUtils.info(e, this));
+ }
+ }
+ this.opcMaster = new RealOPCMaster();
+ JISystem.getLogger().setLevel(Level.OFF);
opcMaster.setHost(vo.getHost());
opcMaster.setDomain(vo.getDomain());
@@ -134,7 +144,7 @@ public void initialize() {
opcMaster.init();
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT,
System.currentTimeMillis());
- } catch (Exception e) {
+ } catch (Throwable e) {
String message = e.getMessage();
if(e.getMessage() != null && e.getMessage().contains("Unknown Error")) {
message = "The OPC DA Server for the data source settings may not be found. ";
@@ -155,8 +165,10 @@ public void initialize() {
public void terminate() {
super.terminate();
try {
- opcMaster.terminate();
- } catch (Exception e) {
+ if(opcMaster != null)
+ opcMaster.terminate();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
String message = e.getMessage();
if(e instanceof NullPointerException) {
message = "The client may not have been properly initialized. ";
diff --git a/src/br/org/scadabr/rt/scripting/ContextualizedScriptRT.java b/src/br/org/scadabr/rt/scripting/ContextualizedScriptRT.java
index 73209e9e01..267628976a 100644
--- a/src/br/org/scadabr/rt/scripting/ContextualizedScriptRT.java
+++ b/src/br/org/scadabr/rt/scripting/ContextualizedScriptRT.java
@@ -81,8 +81,8 @@ public void execute() throws ScriptException {
try {
context = new ScriptExecutor().convertContext(((ContextualizedScriptVO) vo).getPointsOnContext());
- } catch (DataPointStateException e1) {
- LOG.error("Data Point State Exception" + e1.getMessage());
+ } catch (Exception e1) {
+ LOG.error("Data Point State Exception " + e1.getMessage());
if (vo != null) {
throw new ScriptException("xid:"+vo.getXid() +" script:"+vo.getScript()+" error:" + e1.getMessage());
} else {
diff --git a/src/br/org/scadabr/vo/dataSource/dnp3/Dnp3DataSourceVO.java b/src/br/org/scadabr/vo/dataSource/dnp3/Dnp3DataSourceVO.java
index dcb5a37649..f2ba25cde4 100644
--- a/src/br/org/scadabr/vo/dataSource/dnp3/Dnp3DataSourceVO.java
+++ b/src/br/org/scadabr/vo/dataSource/dnp3/Dnp3DataSourceVO.java
@@ -33,6 +33,9 @@ protected void addEventTypes(List eventTypes) {
eventTypes.add(createEventType(
Dnp3DataSource.DATA_SOURCE_EXCEPTION_EVENT,
new LocalizableMessage("event.ds.dataSource")));
+ eventTypes.add(createEventType(
+ Dnp3DataSource.POINT_WRITE_EXCEPTION_EVENT,
+ new LocalizableMessage("event.ds.pointWrite")));
}
private static final ExportCodes EVENT_CODES = new ExportCodes();
@@ -41,6 +44,8 @@ protected void addEventTypes(List eventTypes) {
"DATA_SOURCE_EXCEPTION");
EVENT_CODES.addElement(Dnp3DataSource.POINT_READ_EXCEPTION_EVENT,
"POINT_READ_EXCEPTION");
+ EVENT_CODES.addElement(Dnp3DataSource.POINT_WRITE_EXCEPTION_EVENT,
+ "POINT_WRITE_EXCEPTION");
}
@Override
diff --git a/src/br/org/scadabr/vo/dataSource/drStorageHt5b/DrStorageHt5bDataSourceVO.java b/src/br/org/scadabr/vo/dataSource/drStorageHt5b/DrStorageHt5bDataSourceVO.java
index 78959fe38d..3c1e68168b 100644
--- a/src/br/org/scadabr/vo/dataSource/drStorageHt5b/DrStorageHt5bDataSourceVO.java
+++ b/src/br/org/scadabr/vo/dataSource/drStorageHt5b/DrStorageHt5bDataSourceVO.java
@@ -108,7 +108,6 @@ public com.serotonin.mango.vo.dataSource.DataSourceVO.Type getType() {
@JsonRemoteProperty
private boolean quantize;
- @JsonRemoteProperty
@Override
public void validate(DwrResponseI18n response) {
super.validate(response);
diff --git a/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoEventDataSource.java b/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoEventDataSource.java
index 89fd53225b..41fafeca42 100644
--- a/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoEventDataSource.java
+++ b/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoEventDataSource.java
@@ -1,5 +1,6 @@
package cc.radiuino.scadabr.rt.datasource.radiuino;
+import com.serotonin.mango.util.LoggingUtils;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
@@ -25,6 +26,7 @@
import com.serotonin.mango.rt.dataImage.SetPointSource;
import com.serotonin.mango.rt.dataSource.EventDataSource;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.scada_lts.serial.gnu.io.ScadaCommPortIdentifier;
public class RadiuinoEventDataSource extends EventDataSource implements
SerialPortEventListener {
@@ -57,7 +59,7 @@ private boolean reconnect() {
try {
while (true) {
Thread.sleep(5000);
- portList = CommPortIdentifier.getPortIdentifiers();
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
SerialPort p = getPort(vo.getCommPortId(), vo.getTimeout());
if (p != null) {
LOG.debug("Conexao estabelecida com a porta serial");
@@ -66,8 +68,8 @@ private boolean reconnect() {
return true;
}
}
- } catch (Exception e) {
- LOG.error("Erro ao conectar na porta serial", e);
+ } catch (Throwable e) {
+ LOG.error("Erro ao conectar na porta serial: " + LoggingUtils.info(e, this));
return false;
}
@@ -75,19 +77,37 @@ private boolean reconnect() {
@Override
public void initialize() {
- super.initialize();
LOG.debug("Inicializando o Radiuino Polling Data Source.");
- portList = CommPortIdentifier.getPortIdentifiers();
- getPort(vo.getCommPortId(), vo.getTimeout());
- configurePort(getsPort());
+ try {
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
+ getPort(vo.getCommPortId(), vo.getTimeout());
+ configurePort(getsPort());
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ return;
+ }
+
+ super.initialize();
}
@Override
public void terminate() {
super.terminate();
- getsPort().close();
+ try {
+ SerialPort serialPort = getsPort();
+ if(serialPort != null)
+ serialPort.close();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ }
LOG.debug("Terminando o Radiuino Polling Data Source.");
}
@@ -155,11 +175,15 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
enviarPacote(pacoteEnvio, 1);
} catch (IOException io) {
- LOG.error("Erro ao setar valor no data point Radiuino.", io);
- getsPort().close();
- reconnect();
+ LOG.error("Erro ao setar valor no data point Radiuino: " + LoggingUtils.info(io, this));
+ try {
+ getsPort().close();
+ reconnect();
+ } catch (Throwable e) {
+ LOG.error(LoggingUtils.info(e, this));
+ }
} catch (Exception e) {
- LOG.error("Erro geral ao setar valor no datasource.", e);
+ LOG.error("Erro geral ao setar valor no datasource: " + LoggingUtils.info(e, this));
}
}
@@ -197,8 +221,7 @@ private void enviarPacote(final byte[] pacoteEnvio, final int retries)
try {
Thread.sleep(100);
} catch (InterruptedException e) {
- LOG.error("Erro ao aguardar por pacote.", e);
- e.printStackTrace();
+ LOG.error("Erro ao aguardar por pacote: " + LoggingUtils.info(e, this), e);
}
} while ((new Date().getTime() - startTime) < timeout);
LOG.debug("Ainda esperando pacote " + new Date().getTime());
@@ -220,7 +243,7 @@ private void configurePort(SerialPort port) {
setInSerialStream(port.getInputStream());
setOutSerialStream(port.getOutputStream());
} catch (Exception e) {
- LOG.error("Erro ao configurar streaming de in e out", e);
+ LOG.error("Erro ao configurar streaming de in e out: " + LoggingUtils.info(e, this));
}
port.notifyOnDataAvailable(true);
@@ -228,16 +251,16 @@ private void configurePort(SerialPort port) {
port.addEventListener(this);
port.enableReceiveTimeout(vo.getTimeout());
} catch (UnsupportedCommOperationException e1) {
- LOG.error("Comando nao suportado ao abrir a porta serial.", e1);
+ LOG.error("Comando nao suportado ao abrir a porta serial: " + LoggingUtils.info(e1, this));
} catch (TooManyListenersException e) {
- LOG.error("Muitos Listeners adicionados a porta serial", e);
+ LOG.error("Muitos Listeners adicionados a porta serial: " + LoggingUtils.info(e, this));
}
try {
port.setSerialPortParams(vo.getBaudRate(), vo.getDataBits(),
vo.getStopBits(), vo.getParity());
} catch (Exception e) {
- LOG.error("Erro ao setar parametros da porta serial", e);
+ LOG.error("Erro ao setar parametros da porta serial: " + LoggingUtils.info(e, this));
}
}
@@ -255,7 +278,7 @@ private SerialPort getPort(String port, int timeout) {
timeout);
setsPort(serialPort);
} catch (Exception e) {
- LOG.error("Erro ao abrir a porta serial.", e);
+ LOG.error("Erro ao abrir a porta serial: " + LoggingUtils.info(e, this));
}
}
}
@@ -305,7 +328,7 @@ public void serialEvent(SerialPortEvent serialPortEvent) {
pacoteRecebido();
}
} catch (IOException e) {
- LOG.error("Erro ao receber dados da porta serial", e);
+ LOG.error("Erro ao receber dados da porta serial: " + LoggingUtils.info(e, this));
}
default:
@@ -326,14 +349,15 @@ private void pacoteRecebido() {
.parsePacoteRadiuino(time, pacote, dataPointVO);
if (pointValueTime != null)
dataPoint.updatePointValue(pointValueTime);
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
} catch (Exception e) {
- LOG.error("Erro ao fazer o parse dos dados.", e);
+ LOG.error("Erro ao fazer o parse dos dados: " + LoggingUtils.info(e, this, dataPoint));
raiseEvent(
POINT_READ_EXCEPTION_EVENT,
time,
true,
new LocalizableMessage("event.exception2", vo
- .getName(), e.getMessage()));
+ .getName(), e.getMessage()), dataPoint);
}
}
diff --git a/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoPollingDataSource.java b/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoPollingDataSource.java
index ab30f6a672..ce7a8d2324 100644
--- a/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoPollingDataSource.java
+++ b/src/cc/radiuino/scadabr/rt/datasource/radiuino/RadiuinoPollingDataSource.java
@@ -1,5 +1,6 @@
package cc.radiuino.scadabr.rt.datasource.radiuino;
+import com.serotonin.mango.util.LoggingUtils;
import gnu.io.CommPortIdentifier;
import gnu.io.SerialPort;
import gnu.io.SerialPortEvent;
@@ -27,6 +28,7 @@
import com.serotonin.mango.rt.dataImage.SetPointSource;
import com.serotonin.mango.rt.dataSource.PollingDataSource;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.scada_lts.serial.gnu.io.ScadaCommPortIdentifier;
public class RadiuinoPollingDataSource extends PollingDataSource implements
SerialPortEventListener {
@@ -60,7 +62,7 @@ private boolean reconnect() {
try {
while (true) {
Thread.sleep(5000);
- portList = CommPortIdentifier.getPortIdentifiers();
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
SerialPort p = getPort(vo.getCommPortId(), vo.getTimeout());
if (p != null) {
LOG.debug("Conexao estabelecida com a porta serial");
@@ -69,7 +71,7 @@ private boolean reconnect() {
return true;
}
}
- } catch (Exception e) {
+ } catch (Throwable e) {
LOG.error("Erro ao conectar na porta serial", e);
return false;
}
@@ -153,19 +155,37 @@ protected void doPoll(long time) {
@Override
public void initialize() {
- super.initialize();
LOG.debug("Inicializando o Radiuino Polling Data Source.");
- portList = CommPortIdentifier.getPortIdentifiers();
- getPort(vo.getCommPortId(), vo.getTimeout());
- configurePort(getsPort());
+ try {
+ portList = ScadaCommPortIdentifier.getPortIdentifiers();
+ getPort(vo.getCommPortId(), vo.getTimeout());
+ configurePort(getsPort());
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ return;
+ }
+
+ super.initialize();
}
@Override
public void terminate() {
super.terminate();
- getsPort().close();
+ try {
+ SerialPort serialPort = getsPort();
+ if(serialPort != null)
+ serialPort.close();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ }
LOG.debug("Terminando o Radiuino Polling Data Source.");
}
@@ -297,8 +317,8 @@ private void configurePort(SerialPort port) {
try {
setInSerialStream(port.getInputStream());
setOutSerialStream(port.getOutputStream());
- } catch (Exception e) {
- LOG.error("Erro ao configurar streaming de in e out", e);
+ } catch (Throwable e) {
+ LOG.error("Erro ao configurar streaming de in e out: " + LoggingUtils.info(e, this));
}
port.notifyOnDataAvailable(true);
@@ -306,16 +326,16 @@ private void configurePort(SerialPort port) {
port.addEventListener(this);
port.enableReceiveTimeout(vo.getTimeout());
} catch (UnsupportedCommOperationException e1) {
- LOG.error("Comando nao suportado ao abrir a porta serial.", e1);
+ LOG.error("Comando nao suportado ao abrir a porta serial: " + LoggingUtils.info(e1, this));
} catch (TooManyListenersException e) {
- LOG.error("Muitos Listeners adicionados a porta serial", e);
+ LOG.error("Muitos Listeners adicionados a porta serial: " + LoggingUtils.info(e, this));
}
try {
port.setSerialPortParams(vo.getBaudRate(), vo.getDataBits(),
vo.getStopBits(), vo.getParity());
- } catch (Exception e) {
- LOG.error("Erro ao setar parametros da porta serial", e);
+ } catch (Throwable e) {
+ LOG.error("Erro ao setar parametros da porta serial: " + LoggingUtils.info(e, this));
}
}
@@ -332,8 +352,8 @@ private SerialPort getPort(String port, int timeout) {
serialPort = (SerialPort) portId.open(this.getName(),
timeout);
setsPort(serialPort);
- } catch (Exception e) {
- LOG.error("Erro ao abrir a porta serial.", e);
+ } catch (Throwable e) {
+ LOG.error("Erro ao abrir a porta serial: " + LoggingUtils.info(e, this));
}
}
}
@@ -387,14 +407,14 @@ public void serialEvent(SerialPortEvent serialPortEvent) {
pacoteRecebido();
}
} catch (IOException e) {
- LOG.error("Erro ao receber dados da porta serial", e);
+ LOG.error("Erro ao receber dados da porta serial: " + LoggingUtils.info(e, this));
}
} else {
try {
int i = getInSerialStream().read(buffer);
} catch (IOException e) {
- LOG.error("Erro ao ler dados da porta serial", e);
+ LOG.error("Erro ao ler dados da porta serial: " + LoggingUtils.info(e, this));
}
}
default:
@@ -415,14 +435,15 @@ private void pacoteRecebido() {
.parsePacoteRadiuino(time, pacote, dataPointVO);
if (pointValueTime != null)
dataPoint.updatePointValue(pointValueTime);
- } catch (Exception e) {
- LOG.error("Erro ao fazer o parse dos dados.", e);
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
+ } catch (Throwable e) {
+ LOG.error("Erro ao fazer o parse dos dados: " + LoggingUtils.info(e, this));
raiseEvent(
POINT_READ_EXCEPTION_EVENT,
time,
true,
new LocalizableMessage("event.exception2", vo
- .getName(), e.getMessage()));
+ .getName(), e.getMessage()), dataPoint);
}
}
diff --git a/src/com/serotonin/mango/Common.java b/src/com/serotonin/mango/Common.java
index 67e5f4bc94..f9a8d1abc2 100644
--- a/src/com/serotonin/mango/Common.java
+++ b/src/com/serotonin/mango/Common.java
@@ -61,6 +61,7 @@
import com.serotonin.util.PropertiesUtils;
import com.serotonin.util.StringUtils;
import com.serotonin.web.i18n.LocalizableMessage;
+import org.scada_lts.serial.gnu.io.ScadaCommPortIdentifier;
import org.scada_lts.serial.SerialPortUtils;
import org.scada_lts.utils.SystemSettingsUtils;
import org.springframework.security.core.GrantedAuthority;
@@ -411,7 +412,7 @@ public static List getCommPorts()
throws CommPortConfigException {
try {
List ports = new LinkedList();
- Enumeration> portEnum = CommPortIdentifier.getPortIdentifiers();
+ Enumeration> portEnum = ScadaCommPortIdentifier.getPortIdentifiers();
CommPortIdentifier cpid;
while (portEnum.hasMoreElements()) {
cpid = (CommPortIdentifier) portEnum.nextElement();
diff --git a/src/com/serotonin/mango/MangoContextListener.java b/src/com/serotonin/mango/MangoContextListener.java
index 48d8627c57..74a5f8f884 100644
--- a/src/com/serotonin/mango/MangoContextListener.java
+++ b/src/com/serotonin/mango/MangoContextListener.java
@@ -373,6 +373,8 @@ private void constantsInitialize(ServletContext ctx) {
EventType.EventSources.AUDIT);
ctx.setAttribute("constants.EventType.EventSources.MAINTENANCE",
EventType.EventSources.MAINTENANCE);
+ ctx.setAttribute("constants.EventType.EventSources.DATA_SOURCE_POINT",
+ EventType.EventSources.DATA_SOURCE_POINT);
ctx.setAttribute("constants.SystemEventType.TYPE_SYSTEM_STARTUP",
SystemEventType.TYPE_SYSTEM_STARTUP);
ctx.setAttribute("constants.SystemEventType.TYPE_SYSTEM_SHUTDOWN",
diff --git a/src/com/serotonin/mango/rt/RuntimeManager.java b/src/com/serotonin/mango/rt/RuntimeManager.java
index 5ac9e28c86..28292d8dc6 100644
--- a/src/com/serotonin/mango/rt/RuntimeManager.java
+++ b/src/com/serotonin/mango/rt/RuntimeManager.java
@@ -21,6 +21,8 @@
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
import com.serotonin.mango.db.dao.*;
import com.serotonin.mango.rt.dataImage.*;
@@ -70,6 +72,9 @@
import com.serotonin.web.i18n.LocalizableException;
import com.serotonin.web.i18n.LocalizableMessage;
+import static org.scada_lts.utils.MetaDataPointUtils.isDataPointInContext;
+import static org.scada_lts.utils.MetaDataPointUtils.isMetaDataPointRT;
+
public class RuntimeManager {
private static final Log LOG = LogFactory.getLog(RuntimeManager.class);
@@ -490,7 +495,9 @@ private void startDataPoint(DataPointVO vo) {
// Add/update it in the data source.
ds.addDataPoint(dataPoint);
- LOG.info("Data point '" + vo.getExtendedName() + "' initialized");
+ boolean unreliable = dataPoint.isUnreliable();
+
+ LOG.info("Data point '" + vo.getExtendedName() + "' initialized - unreliable: " + unreliable);
}
}
}
@@ -1083,4 +1090,23 @@ private void startPoints() {
private void stopPoints() {
StartStopDataPointsUtils.stopPoints(this.dataPoints.values(), this::stopDataPointSafe, this::getDataPoint);
}
+
+ public List getRunningMetaDataPoints(int dataPointInContextId) {
+ Map dataPoints = new HashMap<>(this.dataPoints);
+ return filterRunningDataPoints(dataPoints.values(), dataPoint -> isMetaDataPointRT(dataPoint)
+ && isDataPointInContext(dataPoint, dataPointInContextId));
+ }
+
+ private static List filterRunningDataPoints(List dataPoints, Predicate filter) {
+ return dataPoints.stream()
+ .filter(filter)
+ .collect(Collectors.toList());
+ }
+
+ private static List filterRunningDataPoints(Collection dataPoints, Predicate filter) {
+ return dataPoints.stream()
+ .filter(filter)
+ .collect(Collectors.toList());
+ }
+
}
diff --git a/src/com/serotonin/mango/rt/dataImage/DataPointRT.java b/src/com/serotonin/mango/rt/dataImage/DataPointRT.java
index 16108ef48c..cad74e9e10 100644
--- a/src/com/serotonin/mango/rt/dataImage/DataPointRT.java
+++ b/src/com/serotonin/mango/rt/dataImage/DataPointRT.java
@@ -24,6 +24,8 @@
import com.serotonin.mango.rt.RuntimeManager;
import com.serotonin.mango.rt.dataImage.types.MangoValue;
import com.serotonin.mango.rt.dataImage.types.NumericValue;
+import com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils;
+import com.serotonin.mango.rt.dataSource.DataSourceRT;
import com.serotonin.mango.rt.dataSource.PointLocatorRT;
import com.serotonin.mango.rt.event.detectors.PointEventDetectorRT;
import com.serotonin.mango.rt.maint.work.AbstractBeforeAfterWorkItem;
@@ -624,6 +626,17 @@ public void terminateHistorical() {
terminateIntervalLogging();
}
+ public boolean isUnreliable() {
+ DataSourceRT dataSourceRT = Common.ctx.getRuntimeManager().getRunningDataSource(getDataSourceId());
+ if(dataSourceRT == null)
+ return true;
+ return !dataSourceRT.isInitialized() || isSetUnreliable();
+ }
+
+ public boolean isSetUnreliable() {
+ return DataPointUnreliableUtils.isSetUnreliable(this, true);
+ }
+
public boolean isInitialized() {
return initialized;
}
diff --git a/src/com/serotonin/mango/rt/dataSource/DataPointUnreliableUtils.java b/src/com/serotonin/mango/rt/dataSource/DataPointUnreliableUtils.java
new file mode 100644
index 0000000000..3d5a5ee6dc
--- /dev/null
+++ b/src/com/serotonin/mango/rt/dataSource/DataPointUnreliableUtils.java
@@ -0,0 +1,70 @@
+package com.serotonin.mango.rt.dataSource;
+
+import com.serotonin.mango.Common;
+import com.serotonin.mango.rt.dataImage.DataPointRT;
+import com.serotonin.mango.util.LoggingUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public final class DataPointUnreliableUtils {
+
+ private static final Log LOG = LogFactory.getLog(DataPointUnreliableUtils.class);
+
+ private static final String ATTR_UNRELIABLE_KEY = "UNRELIABLE";
+ private static final int SAFE = 10;
+
+ private DataPointUnreliableUtils() {}
+
+ public static boolean isSetUnreliable(DataPointRT dataPoint, boolean unreliable) {
+ return dataPoint.getAttribute(ATTR_UNRELIABLE_KEY) instanceof Boolean
+ && ((boolean) dataPoint.getAttribute(ATTR_UNRELIABLE_KEY)) == unreliable;
+ }
+
+ public static void setUnreliableDataPoints(List dataPoints) {
+ unreliable(dataPoints, true, SAFE);
+ }
+
+ public static void setUnreliableDataPoint(DataPointRT dataPoint) {
+ unreliable(Collections.singletonList(dataPoint), true, SAFE);
+ }
+
+ public static void resetUnreliableDataPoints(List dataPoints) {
+ unreliable(dataPoints, false, SAFE);
+ }
+
+ public static void resetUnreliableDataPoint(DataPointRT dataPoint) {
+ unreliable(Collections.singletonList(dataPoint), false, SAFE);
+ }
+
+ private static void unreliable(List dataPoints, boolean unreliable, int safe) {
+ setAttributes(filter(dataPoints, unreliable), unreliable);
+ for(DataPointRT dataPoint: dataPoints) {
+ List metaDataPoints = Common.ctx.getRuntimeManager().getRunningMetaDataPoints(dataPoint.getId());
+ if(!metaDataPoints.isEmpty()) {
+ if(safe > -1)
+ unreliable(metaDataPoints, unreliable, --safe);
+ else {
+ LOG.warn("The safe counter has been exceeded!: " + LoggingUtils.dataPointInfo(dataPoint));
+ setAttributes(filter(metaDataPoints, unreliable), unreliable);
+ }
+ }
+ }
+ }
+
+ private static void setAttributes(List dataPoints, boolean unreliable) {
+ for (DataPointRT dataPoint : dataPoints) {
+ dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, unreliable);
+ }
+ }
+
+ private static List filter(List dataPoints, boolean unreliable) {
+ return dataPoints.stream().filter(dataPoint -> !isSetUnreliable(dataPoint, unreliable))
+ .collect(Collectors.toList());
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/com/serotonin/mango/rt/dataSource/DataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/DataSourceRT.java
index 620260cc36..7818958f95 100644
--- a/src/com/serotonin/mango/rt/dataSource/DataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/DataSourceRT.java
@@ -18,6 +18,8 @@
*/
package com.serotonin.mango.rt.dataSource;
+import com.serotonin.mango.rt.event.type.DataSourcePointEventType;
+import com.serotonin.mango.vo.DataPointVO;
import gnu.io.NoSuchPortException;
import gnu.io.PortInUseException;
@@ -35,6 +37,8 @@
import com.serotonin.util.ILifecycle;
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.*;
+
/**
* Data sources are things that produce data for consumption of this system. Anything that houses, creates, manages, or
* otherwise can get data to Mango can be considered a data source. As such, this interface can more precisely be
@@ -49,8 +53,12 @@
* @author Matthew Lohbihler
*/
abstract public class DataSourceRT implements ILifecycle {
+
+ @Deprecated(since = "2.8.0")
public static final String ATTR_UNRELIABLE_KEY = "UNRELIABLE";
+ private volatile boolean initialized;
+
private final DataSourceVO> vo;
/**
@@ -80,7 +88,7 @@ abstract public class DataSourceRT implements ILifecycle {
public DataSourceRT(DataSourceVO> vo) {
this.vo = vo;
- eventTypes = new ArrayList();
+ eventTypes = new ArrayList<>();
for (EventTypeVO etvo : vo.getEventTypes())
eventTypes.add((DataSourceEventType) etvo.createEventType());
}
@@ -126,6 +134,11 @@ public void removeDataPoint(DataPointRT dataPoint) {
abstract public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPointSource source);
+ protected abstract List getDataPoints();
+ public boolean isInitialized() {
+ return initialized;
+ }
+
public void relinquish(@SuppressWarnings("unused") DataPointRT dataPoint) {
throw new ShouldNeverHappenException("not implemented in " + getClass());
}
@@ -143,9 +156,22 @@ public static void raiseEvent(String describe, DataSourceVO vo) {
Common.ctx.getEventManager().raiseEvent(dset, new Date().getTime(), true, dset.getAlarmLevel(), message, context);
}
- protected void raiseEvent(int eventId, long time, boolean rtn, LocalizableMessage message) {
+ private void _raiseEvent(int eventId, long time, boolean rtn, LocalizableMessage message) {
message = new LocalizableMessage("event.ds", vo.getName(), message);
- DataSourceEventType type = getEventType(eventId);
+ _raiseEvent(eventId, time, rtn, message, -1);
+ }
+
+ private void _returnToNormal(int eventId, long time) {
+ _returnToNormal(eventId, time, -1);
+ }
+
+ private void _raiseEvent(int eventId, long time, boolean rtn, LocalizableMessage message, DataPointVO dataPoint) {
+ message = new LocalizableMessage("event.ds", dataPoint.getExtendedName(), message);
+ _raiseEvent(eventId, time, rtn, message, dataPoint.getId());
+ }
+
+ private void _raiseEvent(int eventId, long time, boolean rtn, LocalizableMessage message, int dataPointId) {
+ DataSourceEventType type = getDataSourceEventType(eventId, dataPointId);
Map context = new HashMap();
context.put("dataSource", vo);
@@ -153,11 +179,42 @@ protected void raiseEvent(int eventId, long time, boolean rtn, LocalizableMessag
Common.ctx.getEventManager().raiseEvent(type, time, rtn, type.getAlarmLevel(), message, context);
}
- protected void returnToNormal(int eventId, long time) {
- DataSourceEventType type = getEventType(eventId);
+ private void _returnToNormal(int eventId, long time, int dataPointId) {
+ DataSourceEventType type = getDataSourceEventType(eventId, dataPointId);
Common.ctx.getEventManager().returnToNormal(type, time);
}
+ private DataSourceEventType getDataSourceEventType(int eventId, int dataPointId) {
+ DataSourceEventType eventType = getEventType(eventId);
+ if(eventType == null)
+ return null;
+ if(dataPointId == Common.NEW_ID)
+ return eventType;
+ return new DataSourcePointEventType(eventType, dataPointId);
+ }
+
+ protected void raiseEvent(int eventId, long time, boolean rtn, LocalizableMessage message) {
+ _raiseEvent(eventId, time, rtn, message);
+ List dataPoints = getDataPoints();
+ setUnreliableDataPoints(dataPoints);
+ }
+
+ protected void raiseEvent(int eventId, long time, boolean rtn, LocalizableMessage message, DataPointRT dataPoint) {
+ _raiseEvent(eventId, time, rtn, message, dataPoint.getVO());
+ setUnreliableDataPoint(dataPoint);
+ }
+
+ protected void returnToNormal(int eventId, long time) {
+ _returnToNormal(eventId, time);
+ List dataPoints = getDataPoints();
+ resetUnreliableDataPoints(dataPoints);
+ }
+
+ protected void returnToNormal(int eventId, long time, DataPointRT dataPoint) {
+ _returnToNormal(eventId, time, dataPoint.getId());
+ resetUnreliableDataPoint(dataPoint);
+ }
+
protected DataSourceEventType getEventType(int eventId) {
for (DataSourceEventType et : eventTypes) {
if (et.getDataSourceEventTypeId() == eventId)
@@ -166,7 +223,7 @@ protected DataSourceEventType getEventType(int eventId) {
return null;
}
- protected LocalizableMessage getSerialExceptionMessage(Exception e, String portId) {
+ protected LocalizableMessage getSerialExceptionMessage(Throwable e, String portId) {
if (e instanceof NoSuchPortException)
return new LocalizableMessage("event.serial.portOpenError", portId);
if (e instanceof PortInUseException)
@@ -174,7 +231,7 @@ protected LocalizableMessage getSerialExceptionMessage(Exception e, String portI
return getExceptionMessage(e);
}
- protected static LocalizableMessage getExceptionMessage(Exception e) {
+ protected static LocalizableMessage getExceptionMessage(Throwable e) {
return new LocalizableMessage("event.exception2", e.getClass().getName(), e.getMessage());
}
@@ -185,9 +242,11 @@ protected static LocalizableMessage getExceptionMessage(Exception e) {
//
public void initialize() {
// no op
+ this.initialized = true;
}
public void terminate() {
+ this.initialized = false;
// Remove any outstanding events.
Common.ctx.getEventManager().cancelEventsForDataSource(vo.getId());
}
diff --git a/src/com/serotonin/mango/rt/dataSource/DataSourceUtils.java b/src/com/serotonin/mango/rt/dataSource/DataSourceUtils.java
index dbde05832d..b5738bc89b 100644
--- a/src/com/serotonin/mango/rt/dataSource/DataSourceUtils.java
+++ b/src/com/serotonin/mango/rt/dataSource/DataSourceUtils.java
@@ -162,6 +162,12 @@ public static MangoValue getValue(String valueStr, int dataTypeId,
return null;
}
+ public static void checkInitialized(T master, DataSourceRT dataSource) {
+ if(master == null || !dataSource.isInitialized()) {
+ throw new IllegalStateException("Data Source not initialized!");
+ }
+ }
+
public static DataPointVO copyAndSaveDataPoint(DataSourceVO> dataSource, DataPointVO dataPoint, DataPointService dataPointService) {
DataPointVO dataPointCopy = dataPoint.copy();
dataPointCopy.setId(Common.NEW_ID);
diff --git a/src/com/serotonin/mango/rt/dataSource/EventDataSource.java b/src/com/serotonin/mango/rt/dataSource/EventDataSource.java
index 44bee9c9f5..21a7cf3855 100644
--- a/src/com/serotonin/mango/rt/dataSource/EventDataSource.java
+++ b/src/com/serotonin/mango/rt/dataSource/EventDataSource.java
@@ -53,4 +53,9 @@ public void removeDataPoint(DataPointRT dataPoint) {
public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPointSource source) {
// Typically, event based data sources cannot set point values, so don't make subclasses implement this.
}
+
+ @Override
+ protected List getDataPoints() {
+ return dataPoints;
+ }
}
diff --git a/src/com/serotonin/mango/rt/dataSource/PollingDataSource.java b/src/com/serotonin/mango/rt/dataSource/PollingDataSource.java
index 39d6cfc471..4098723397 100644
--- a/src/com/serotonin/mango/rt/dataSource/PollingDataSource.java
+++ b/src/com/serotonin/mango/rt/dataSource/PollingDataSource.java
@@ -144,6 +144,11 @@ public void joinTermination() {
}
}
+ @Override
+ protected List getDataPoints() {
+ return dataPoints;
+ }
+
public boolean isMarkAsTerminating() {
if(markAsTerminating) {
LOG.info(LoggingUtils.dataSourceInfo(this) + " is terminating.");
diff --git a/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java
index 4b1ece3cf7..d2824e4e85 100644
--- a/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/bacnet/BACnetIPDataSourceRT.java
@@ -91,6 +91,9 @@
import com.serotonin.web.i18n.LocalizableMessage;
import com.serotonin.web.taglib.DateFunctions;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.resetUnreliableDataPoint;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.setUnreliableDataPoint;
+
/**
* @author Matthew Lohbihler
*/
@@ -102,7 +105,7 @@ public class BACnetIPDataSourceRT extends PollingDataSource implements DeviceEve
final Log log = LogFactory.getLog(BACnetIPDataSourceRT.class);
final BACnetIPDataSourceVO vo;
private LocalDevice localDevice;
- private boolean initialized = false;
+ private volatile boolean initialized = false;
final List pollsInProgress = new ArrayList();
private CovResubscriptionTask covResubscriptionTask;
@@ -137,7 +140,7 @@ public void initialize() {
// Deactivate any existing event.
returnToNormal(INITIALIZATION_EXCEPTION_EVENT, System.currentTimeMillis());
}
- catch (Exception e) {
+ catch (Throwable e) {
raiseEvent(INITIALIZATION_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"event.initializationError", e.getMessage()));
return;
@@ -148,15 +151,17 @@ public void initialize() {
// Let everyone know we're here.
try {
localDevice.sendBroadcast(localDevice.getIAm());
+ returnToNormal();
}
catch (BACnetException e) {
fireMessageExceptionEvent("event.bacnet.iamError", e.getMessage());
+ return;
}
// Find out who we're slummin with.
try {
localDevice.sendBroadcast(new WhoIsRequest());
-
+ returnToNormal();
// Wait for responses to come in.
try {
Thread.sleep(vo.getTimeout() / 4);
@@ -167,9 +172,10 @@ public void initialize() {
}
catch (BACnetException e) {
fireMessageExceptionEvent("event.bacnet.whoisError", e.getMessage());
+ return;
}
- initialized = true;
+ initialized = isInitialized(localDevice);
}
@Override
@@ -204,6 +210,7 @@ public void terminate() {
}
}
LocalDevice.setExceptionListener(null);
+ initialized = isInitialized(localDevice);
}
@Override
@@ -221,9 +228,10 @@ public void addDataPoint(DataPointRT dataPoint) {
// Send a whois to get remote device data.
try {
localDevice.sendUnconfirmed(address, null, new WhoIsRequest());
+ returnToNormal(dataPoint);
}
catch (BACnetException e) {
- fireMessageExceptionEvent("event.bacnet.whoisPoint", dataPoint.getVO().getName(), e.getMessage());
+ fireMessageExceptionEvent(dataPoint,"event.bacnet.whoisPoint", dataPoint.getVO().getName(), e.getMessage());
disablePoint(dataPoint);
return;
}
@@ -250,19 +258,21 @@ public void addDataPoint(DataPointRT dataPoint) {
// If we still don't have the device, try to get it manually.
try {
d = localDevice.findRemoteDevice(address, network, locator.getRemoteDeviceInstanceNumber());
+ resetUnreliableDataPoint(dataPoint);
}
catch (BACnetException e) {
- // Ignore.
+ log.warn(LoggingUtils.info(e, this), e);
}
catch (PropertyValueException e) {
+ setUnreliableDataPoint(dataPoint);
// Shouldn't happen, so just log.
- log.error("Couldn't manually get segmentation and vendor id from device", e);
+ log.error("Couldn't manually get segmentation and vendor id from device: " + LoggingUtils.info(e, this));
}
}
if (d == null) {
// If we still don't have the device, call it in.
- fireDeviceExceptionEvent("event.bacnet.deviceError", address.toIpString());
+ fireDeviceExceptionEvent(dataPoint,"event.bacnet.deviceError", address.toIpString());
disablePoint(dataPoint);
}
else {
@@ -274,6 +284,7 @@ public void addDataPoint(DataPointRT dataPoint) {
}
super.addDataPoint(dataPoint);
+ returnToNormal(dataPoint);
}
}
@@ -369,11 +380,11 @@ public String getDetails() {
}
private String getPoints() {
- if(dataPoints == null) {
+ if(points == null) {
return "";
}
StringBuilder info = new StringBuilder();
- for(DataPointRT dataPoint: dataPoints) {
+ for(DataPointRT dataPoint: points) {
info.append(LoggingUtils.dataPointInfo(dataPoint.getVO())).append("\n");
}
return info.toString();
@@ -391,7 +402,6 @@ void pollDevice(RemoteDevice d, List points, long time) {
try {
// Send the read request.
PropertyValues values = localDevice.readProperties(d, refs);
-
// Dereference the property values back into the points.
for (DataPointRT dp : points) {
BACnetIPPointLocatorRT locator = dp.getPointLocator();
@@ -416,19 +426,20 @@ public void forcePointRead(DataPointRT dataPoint) {
dereferencePoint(dataPoint, ack.getValue(), System.currentTimeMillis());
}
catch (BACnetException e) {
- fireMessageExceptionEvent("event.bacnet.readDevice", d.getAddress().toIpString(), e.getMessage());
+ fireMessageExceptionEvent(dataPoint, "event.bacnet.readDevice", d.getAddress().toIpString(), e.getMessage());
}
}
private void dereferencePoint(DataPointRT dp, Encodable encodable, long time) {
- if (encodable == null)
- fireDeviceExceptionEvent("event.bacnet.readError", dp.getVO().getName(), "no value returned");
- else if (encodable instanceof BACnetError)
- fireDeviceExceptionEvent("event.bacnet.readError", dp.getVO().getName(),
- ((BACnetError) encodable).getErrorCode());
- else {
+ if (encodable == null) {
+ fireDeviceExceptionEvent(dp, "event.bacnet.readError", dp.getVO().getName(), "no value returned");
+ } else if (encodable instanceof BACnetError) {
+ fireDeviceExceptionEvent(dp, "event.bacnet.readError", dp.getVO().getName(),
+ String.valueOf(((BACnetError) encodable).getErrorCode()));
+ } else {
MangoValue value = encodableToValue(encodable, dp.getDataTypeId());
dp.updatePointValue(new PointValueTime(value, time));
+ returnToNormal(dp);
}
}
@@ -447,9 +458,10 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime pvt, SetPointSou
new UnsignedInteger(locator.getWritePriority()));
localDevice.send(locator.getRemoteDevice(), writeRequest);
dataPoint.setPointValue(pvt, source);
+ returnToNormal(dataPoint);
}
catch (Throwable t) {
- fireMessageExceptionEvent("event.setPointFailed", t.getMessage());
+ fireMessageExceptionEvent(dataPoint, "event.setPointFailed", t.getMessage());
}
}
@@ -469,11 +481,12 @@ public void relinquish(DataPointRT dataPoint) {
forcePointRead(dataPoint);
}
catch (Throwable t) {
- fireMessageExceptionEvent("event.relinquishFailed", t.getMessage());
+ fireMessageExceptionEvent(dataPoint, "event.relinquishFailed", t.getMessage());
}
}
- List getDataPoints() {
+ @Override
+ protected List getDataPoints() {
return dataPoints;
}
@@ -560,6 +573,7 @@ public void covNotificationReceived(UnsignedInteger subscriberProcessIdentifier,
sendCovSubscriptionImpl(initiatingDevice, monitoredObjectIdentifier, covId, true);
}
catch (BACnetException e) { /* Ignore exceptions */
+ log.warn(LoggingUtils.info(e, this), e);
}
}
}
@@ -609,7 +623,7 @@ public void receivedThrowable(Throwable t) {
public void unimplementedVendorService(UnsignedInteger vendorId, UnsignedInteger serviceNumber, ByteQueue queue) {
log.warn("Received unimplemented vendor service: vendor id=" + vendorId + ", service number=" + serviceNumber
- + ", bytes (with context id)=" + queue);
+ + ", bytes (with context id)=" + queue + " : " + LoggingUtils.dataSourceInfo(this));
}
//
@@ -627,7 +641,7 @@ boolean sendCovSubscription(DataPointRT dataPoint, boolean unsubscribe) {
// If we are unsubscribing a failure doesn't really matter since the lease will expire eventually anyway,
// so ignore.
if (!unsubscribe) {
- fireMessageExceptionEvent("event.bacnet.covFailed",
+ fireMessageExceptionEvent(dataPoint, "event.bacnet.covFailed",
locator.getRemoteDevice().getAddress().toIpString(), e.getMessage());
disablePoint(dataPoint);
return false;
@@ -658,12 +672,24 @@ private void fireMessageExceptionEvent(Throwable t) {
log.info("", t);
}
- private void fireMessageExceptionEvent(String key, Object... args) {
- raiseEvent(MESSAGE_EXCEPTION_EVENT, System.currentTimeMillis(), false, new LocalizableMessage(key, args));
+ private void fireMessageExceptionEvent(String key, String... args) {
+ raiseEvent(MESSAGE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(key, (Object[]) args));
+ }
+
+ private void fireMessageExceptionEvent(DataPointRT dataPointRT, String key, String... args) {
+ raiseEvent(MESSAGE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(key, (Object[]) args), dataPointRT);
}
- private void fireDeviceExceptionEvent(String key, Object... args) {
- raiseEvent(DEVICE_EXCEPTION_EVENT, System.currentTimeMillis(), false, new LocalizableMessage(key, args));
+ private void fireDeviceExceptionEvent(DataPointRT dataPointRT, String key, String... args) {
+ raiseEvent(DEVICE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(key, (Object[]) args), dataPointRT);
+ }
+
+ private void returnToNormal() {
+ returnToNormal(DEVICE_EXCEPTION_EVENT, System.currentTimeMillis());
+ }
+
+ private void returnToNormal(DataPointRT dataPoint) {
+ returnToNormal(DEVICE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
}
private void disablePoint(DataPointRT dataPoint) {
@@ -780,4 +806,13 @@ else if (value instanceof AlphanumericValue) {
throw new ShouldNeverHappenException("Unknown data type: " + value.getClass().getName());
}
+
+ @Override
+ public boolean isInitialized() {
+ return initialized;
+ }
+
+ private boolean isInitialized(LocalDevice localDevice) {
+ return localDevice != null && localDevice.isInitialized() && super.isInitialized();
+ }
}
diff --git a/src/com/serotonin/mango/rt/dataSource/galil/GalilDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/galil/GalilDataSourceRT.java
index 9934955ba1..62d30be4a8 100644
--- a/src/com/serotonin/mango/rt/dataSource/galil/GalilDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/galil/GalilDataSourceRT.java
@@ -65,8 +65,10 @@ synchronized protected void doPoll(long time) {
if (socket == null) {
try {
openConnection();
- }
- catch (IOException e) {
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, time);
+ } catch (Throwable messageException) {
+ raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true, new LocalizableMessage("event.pollingError",
+ messageException.getMessage()));
return;
}
}
@@ -83,16 +85,14 @@ synchronized protected void doPoll(long time) {
try {
sendMsg = sendRequest(request, dataPoint, locator, time);
- }
- catch (IOException e) {
+ } catch (Throwable e) {
// The connection may have been reset, so try to reopen it and attempt the message again.
try {
- LOG.debug("Keep-alive connection may have been reset. Attempting to re-open.");
+ LOG.warn("Keep-alive connection may have been reset. Attempting to re-open.");
closeConnection();
openConnection();
sendMsg = sendRequest(request, dataPoint, locator, time);
- }
- catch (Exception e2) {
+ } catch (Exception e2) {
messageException = e2;
closeConnection();
break;
@@ -105,10 +105,11 @@ synchronized protected void doPoll(long time) {
}
if (messageException != null) {
+ LOG.info("Error while polling Galil device", messageException);
// Raise an event.
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true, new LocalizableMessage("event.pollingError",
messageException.getMessage()));
- LOG.info("Error while polling Galil device", messageException);
+ return;
}
else
// Deactivate any existing event.
@@ -117,6 +118,7 @@ synchronized protected void doPoll(long time) {
if (pointError != null) {
// Raise an event.
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true, pointError);
+ return;
}
else
// Deactivate any existing event.
@@ -156,11 +158,12 @@ public void initialize() {
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
}
catch (Exception e) {
+ LOG.warn("Error while initializing data source", e);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"event.initializationError", e.getMessage()));
- LOG.debug("Error while initializing data source", e);
return;
}
+ super.initialize();
}
@Override
@@ -181,33 +184,33 @@ synchronized public void setPointValue(DataPointRT dataPoint, PointValueTime val
if (socket == null) {
try {
openConnection();
- }
- catch (IOException e) {
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
+ LOG.warn("Error while initializing data source", e);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "event.galil.setPointFailed", dataPoint.getVO().getName(), e.getMessage()));
- LOG.debug("Error while initializing data source", e);
+ "event.galil.setPointFailed", dataPoint.getVO().getName(), e.getMessage()), dataPoint);
return;
}
- returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
}
GalilPointLocatorRT locator = dataPoint.getPointLocator();
GalilRequest request = locator.getSetRequest(valueTime.getValue());
if (request == null)
- raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), false, new LocalizableMessage(
- "event.galil.setRequest", dataPoint.getVO().getName(), valueTime.getValue()));
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
+ "event.galil.setRequest", dataPoint.getVO().getName(), valueTime.getValue()), dataPoint);
else {
try {
GalilResponse response = (GalilResponse) conn.send(request);
if (response.isErrorResponse())
- raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), false, new LocalizableMessage(
- "event.galil.setResponse", dataPoint.getVO().getName()));
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
+ "event.galil.setResponse", dataPoint.getVO().getName()), dataPoint);
else {
try {
// Update the data image with the new value.
dataPoint.updatePointValue(new PointValueTime(valueTime.getValue(), valueTime.getTime()));
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
MangoValue value = locator.parseSetResponse(response.getResponseData());
if (value != null)
@@ -215,15 +218,15 @@ synchronized public void setPointValue(DataPointRT dataPoint, PointValueTime val
dataPoint.updatePointValue(new PointValueTime(value, System.currentTimeMillis()));
}
catch (LocalizableException e) {
- raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), false,
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
new LocalizableMessage("event.galil.parsingError", dataPoint.getVO().getName(),
- response.getResponseData()));
+ response.getResponseData()), dataPoint);
}
}
}
- catch (IOException e) {
- raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), false, new LocalizableMessage(
- "event.galil.sendError", dataPoint.getVO().getName(), e.getMessage()));
+ catch (Throwable e) {
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
+ "event.galil.sendError", dataPoint.getVO().getName(), e.getMessage()), dataPoint);
}
}
}
diff --git a/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java
index afc9239d2a..ce8094ec98 100644
--- a/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/http/HttpImageDataSourceRT.java
@@ -92,10 +92,12 @@ protected void doPoll(long time) {
}
// Check the results.
- if (monitor.getRetrievalFailure() != null)
+ if (monitor.getRetrievalFailure() != null) {
raiseEvent(DATA_RETRIEVAL_FAILURE_EVENT, time, true, monitor.getRetrievalFailure());
- else
+ return;
+ } else {
returnToNormal(DATA_RETRIEVAL_FAILURE_EVENT, time);
+ }
if (monitor.getSaveFailure() != null)
raiseEvent(FILE_SAVE_EXCEPTION_EVENT, time, true, monitor.getSaveFailure());
diff --git a/src/com/serotonin/mango/rt/dataSource/http/HttpReceiverDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/http/HttpReceiverDataSourceRT.java
index 6fd1ef1bfa..6ccf382673 100644
--- a/src/com/serotonin/mango/rt/dataSource/http/HttpReceiverDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/http/HttpReceiverDataSourceRT.java
@@ -18,6 +18,8 @@
*/
package com.serotonin.mango.rt.dataSource.http;
+import com.serotonin.mango.util.LoggingUtils;
+import com.serotonin.web.i18n.LocalizableMessage;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -36,6 +38,8 @@
* @author Matthew Lohbihler
*/
public class HttpReceiverDataSourceRT extends EventDataSource implements HttpMulticastListener {
+
+ public static final int INITIALIZATION_EXCEPTION_EVENT = 1;
private final Log log = LogFactory.getLog(HttpReceiverDataSourceRT.class);
private final HttpReceiverDataSourceVO vo;
@@ -51,14 +55,26 @@ public HttpReceiverDataSourceRT(HttpReceiverDataSourceVO vo) {
//
@Override
public void initialize() {
- Common.ctx.getHttpReceiverMulticaster().addListener(this);
+ try {
+ Common.ctx.getHttpReceiverMulticaster().addListener(this);
+ returnToNormal(INITIALIZATION_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(INITIALIZATION_EXCEPTION_EVENT,
+ System.currentTimeMillis(), true, new LocalizableMessage(
+ "event.initializationError", e.getMessage()));
+ return;
+ }
super.initialize();
}
@Override
public void terminate() {
super.terminate();
- Common.ctx.getHttpReceiverMulticaster().removeListener(this);
+ try {
+ Common.ctx.getHttpReceiverMulticaster().removeListener(this);
+ } catch (Throwable e) {
+ log.warn(LoggingUtils.info(e, this), e);
+ }
}
//
diff --git a/src/com/serotonin/mango/rt/dataSource/http/HttpRetrieverDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/http/HttpRetrieverDataSourceRT.java
index 503a4e3a57..9a714fcbf6 100644
--- a/src/com/serotonin/mango/rt/dataSource/http/HttpRetrieverDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/http/HttpRetrieverDataSourceRT.java
@@ -71,7 +71,7 @@ public HttpRetrieverDataSourceRT(HttpRetrieverDataSourceVO vo, StopSleepRT stopS
@Override
public void removeDataPoint(DataPointRT dataPoint) {
- returnToNormal(PARSE_EXCEPTION_EVENT, System.currentTimeMillis());
+ returnToNormal(PARSE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
super.removeDataPoint(dataPoint);
}
@@ -127,7 +127,7 @@ protected void doPoll(long time) {
}
if (parseErrorMessage != null)
- raiseEvent(PARSE_EXCEPTION_EVENT, time, false, parseErrorMessage);
+ raiseEvent(PARSE_EXCEPTION_EVENT, time, true, parseErrorMessage);
else
returnToNormal(PARSE_EXCEPTION_EVENT, time);
}
diff --git a/src/com/serotonin/mango/rt/dataSource/jmx/JmxDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/jmx/JmxDataSourceRT.java
index a5c8be4094..e1599968c9 100644
--- a/src/com/serotonin/mango/rt/dataSource/jmx/JmxDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/jmx/JmxDataSourceRT.java
@@ -124,7 +124,7 @@ protected void doPoll(long time) {
public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPointSource source) {
if (server == null) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.writeFailed", dataPoint.getVO().getName()));
+ "dsEdit.jmx.writeFailed", dataPoint.getVO().getName()), dataPoint);
return;
}
@@ -132,13 +132,13 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPo
JmxPointLocatorRT loc = dataPoint.getPointLocator();
if (loc.getObjectName() == null) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.writeFailed", dataPoint.getVO().getName()));
+ "dsEdit.jmx.writeFailed", dataPoint.getVO().getName()), dataPoint);
return;
}
if (loc.isComposite()) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.writeFailed.composite", dataPoint.getVO().getName()));
+ "dsEdit.jmx.writeFailed.composite", dataPoint.getVO().getName()), dataPoint);
return;
}
@@ -146,10 +146,11 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPo
loc.mangoValueToManagementValue(valueTime.getValue()));
try {
server.setAttribute(loc.getObjectName(), attr);
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
}
catch (Exception e) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.writeFailed.msg", dataPoint.getVO().getName(), e.getMessage()));
+ "dsEdit.jmx.writeFailed.msg", dataPoint.getVO().getName(), e.getMessage()), dataPoint);
}
}
@@ -206,12 +207,12 @@ private boolean updateDataPoint(DataPointRT dp) {
catch (MalformedObjectNameException e) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true,
new LocalizableMessage("dsEdit.jmx.objectNameError", loc.getPointLocatorVO().getObjectName(),
- dp.getVO().getName(), e.getMessage()));
+ dp.getVO().getName(), e.getMessage()), dp);
return false;
}
catch (NullPointerException e) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.objectNameNotFound", loc.getPointLocatorVO().getObjectName(), dp.getVO().getName()));
+ "dsEdit.jmx.objectNameNotFound", loc.getPointLocatorVO().getObjectName(), dp.getVO().getName()), dp);
return false;
}
updated = true;
@@ -224,7 +225,7 @@ private boolean updateDataPoint(DataPointRT dp) {
}
catch (Exception e) {
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "common.default", e.getMessage()));
+ "common.default", e.getMessage()), dp);
return false;
}
@@ -232,7 +233,7 @@ private boolean updateDataPoint(DataPointRT dp) {
if (attr == null) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"dsEdit.jmx.attributeNameNotFound", loc.getPointLocatorVO().getAttributeName(), dp.getVO()
- .getName()));
+ .getName()), dp);
return false;
}
@@ -242,7 +243,7 @@ private boolean updateDataPoint(DataPointRT dp) {
if (!JmxPointLocatorRT.isValidType(type)) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.attributeTypeNotSupported", type, dp.getVO().getName()));
+ "dsEdit.jmx.attributeTypeNotSupported", type, dp.getVO().getName()), dp);
return false;
}
@@ -251,7 +252,7 @@ private boolean updateDataPoint(DataPointRT dp) {
if (!attr.getType().equals("javax.management.openmbean.CompositeData")) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"dsEdit.jmx.attributeNotComposite", loc.getPointLocatorVO().getAttributeName(), dp.getVO()
- .getName()));
+ .getName()), dp);
return false;
}
@@ -261,7 +262,7 @@ private boolean updateDataPoint(DataPointRT dp) {
}
catch (Exception e) {
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "common.default", e.getMessage()));
+ "common.default", e.getMessage()), dp);
return false;
}
@@ -269,7 +270,7 @@ private boolean updateDataPoint(DataPointRT dp) {
if (openType == null) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"dsEdit.jmx.compositeNameNotFound", loc.getPointLocatorVO().getCompositeItemName(), dp
- .getVO().getName()));
+ .getVO().getName()), dp);
return false;
}
@@ -277,7 +278,7 @@ private boolean updateDataPoint(DataPointRT dp) {
if (!JmxPointLocatorRT.isValidType(type)) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
- "dsEdit.jmx.compositeTypeNotSupported", type, dp.getVO().getName()));
+ "dsEdit.jmx.compositeTypeNotSupported", type, dp.getVO().getName()), dp);
return false;
}
}
diff --git a/src/com/serotonin/mango/rt/dataSource/mbus/MBusDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/mbus/MBusDataSourceRT.java
index 3d23917390..72e673ab08 100644
--- a/src/com/serotonin/mango/rt/dataSource/mbus/MBusDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/mbus/MBusDataSourceRT.java
@@ -61,13 +61,13 @@ public MBusDataSourceRT(MBusDataSourceVO vo) {
@Override
public void initialize() {
- LOG.fatal("INITIALIZE MBusaDataSourceRT" + Thread.getAllStackTraces().get(Thread.currentThread()));
+ LOG.debug("INITIALIZE MBusaDataSourceRT" + Thread.getAllStackTraces().get(Thread.currentThread()));
super.initialize();
}
@Override
public void terminate() {
- LOG.fatal("TERMINATE MBusaDataSourceRT" + Thread.getAllStackTraces().get(Thread.currentThread()));
+ LOG.debug("TERMINATE MBusaDataSourceRT" + Thread.getAllStackTraces().get(Thread.currentThread()));
super.terminate();
}
@@ -184,6 +184,7 @@ private boolean openConnection() {
private void closeConnection() {
try {
master.close();
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
} catch (IOException ex) {
LOG.fatal("Close port", ex);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
diff --git a/src/com/serotonin/mango/rt/dataSource/meta/HistoricalMetaPointLocatorRT.java b/src/com/serotonin/mango/rt/dataSource/meta/HistoricalMetaPointLocatorRT.java
index ec13289060..4f8a130b69 100644
--- a/src/com/serotonin/mango/rt/dataSource/meta/HistoricalMetaPointLocatorRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/meta/HistoricalMetaPointLocatorRT.java
@@ -1,19 +1,12 @@
package com.serotonin.mango.rt.dataSource.meta;
-import java.util.HashMap;
-
-import com.serotonin.db.IntValuePair;
-import com.serotonin.mango.db.dao.DataPointDao;
-import com.serotonin.mango.db.dao.PointValueDao;
import com.serotonin.mango.rt.dataImage.DataPointRT;
-import com.serotonin.mango.rt.dataImage.HistoricalDataPoint;
-import com.serotonin.mango.rt.dataImage.IDataPoint;
import com.serotonin.mango.rt.dataImage.PointValueTime;
-import com.serotonin.mango.vo.DataPointVO;
import com.serotonin.mango.vo.dataSource.meta.MetaPointLocatorVO;
import com.serotonin.timer.SimulationTimer;
import com.serotonin.web.i18n.LocalizableMessage;
+@Deprecated(since = "2.8.0")
public class HistoricalMetaPointLocatorRT extends MetaPointLocatorRT {
private long updates;
@@ -26,16 +19,7 @@ public void initialize(SimulationTimer timer, DataPointRT dataPoint) {
this.dataPoint = dataPoint;
initialized = true;
initializeTimerTask();
-
- context = new HashMap();
- DataPointDao dataPointDao = new DataPointDao();
- PointValueDao pointValueDao = new PointValueDao();
- for (IntValuePair contextEntry : vo.getContext()) {
- DataPointVO cvo = dataPointDao.getDataPoint(contextEntry.getKey());
- HistoricalDataPoint point = new HistoricalDataPoint(cvo.getId(), cvo.getPointLocator().getDataTypeId(),
- timer, pointValueDao);
- context.put(contextEntry.getValue(), point);
- }
+ this.context = createContext(dataPoint);
}
@Override
@@ -52,13 +36,13 @@ public long getUpdates() {
}
@Override
- protected void updatePoint(PointValueTime pvt) {
- super.updatePoint(pvt);
+ protected void doUpdate(PointValueTime pvt, DataPointRT dataPoint) {
+ super.doUpdate(pvt, dataPoint);
updates++;
}
@Override
- protected void handleError(long runtime, LocalizableMessage message) {
+ protected void handleScriptError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
throw new MetaPointExecutionException(message);
}
}
diff --git a/src/com/serotonin/mango/rt/dataSource/meta/MetaDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/meta/MetaDataSourceRT.java
index ed814affe1..1e1761dea7 100644
--- a/src/com/serotonin/mango/rt/dataSource/meta/MetaDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/meta/MetaDataSourceRT.java
@@ -31,6 +31,8 @@
import com.serotonin.mango.vo.dataSource.meta.MetaDataSourceVO;
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.*;
+
/**
* @author Matthew Lohbihler
*/
@@ -40,6 +42,7 @@ public class MetaDataSourceRT extends DataSourceRT {
public static final int EVENT_TYPE_RESULT_TYPE_ERROR = 3;
private final List points = new CopyOnWriteArrayList();
+ @Deprecated(since = "2.8.0")
private boolean contextPointDisabledEventActive;
public MetaDataSourceRT(MetaDataSourceVO vo) {
@@ -59,7 +62,6 @@ public void addDataPoint(DataPointRT dataPoint) {
MetaPointLocatorRT locator = dataPoint.getPointLocator();
points.add(dataPoint);
locator.initialize(Common.timer, this, dataPoint);
- checkForDisabledPoints();
}
}
@@ -67,7 +69,6 @@ public void addDataPoint(DataPointRT dataPoint) {
public void removeDataPoint(DataPointRT dataPoint) {
synchronized (pointListChangeLock) {
remove(dataPoint);
- checkForDisabledPoints();
}
}
@@ -77,6 +78,7 @@ private void remove(DataPointRT dataPoint) {
points.remove(dataPoint);
}
+ @Deprecated(since = "2.8.0")
synchronized void checkForDisabledPoints() {
DataPointRT problemPoint = null;
@@ -93,7 +95,7 @@ synchronized void checkForDisabledPoints() {
if (contextPointDisabledEventActive)
// A context point has been terminated, was never enabled, or not longer exists.
raiseEvent(EVENT_TYPE_CONTEXT_POINT_DISABLED, System.currentTimeMillis(), true, new LocalizableMessage(
- "event.meta.pointUnavailable", problemPoint.getVO().getName()));
+ "event.meta.pointUnavailable", problemPoint.getVO().getName()), problemPoint);
else
// Everything is good
returnToNormal(EVENT_TYPE_CONTEXT_POINT_DISABLED, System.currentTimeMillis());
@@ -101,17 +103,53 @@ synchronized void checkForDisabledPoints() {
}
public void raiseScriptError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
- if(isNone(EVENT_TYPE_SCRIPT_ERROR))
+ if(isNone(EVENT_TYPE_SCRIPT_ERROR)) {
+ setUnreliableDataPoint(dataPoint);
+ return;
+ }
+ raiseEvent(EVENT_TYPE_SCRIPT_ERROR, runtime, true, new LocalizableMessage("event.meta.scriptError", dataPoint
+ .getVO().getName(), message), dataPoint);
+ }
+
+ public void raiseContextError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
+ if(isNone(EVENT_TYPE_CONTEXT_POINT_DISABLED)) {
+ setUnreliableDataPoint(dataPoint);
+ return;
+ }
+ raiseEvent(EVENT_TYPE_CONTEXT_POINT_DISABLED, runtime, true, message, dataPoint);
+ }
+
+ public void returnToNormalScript(long runtime, DataPointRT dataPoint) {
+ if(isNone(EVENT_TYPE_SCRIPT_ERROR)) {
+ resetUnreliableDataPoint(dataPoint);
+ return;
+ }
+ returnToNormal(EVENT_TYPE_SCRIPT_ERROR, runtime, dataPoint);
+ }
+
+ public void returnToNormalContext(long runtime, DataPointRT dataPoint) {
+ if(isNone(EVENT_TYPE_CONTEXT_POINT_DISABLED)) {
+ resetUnreliableDataPoint(dataPoint);
return;
- raiseEvent(EVENT_TYPE_SCRIPT_ERROR, runtime, false, new LocalizableMessage("event.meta.scriptError", dataPoint
- .getVO().getName(), message));
+ }
+ returnToNormal(EVENT_TYPE_CONTEXT_POINT_DISABLED, runtime, dataPoint);
}
public void raiseResultTypeError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
- if(isNone(EVENT_TYPE_RESULT_TYPE_ERROR))
+ if(isNone(EVENT_TYPE_RESULT_TYPE_ERROR)) {
+ setUnreliableDataPoint(dataPoint);
return;
- raiseEvent(EVENT_TYPE_RESULT_TYPE_ERROR, runtime, false, new LocalizableMessage("event.meta.typeError",
- dataPoint.getVO().getName(), message));
+ }
+ raiseEvent(EVENT_TYPE_RESULT_TYPE_ERROR, runtime, true, new LocalizableMessage("event.meta.typeError",
+ dataPoint.getVO().getName(), message), dataPoint);
+ }
+
+ public void returnToNormalType(long runtime, DataPointRT dataPoint) {
+ if(isNone(EVENT_TYPE_RESULT_TYPE_ERROR)) {
+ resetUnreliableDataPoint(dataPoint);
+ return;
+ }
+ returnToNormal(EVENT_TYPE_RESULT_TYPE_ERROR, runtime, dataPoint);
}
private boolean isNone(int type) {
@@ -120,4 +158,9 @@ private boolean isNone(int type) {
return true;
return object.getAlarmLevel() == AlarmLevels.NONE;
}
+
+ @Override
+ protected List getDataPoints() {
+ return points;
+ }
}
diff --git a/src/com/serotonin/mango/rt/dataSource/meta/MetaPointLocatorRT.java b/src/com/serotonin/mango/rt/dataSource/meta/MetaPointLocatorRT.java
index 1c382958d7..848f19f00b 100644
--- a/src/com/serotonin/mango/rt/dataSource/meta/MetaPointLocatorRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/meta/MetaPointLocatorRT.java
@@ -24,6 +24,7 @@
import java.util.Date;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
import javax.script.ScriptException;
@@ -37,6 +38,7 @@
import com.serotonin.mango.rt.dataImage.PointValueTime;
import com.serotonin.mango.rt.dataSource.PointLocatorRT;
import com.serotonin.mango.util.DateUtils;
+import com.serotonin.mango.util.LoggingUtils;
import com.serotonin.mango.vo.dataSource.meta.MetaPointLocatorVO;
import com.serotonin.timer.AbstractTimer;
import com.serotonin.timer.CronExpression;
@@ -64,11 +66,14 @@ public class MetaPointLocatorRT extends PointLocatorRT implements DataPointListe
AbstractTimer timer;
private MetaDataSourceRT dataSource;
protected DataPointRT dataPoint;
- protected Map context;
+ protected volatile Map context;
boolean initialized;
TimerTask timerTask;
- private final static Log LOG = LogFactory.getLog(MetaPointLocatorRT.class);
+ private final AtomicInteger pointInitializedSafe = new AtomicInteger(MAX_RECURSION);
+ private final AtomicInteger pointTerminatedSafe = new AtomicInteger(MAX_RECURSION);
+
+ private static final Log LOG = LogFactory.getLog(MetaPointLocatorRT.class);
public MetaPointLocatorRT(MetaPointLocatorVO vo) {
this.vo = vo;
@@ -83,6 +88,7 @@ public MetaPointLocatorVO getPointLocatorVO() {
return vo;
}
+ @Deprecated(since = "2.8.0")
boolean isContextCreated() {
return context != null;
}
@@ -97,7 +103,7 @@ public void initialize(AbstractTimer timer, MetaDataSourceRT dataSource, DataPoi
this.dataSource = dataSource;
this.dataPoint = dataPoint;
- createContext();
+ this.context = createContext(dataPoint);
// Add listener registrations
RuntimeManager rm = Common.ctx.getRuntimeManager();
@@ -107,10 +113,10 @@ public void initialize(AbstractTimer timer, MetaDataSourceRT dataSource, DataPoi
rm.addDataPointListener(contextKey.getKey(), this);
}
- initialized = true;
-
initializeTimerTask();
+ initialized = true;
+
if(dataPoint.isInitialized() && (vo.getUpdateEvent() == MetaPointLocatorVO.UPDATE_EVENT_CONTEXT_CHANGE
|| vo.getUpdateEvent() == MetaPointLocatorVO.UPDATE_EVENT_CONTEXT_UPDATE) && !vo.getContext().isEmpty()) {
execute(System.currentTimeMillis(), new ArrayList<>(), true, dataPoint);
@@ -166,13 +172,43 @@ public void pointBackdated(PointValueTime value) {
}
public void pointInitialized() {
- createContext();
- dataSource.checkForDisabledPoints();
+
+ context = createContext(dataPoint);
+
+ if(context == null) {
+ return;
+ }
+
+ if(pointInitializedSafe.getAndDecrement() < 0) {
+ LOG.error("Exceeded recursive level: " + LoggingUtils.dataPointInfo(dataPoint));
+ pointInitializedSafe.set(MAX_RECURSION);
+ return;
+ }
+
+ if(dataPoint.getPointLocator() instanceof MetaPointLocatorRT) {
+ DataPointListener dataPointListener = Common.ctx.getRuntimeManager().getDataPointListeners(dataPoint.getId());
+ if(dataPointListener != null) {
+ dataPointListener.pointInitialized();
+ }
+ }
}
public void pointTerminated() {
- createContext();
- dataSource.checkForDisabledPoints();
+
+ context = createContext(dataPoint);
+
+ if(pointTerminatedSafe.getAndDecrement() < 0) {
+ LOG.error("Exceeded recursive level: " + LoggingUtils.dataPointInfo(dataPoint));
+ pointTerminatedSafe.set(MAX_RECURSION);
+ return;
+ }
+
+ if(dataPoint.getPointLocator() instanceof MetaPointLocatorRT) {
+ DataPointListener dataPointListener = Common.ctx.getRuntimeManager().getDataPointListeners(dataPoint.getId());
+ if(dataPointListener != null) {
+ dataPointListener.pointTerminated();
+ }
+ }
}
//
@@ -238,7 +274,8 @@ private void execute(long runtime, List sourceIds) {
}
private void execute(long runtime, List sourceIds, boolean initializeMode, DataPointRT dataPoint) {
- if (context == null) {
+ this.context = createContext(dataPoint);
+ if(context == null) {
LOG.warn("MetaPointLocatorRT.context is null, Context: " + generateContext(dataPoint, dataSource));
return;
}
@@ -251,11 +288,13 @@ private void execute(long runtime, List sourceIds, boolean initializeMo
}
if (count > MAX_RECURSION) {
- handleError(runtime, new LocalizableMessage("event.meta.recursionFailure"));
+ handleScriptError(runtime, dataPoint, new LocalizableMessage("event.meta.recursionFailure"));
String msg = MessageFormat.format("Recursion failure: exceeded MAX_RECURSION: expected <= {0} but was {1}, Context: {2}",
String.valueOf(MAX_RECURSION), count, generateContext(dataPoint, dataSource));
LOG.warn(msg);
return;
+ } else {
+ returnToNormal(runtime, dataPoint);
}
sourceIds.add(dataPoint.getId());
@@ -265,23 +304,21 @@ private void execute(long runtime, List sourceIds, boolean initializeMo
try {
PointValueTime valueTime = executor.execute(vo.getScript(), context, timer.currentTimeMillis(),
vo.getDataTypeId(), runtime);
+ returnToNormalType(System.currentTimeMillis(), dataPoint);
PointValueTime previousValueTime = dataPoint.getPointValue();
if (valueTime.getValue() == null)
- handleError(runtime, new LocalizableMessage("event.meta.nullResult"));
+ handleScriptError(runtime, dataPoint, new LocalizableMessage("event.meta.nullResult"));
else if(isUpdatePoint(initializeMode, valueTime, previousValueTime, vo))
- updatePoint(valueTime);
- }
- catch (ScriptException e) {
- handleError(runtime, new LocalizableMessage("common.default", e.getMessage()));
+ doUpdate(valueTime, dataPoint);
+ } catch (ScriptException e) {
+ handleScriptError(runtime, dataPoint, new LocalizableMessage("common.default", e.getLocalizedMessage()));
LOG.warn(infoErrorExecutionScript(e, dataPoint, dataSource));
- }
- catch (ResultTypeException e) {
- handleError(runtime, e.getLocalizableMessage());
+ } catch (ResultTypeException e) {
+ handleTypeError(runtime, dataPoint, e.getLocalizableMessage());
LOG.warn(infoErrorExecutionScript(e, dataPoint, dataSource));
- }
- catch (Exception e) {
+ } catch (Exception e) {
+ handleScriptError(runtime, dataPoint, new LocalizableMessage("common.default", e.getMessage()));
LOG.warn(infoErrorExecutionScript(e, dataPoint, dataSource));
- throw e;
}
}
finally {
@@ -289,13 +326,16 @@ else if(isUpdatePoint(initializeMode, valueTime, previousValueTime, vo))
}
}
- private void createContext() {
- context = null;
+ protected Map createContext(DataPointRT dataPoint) {
+ Map context;
try {
ScriptExecutor scriptExecutor = new ScriptExecutor();
- context = scriptExecutor.convertContext(vo.getContext());
+ context = scriptExecutor.convertContext(vo.getContext(), dataPoint, this.dataSource);
+ returnToNormalContext(System.currentTimeMillis(), dataPoint);
+ return context;
} catch (Exception e) {
LOG.warn(infoErrorInitializationScript(e, dataPoint, dataSource));
+ return null;
}
}
@@ -325,14 +365,35 @@ private void execute(PointValueTime newValue, boolean initializeMode) {
}
}
- protected void updatePoint(PointValueTime pvt) {
+ protected void doUpdate(PointValueTime pvt, DataPointRT dataPoint) {
dataPoint.updatePointValue(pvt);
+ returnToNormal(System.currentTimeMillis(), dataPoint);
}
- protected void handleError(long runtime, LocalizableMessage message) {
+ protected void handleScriptError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
dataSource.raiseScriptError(runtime, dataPoint, message);
}
+ protected void handleContextError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
+ dataSource.raiseContextError(runtime, dataPoint, message);
+ }
+
+ protected void returnToNormal(long runtime, DataPointRT dataPoint) {
+ dataSource.returnToNormalScript(runtime, dataPoint);
+ }
+
+ protected void returnToNormalContext(long runtime, DataPointRT dataPoint) {
+ dataSource.returnToNormalContext(runtime, dataPoint);
+ }
+
+ protected void handleTypeError(long runtime, DataPointRT dataPoint, LocalizableMessage message) {
+ dataSource.raiseResultTypeError(runtime, dataPoint, message);
+ }
+
+ protected void returnToNormalType(long runtime, DataPointRT dataPoint) {
+ dataSource.returnToNormalType(runtime, dataPoint);
+ }
+
private static boolean isUpdatePoint(boolean initializeMode, PointValueTime valueTime, PointValueTime previousValueTime, MetaPointLocatorVO metaPointLocator) {
return !initializeMode || (metaPointLocator.getUpdateEvent() != MetaPointLocatorVO.UPDATE_EVENT_CONTEXT_CHANGE
&& metaPointLocator.getUpdateEvent() != MetaPointLocatorVO.UPDATE_EVENT_CONTEXT_UPDATE)
diff --git a/src/com/serotonin/mango/rt/dataSource/meta/ScriptExecutor.java b/src/com/serotonin/mango/rt/dataSource/meta/ScriptExecutor.java
index 99f4ef9a4a..7531af6b22 100644
--- a/src/com/serotonin/mango/rt/dataSource/meta/ScriptExecutor.java
+++ b/src/com/serotonin/mango/rt/dataSource/meta/ScriptExecutor.java
@@ -28,6 +28,7 @@
import javax.script.ScriptException;
+import com.serotonin.mango.util.LoggingUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.mozilla.javascript.Context;
@@ -64,22 +65,52 @@ public static void setScriptFunctionPath(String path) {
SCRIPT_FUNCTION_PATH = path;
}
- public Map convertContext(List context)
- throws DataPointStateException {
+ public Map convertContext(List context) throws Exception {
+ return convertContext(context, null, null);
+ }
+
+ public Map convertContext(List context, DataPointRT dataPoint, MetaDataSourceRT metaDataSource) throws Exception {
RuntimeManager rtm = Common.ctx.getRuntimeManager();
- Map converted = new HashMap();
+ Map converted = new HashMap<>();
+ List exceptions = new ArrayList<>();
for (IntValuePair contextEntry : context) {
- DataPointRT point = rtm.getDataPoint(contextEntry.getKey());
- if (point == null) {
- LOG.error("Error DataPointRT null "
- + new Exception("key:" + contextEntry.getKey()
- + " value:" + contextEntry.getValue()));
- throw new DataPointStateException(contextEntry.getKey(),
- new LocalizableMessage("event.meta.pointMissing"));
+ if(dataPoint == null || dataPoint.getId() == Common.NEW_ID || dataPoint.getId() != contextEntry.getKey()) {
+ DataPointRT point = rtm.getDataPoint(contextEntry.getKey());
+ if (point == null) {
+ LOG.error("Error DataPointRT null "
+ + new Exception("key:" + contextEntry.getKey()
+ + " value:" + contextEntry.getValue()));
+ DataPointStateException dataPointStateException = createPointUnavailableException(contextEntry);
+ if(dataPoint != null && metaDataSource != null) {
+ metaDataSource.raiseContextError(System.currentTimeMillis(), dataPoint, dataPointStateException.getLocalizableMessage());
+ }
+ exceptions.add(dataPointStateException);
+ } else if (point.isUnreliable()) {
+ LOG.warn("Error DataPointRT is unavailable "
+ + new Exception("key:" + contextEntry.getKey()
+ + " value:" + contextEntry.getValue()) + " - " + LoggingUtils.dataPointInfo(point));
+ DataPointStateException dataPointStateException = createPointUnavailableException(contextEntry, point);
+ if(dataPoint != null && metaDataSource != null) {
+ metaDataSource.raiseContextError(System.currentTimeMillis(), dataPoint, dataPointStateException.getLocalizableMessage());
+ }
+ exceptions.add(dataPointStateException);
+ } else {
+ converted.put(contextEntry.getValue(), point);
+ }
}
- converted.put(contextEntry.getValue(), point);
}
+ if(!exceptions.isEmpty()) {
+ StringBuilder messages = new StringBuilder();
+ for(DataPointStateException exception: exceptions) {
+ LocalizableMessage localizableMessage = exception.getLocalizableMessage();
+ String message = localizableMessage.getLocalizedMessage(Common.getBundle());
+ messages.append(message).append(";");
+ }
+ throw new Exception(messages.toString());
+ }
+ if(dataPoint != null && metaDataSource != null)
+ metaDataSource.returnToNormalContext(System.currentTimeMillis(), dataPoint);
return converted;
}
@@ -336,4 +367,14 @@ private static void ensureFunctions() {
FUNCTIONS = sw.toString();
}
}
+
+ private static DataPointStateException createPointUnavailableException(IntValuePair contextEntry, DataPointRT point) {
+ return new DataPointStateException(contextEntry.getKey(),
+ new LocalizableMessage("event.meta.pointUnavailable", point.getVO().getExtendedName()));
+ }
+
+ private static DataPointStateException createPointUnavailableException(IntValuePair contextEntry) {
+ return new DataPointStateException(contextEntry.getKey(),
+ new LocalizableMessage("validate.invalidVariable", LoggingUtils.varInfo(contextEntry)));
+ }
}
diff --git a/src/com/serotonin/mango/rt/dataSource/modbus/ModbusDataSource.java b/src/com/serotonin/mango/rt/dataSource/modbus/ModbusDataSource.java
index 5361b9ca47..d603047bb7 100644
--- a/src/com/serotonin/mango/rt/dataSource/modbus/ModbusDataSource.java
+++ b/src/com/serotonin/mango/rt/dataSource/modbus/ModbusDataSource.java
@@ -25,6 +25,7 @@
import java.util.List;
import java.util.Map;
+import com.serotonin.mango.util.LoggingUtils;
import com.serotonin.modbus4j.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -50,6 +51,9 @@
import com.serotonin.modbus4j.sero.messaging.TimeoutException;
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.*;
+import static com.serotonin.mango.rt.dataSource.DataSourceUtils.checkInitialized;
+
abstract public class ModbusDataSource extends PollingDataSource implements
MessagingExceptionHandler {
private final Log LOG = LogFactory.getLog(ModbusDataSource.class);
@@ -58,6 +62,8 @@ abstract public class ModbusDataSource extends PollingDataSource implements
public static final int POINT_READ_EXCEPTION_EVENT = 1;
public static final int POINT_WRITE_EXCEPTION_EVENT = 2;
public static final int DATA_SOURCE_EXCEPTION_EVENT = 3;
+ public static final int MONITOR_WRITE_EXCEPTION_EVENT = 4;
+ public static final int INITIALIZATION_EXCEPTION_EVENT = 5;
private ModbusMaster modbusMaster;
private BatchRead batchRead;
@@ -78,7 +84,7 @@ public void addDataPoint(DataPointRT dataPoint) {
// Mark the point as unreliable.
ModbusPointLocatorVO locatorVO = dataPoint.getVO().getPointLocator();
if (!locatorVO.isSlaveMonitor() && !locatorVO.isSocketMonitor())
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ setUnreliableDataPoint(dataPoint);
// Slave monitor points.
if (vo.isCreateSlaveMonitorPoints()) {
@@ -147,8 +153,14 @@ public void removeDataPoint(DataPointRT dataPoint) {
@Override
protected void doPoll(long time) {
-
-
+ try {
+ checkInitialized(modbusMaster, this);
+ returnToNormal(INITIALIZATION_EXCEPTION_EVENT, time);
+ } catch (Throwable e) {
+ raiseEvent(INITIALIZATION_EXCEPTION_EVENT, time, true,
+ getLocalExceptionMessage(e));
+ return;
+ }
if (!modbusMaster.isInitialized()) {
if (vo.isCreateSlaveMonitorPoints()) {
@@ -188,6 +200,9 @@ protected void doPoll(long time) {
}
}
} catch (Exception e) {
+ LOG.warn(LoggingUtils.info(e, this));
+ setUnreliableDataPoints(dataPoints);
+ return;
}
try {
@@ -206,21 +221,19 @@ protected void doPoll(long time) {
if (result instanceof ExceptionResult) {
ExceptionResult exceptionResult = (ExceptionResult) result;
- LOG.trace("Point: " + locator.getVO().getOffset()
+ LOG.warn("Point: " + locator.getVO().getOffset()
+ " Exception: "
+ exceptionResult.getExceptionMessage());
if (exceptionResult.getExceptionMessage().contains(
"no active connection")) {
- LOG.trace("Cannot reach source, setting monitors to false");
+ LOG.warn("Cannot reach source, setting monitors to false");
slaveStatuses.put(locator.getVO().getSlaveId(), false);
} else {
// Raise an event.
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2",
dataPoint.getVO().getName(),
- exceptionResult.getExceptionMessage()));
-
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ exceptionResult.getExceptionMessage()), dataPoint);
// A response, albeit an undesirable one, was received
// from
@@ -239,11 +252,11 @@ protected void doPoll(long time) {
new LocalizableMessage(
"event.modbus.noConnection", dataPoint
.getVO().getDataSourceName(), e
- .getMessage()));
+ .getMessage()), dataPoint);
} else {
// Raise an event.
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, time, true,
- getLocalExceptionMessage(e));
+ getLocalExceptionMessage(e), dataPoint);
}
// Update the slave status. Only set to false if it is
@@ -254,8 +267,6 @@ protected void doPoll(long time) {
slaveStatuses.put(locator.getVO().getSlaveId(), false);
dataSourceExceptions = true;
-
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
} else {
/*
* When an event is raised from the Callback
@@ -271,13 +282,12 @@ protected void doPoll(long time) {
* it´s effective. TODO: Treat this type of exception
* only... but how?!
*/
- LOG.trace("Point: " + locator.getVO().getOffset()
+ LOG.warn("Point: " + locator.getVO().getOffset()
+ " eventRaised: " + eventRaised);
if (!eventRaised) {
- returnToNormal(POINT_READ_EXCEPTION_EVENT, time);
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, false);
updatePointValue(dataPoint, locator, result, time);
slaveStatuses.put(locator.getVO().getSlaveId(), true);
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
}
}
}
@@ -305,8 +315,14 @@ protected void doPoll(long time) {
if (oldOnline != newOnline) {
LOG.trace("Monitor.setPointValue(): " + newOnline);
- monitor.setPointValue(new PointValueTime(newOnline,
- time), null);
+ try {
+ monitor.setPointValue(new PointValueTime(newOnline,
+ time), null);
+ returnToNormal(MONITOR_WRITE_EXCEPTION_EVENT, time, monitor);
+ } catch (Exception e) {
+ raiseEvent(MONITOR_WRITE_EXCEPTION_EVENT, time, true,
+ getLocalExceptionMessage(e), monitor);
+ }
}
}
}
@@ -340,10 +356,10 @@ protected void initialize(ModbusMaster modbusMaster) {
modbusMaster.init();
// Deactivate any existing event.
- returnToNormal(DATA_SOURCE_EXCEPTION_EVENT,
+ returnToNormal(INITIALIZATION_EXCEPTION_EVENT,
System.currentTimeMillis());
- } catch (Exception e) {
- raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(),
+ } catch (Throwable e) {
+ raiseEvent(INITIALIZATION_EXCEPTION_EVENT, System.currentTimeMillis(),
true, getLocalExceptionMessage(e));
return;
}
@@ -354,26 +370,6 @@ protected void initialize(ModbusMaster modbusMaster) {
@Override
public void forcePointRead(DataPointRT dataPoint) {
- if (!modbusMaster.isInitialized()) {
- // terminate();
- //
- // vo.setEnabled(false);
- //
- // RuntimeManager runtimeManager = Common.ctx.getRuntimeManager();
- //
- // for (DataPointRT dP : dataPoints) {
- // dP.getVO().setEnabled(false);
- // }
- //
- // for (DataPointRT dP : dataPoints) {
- // dP.getVO().setEnabled(true);
- // runtimeManager.saveDataPoint(dP.getVO());
- // }
- //
- // vo.setEnabled(true);
- // runtimeManager.saveDataSource(vo);
- }
-
ModbusPointLocatorRT pl = dataPoint.getPointLocator();
if (pl.getVO().isSlaveMonitor() || pl.getVO().isSocketMonitor())
// Nothing to do
@@ -384,20 +380,18 @@ public void forcePointRead(DataPointRT dataPoint) {
synchronized (pointListChangeLock) {
try {
+ checkInitialized(modbusMaster, this);
Object value = modbusMaster.getValue(ml);
-
- returnToNormal(POINT_READ_EXCEPTION_EVENT, time);
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, false);
updatePointValue(dataPoint, pl, value, time);
+ returnToNormal(POINT_READ_EXCEPTION_EVENT, time, dataPoint);
} catch (ErrorResponseException e) {
raiseEvent(POINT_READ_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.exception2", dataPoint
- .getVO().getName(), e.getMessage()));
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
- } catch (ModbusTransportException e) {
+ .getVO().getName(), e.getMessage()), dataPoint);
+ } catch (Throwable e) {
// Don't raise a data source exception. Polling should do that.
LOG.warn("Error during forcePointRead", e);
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ setUnreliableDataPoint(dataPoint);
}
}
}
@@ -424,7 +418,8 @@ else if (pl.getVO().getDataTypeId() == DataTypes.ALPHANUMERIC)
@Override
public void terminate() {
super.terminate();
- modbusMaster.destroy();
+ if(modbusMaster != null)
+ modbusMaster.destroy();
}
//
@@ -439,6 +434,7 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
BaseLocator> ml = createModbusLocator(pl.getVO());
try {
+ checkInitialized(modbusMaster, this);
// See if this is a numeric value that needs to be converted.
if (dataPoint.getDataTypeId() == DataTypes.NUMERIC) {
double convertedValue = valueTime.getDoubleValue();
@@ -456,27 +452,31 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
dataPoint.setPointValue(valueTime, source);
// Deactivate any existing event.
- returnToNormal(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime());
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(), dataPoint);
} catch (ModbusTransportException e) {
if (e.getMessage().contains("no active connection")) {
// Raise an event.
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(),
true, new LocalizableMessage(
"event.modbus.noConnection", dataPoint.getVO()
- .getDataSourceName(), e.getMessage()));
+ .getDataSourceName(), e.getMessage()), dataPoint);
} else {
// Raise an event.
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(),
true, new LocalizableMessage("event.exception2",
- dataPoint.getVO().getName(), e.getMessage()));
+ dataPoint.getVO().getName(), e.getMessage()), dataPoint);
LOG.info("Error setting point value", e);
}
} catch (ErrorResponseException e) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(), true,
new LocalizableMessage("event.exception2", dataPoint
.getVO().getName(), e.getErrorResponse()
- .getExceptionMessage()));
+ .getExceptionMessage()), dataPoint);
LOG.info("Error setting point value", e);
+ } catch (Throwable e) {
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(),
+ true, new LocalizableMessage("event.exception2",
+ dataPoint.getVO().getName(), e.getMessage()), dataPoint);
}
}
@@ -486,7 +486,7 @@ public static BaseLocator> createModbusLocator(ModbusPointLocatorVO vo) {
vo.getRegisterCount(), Charset.forName(vo.getCharset()));
}
- public static LocalizableMessage localExceptionMessage(Exception e) {
+ public static LocalizableMessage localExceptionMessage(Throwable e) {
if (e instanceof ModbusTransportException) {
Throwable cause = e.getCause();
if (cause instanceof TimeoutException)
@@ -499,7 +499,7 @@ public static LocalizableMessage localExceptionMessage(Exception e) {
return DataSourceRT.getExceptionMessage(e);
}
- protected LocalizableMessage getLocalExceptionMessage(Exception e) {
+ protected LocalizableMessage getLocalExceptionMessage(Throwable e) {
return localExceptionMessage(e);
}
diff --git a/src/com/serotonin/mango/rt/dataSource/modbus/ModbusSerialDataSource.java b/src/com/serotonin/mango/rt/dataSource/modbus/ModbusSerialDataSource.java
index c50b129b79..c0630c9b77 100644
--- a/src/com/serotonin/mango/rt/dataSource/modbus/ModbusSerialDataSource.java
+++ b/src/com/serotonin/mango/rt/dataSource/modbus/ModbusSerialDataSource.java
@@ -112,7 +112,7 @@ public boolean verifyPort(String port) {
}
@Override
- protected LocalizableMessage getLocalExceptionMessage(Exception e) {
+ protected LocalizableMessage getLocalExceptionMessage(Throwable e) {
if (e instanceof ModbusInitException) {
Throwable cause = e.getCause();
if (cause instanceof NoSuchPortException)
diff --git a/src/com/serotonin/mango/rt/dataSource/nmea/NmeaDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/nmea/NmeaDataSourceRT.java
index 2fd36fad80..229480a1ff 100644
--- a/src/com/serotonin/mango/rt/dataSource/nmea/NmeaDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/nmea/NmeaDataSourceRT.java
@@ -91,7 +91,7 @@ synchronized private boolean initNmea() {
// Deactivate any existing event.
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
}
- catch (Exception e) {
+ catch (Throwable e) {
LocalizableMessage message = getSerialExceptionMessage(e, vo.getCommPortId());
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, message);
log.debug("Error while initializing data source", e);
@@ -102,7 +102,8 @@ synchronized private boolean initNmea() {
}
synchronized private void termNmea() {
- nmeaReceiver.terminate();
+ if(nmeaReceiver != null)
+ nmeaReceiver.terminate();
}
//
@@ -131,7 +132,7 @@ public void receivedMessage(NmeaMessage message) {
if (parseError == null)
parseError = e.getLocalizableMessage();
}
- catch (Exception e) {
+ catch (Throwable e) {
if (parseError == null)
parseError = new LocalizableMessage("event.exception2", dp.getVO().getName(), e.getMessage());
}
@@ -139,7 +140,9 @@ public void receivedMessage(NmeaMessage message) {
}
if (parseError != null)
- raiseEvent(PARSE_EXCEPTION_EVENT, time, false, parseError);
+ raiseEvent(PARSE_EXCEPTION_EVENT, time, true, parseError);
+ else
+ returnToNormal(PARSE_EXCEPTION_EVENT, time);
}
private void receivedMessageImpl(DataPointRT dp, NmeaMessage message, long time) throws Exception {
diff --git a/src/com/serotonin/mango/rt/dataSource/onewire/OneWireDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/onewire/OneWireDataSourceRT.java
index fcb8a2d38a..aee6c19a59 100644
--- a/src/com/serotonin/mango/rt/dataSource/onewire/OneWireDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/onewire/OneWireDataSourceRT.java
@@ -375,9 +375,11 @@ else if (attributeId == OneWirePointLocatorVO.AttributeTypes.WIPER_POSITION) {
// Event handling.
if (exceptionMessage != null)
- raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), false, exceptionMessage);
- else
+ raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), false, exceptionMessage, dataPoint);
+ else {
dataPoint.setPointValue(valueTime, source);
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ }
}
}
@@ -389,7 +391,6 @@ else if (attributeId == OneWirePointLocatorVO.AttributeTypes.WIPER_POSITION) {
@Override
public void initialize() {
initializeNetwork();
- super.initialize();
}
@Override
@@ -419,6 +420,7 @@ private void initializeNetwork() {
terminateNetwork();
return;
}
+ super.initialize();
}
private void terminateNetwork() {
diff --git a/src/com/serotonin/mango/rt/dataSource/openv4j/OpenV4JDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/openv4j/OpenV4JDataSourceRT.java
index 5522392b74..eb2d7aa310 100644
--- a/src/com/serotonin/mango/rt/dataSource/openv4j/OpenV4JDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/openv4j/OpenV4JDataSourceRT.java
@@ -168,11 +168,11 @@ public synchronized void setPointValue(DataPointRT dataPoint, PointValueTime val
}
catch (InterruptedException ex) {
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), true,
- new LocalizableMessage("openv4j.interrupted"));
+ new LocalizableMessage("openv4j.interrupted"), dataPoint);
}
}
- returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis());
- returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
}
finally {
closePort();
diff --git a/src/com/serotonin/mango/rt/dataSource/pachube/PachubeDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/pachube/PachubeDataSourceRT.java
index 2bbb18ea17..1f80c33cb6 100644
--- a/src/com/serotonin/mango/rt/dataSource/pachube/PachubeDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/pachube/PachubeDataSourceRT.java
@@ -59,29 +59,42 @@
import com.serotonin.web.i18n.LocalizableException;
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.*;
import static com.serotonin.mango.Common.createGetMethod;
public class PachubeDataSourceRT extends PollingDataSource {
public static final int DATA_RETRIEVAL_FAILURE_EVENT = 1;
public static final int PARSE_EXCEPTION_EVENT = 2;
public static final int POINT_WRITE_EXCEPTION_EVENT = 3;
+ public static final int INITIALIZATION_EXCEPTION_EVENT = 4;
public static final String HEADER_API_KEY = "X-PachubeApiKey";
final Log log = LogFactory.getLog(PachubeDataSourceRT.class);
final PachubeDataSourceVO vo;
- private final HttpClient httpClient;
- final SimpleDateFormat sdf;
+ private HttpClient httpClient;
+ private SimpleDateFormat sdf;
public PachubeDataSourceRT(PachubeDataSourceVO vo) {
super(vo);
setPollingPeriod(vo.getUpdatePeriodType(), vo.getUpdatePeriods(), false);
this.vo = vo;
+ }
- httpClient = createHttpClient(vo.getTimeoutSeconds(), vo.getRetries());
-
- sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
- sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+ @Override
+ public void initialize() {
+ try {
+ httpClient = createHttpClient(vo.getTimeoutSeconds(), vo.getRetries());
+ sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
+ sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
+ returnToNormal(INITIALIZATION_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ raiseEvent(INITIALIZATION_EXCEPTION_EVENT, System.currentTimeMillis(), true,
+ new LocalizableMessage("event.exception2",
+ vo.getName(), e.getMessage()));
+ return;
+ }
+ super.initialize();
}
public static HttpClient createHttpClient(int timeoutSeconds, int retries) {
@@ -94,12 +107,12 @@ public static HttpClient createHttpClient(int timeoutSeconds, int retries) {
@Override
public void addDataPoint(DataPointRT dataPoint) {
super.addDataPoint(dataPoint);
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ setUnreliableDataPoint(dataPoint);
}
@Override
public void removeDataPoint(DataPointRT dataPoint) {
- returnToNormal(PARSE_EXCEPTION_EVENT, System.currentTimeMillis());
+ returnToNormal(PARSE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
super.removeDataPoint(dataPoint);
}
@@ -139,7 +152,7 @@ protected void pollFeed(int feedId, List points, long time) {
try {
data = getData(httpClient, feedId, vo.getApiKey());
}
- catch (Exception e) {
+ catch (Throwable e) {
LocalizableMessage lm;
if (e instanceof LocalizableException)
lm = ((LocalizableException) e).getLocalizableMessage();
@@ -147,10 +160,6 @@ protected void pollFeed(int feedId, List points, long time) {
lm = new LocalizableMessage("event.pachube.feed.retrievalError", feedId, e.getMessage());
raiseEvent(DATA_RETRIEVAL_FAILURE_EVENT, time, true, lm);
- // Mark points as unreliable.
- for (DataPointRT point : points)
- point.setAttribute(ATTR_UNRELIABLE_KEY, true);
-
return;
}
@@ -166,7 +175,6 @@ protected void pollFeed(int feedId, List points, long time) {
if (dataValue == null) {
parseErrorMessage = new LocalizableMessage("event.pachube.dataStreamNotFound",
locator.getDataStreamId(), feedId);
- dp.setAttribute(ATTR_UNRELIABLE_KEY, true);
}
else {
try {
@@ -187,24 +195,25 @@ protected void pollFeed(int feedId, List points, long time) {
// Save the new value if it is new
if (!ObjectUtils.isEqual(dp.getPointValue(), pvt))
dp.updatePointValue(new PointValueTime(value, valueTime));
- dp.setAttribute(ATTR_UNRELIABLE_KEY, false);
}
catch (LocalizableException e) {
if (parseErrorMessage == null)
parseErrorMessage = e.getLocalizableMessage();
- dp.setAttribute(ATTR_UNRELIABLE_KEY, true);
}
catch (ParseException e) {
if (parseErrorMessage == null)
parseErrorMessage = new LocalizableMessage("event.valueParse.timeParsePoint",
dataValue.getTimestamp(), dp.getVO().getName());
- dp.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ }
+ catch (Throwable e) {
+ if (parseErrorMessage == null)
+ parseErrorMessage = new LocalizableMessage("common.default", e.getMessage());
}
}
}
if (parseErrorMessage != null)
- raiseEvent(PARSE_EXCEPTION_EVENT, time, false, parseErrorMessage);
+ raiseEvent(PARSE_EXCEPTION_EVENT, time, true, parseErrorMessage);
else
returnToNormal(PARSE_EXCEPTION_EVENT, time);
}
@@ -276,12 +285,12 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPo
dataPoint.setPointValue(valueTime, source);
// Deactivate any existing event.
- returnToNormal(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime());
+ returnToNormal(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(), dataPoint);
}
catch (IOException e) {
// Raise an event.
raiseEvent(POINT_WRITE_EXCEPTION_EVENT, valueTime.getTime(), true, new LocalizableMessage(
- "event.exception2", dataPoint.getVO().getName(), e.getMessage()));
+ "event.exception2", dataPoint.getVO().getName(), e.getMessage()), dataPoint);
}
}
}
diff --git a/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java
index 3c3419c8d2..2346257612 100644
--- a/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/persistent/PersistentDataSourceRT.java
@@ -98,19 +98,19 @@ public long getPacketsReceived(int index) {
//
@Override
public void initialize() {
- super.initialize();
-
try {
serverSocket = new ServerSocket(vo.getPort());
serverSocket.setSoTimeout(2000);
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
}
- catch (IOException e) {
+ catch (Throwable e) {
serverSocket = null;
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"event.initializationError", e.getMessage()));
+ return;
}
+ super.initialize();
}
@Override
diff --git a/src/com/serotonin/mango/rt/dataSource/pop3/Pop3DataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/pop3/Pop3DataSourceRT.java
index 4950a9cb87..99d30e1292 100644
--- a/src/com/serotonin/mango/rt/dataSource/pop3/Pop3DataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/pop3/Pop3DataSourceRT.java
@@ -60,7 +60,7 @@ public Pop3DataSourceRT(Pop3DataSourceVO vo) {
@Override
public void removeDataPoint(DataPointRT dataPoint) {
- returnToNormal(PARSE_EXCEPTION_EVENT, System.currentTimeMillis());
+ returnToNormal(PARSE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
}
@Override
@@ -123,19 +123,21 @@ protected void doPoll(long time) {
returnToNormal(INBOX_EXCEPTION_EVENT, time);
if (messagesRead) {
- if (messageReadError != null)
- raiseEvent(MESSAGE_READ_EXCEPTION_EVENT, time, false, messageReadError);
- else
+ if (messageReadError != null) {
+ raiseEvent(MESSAGE_READ_EXCEPTION_EVENT, time, true, messageReadError);
+ return;
+ } else
returnToNormal(MESSAGE_READ_EXCEPTION_EVENT, time);
- if (parseError != null)
- raiseEvent(PARSE_EXCEPTION_EVENT, time, false, parseError);
- else
+ if (parseError != null) {
+ raiseEvent(PARSE_EXCEPTION_EVENT, time, true, parseError);
+ return;
+ } else
returnToNormal(PARSE_EXCEPTION_EVENT, time);
}
}
catch (Exception e) {
- raiseEvent(INBOX_EXCEPTION_EVENT, time, false, new LocalizableMessage("common.default", e.getMessage()));
+ raiseEvent(INBOX_EXCEPTION_EVENT, time, true, new LocalizableMessage("common.default", e.getMessage()));
}
finally {
try {
diff --git a/src/com/serotonin/mango/rt/dataSource/snmp/SnmpDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/snmp/SnmpDataSourceRT.java
index 1de498569a..2598033a8c 100644
--- a/src/com/serotonin/mango/rt/dataSource/snmp/SnmpDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/snmp/SnmpDataSourceRT.java
@@ -31,6 +31,8 @@
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.setUnreliableDataPoints;
+
/**
* @author Matthew Lohbihler
*
@@ -106,7 +108,7 @@ private void finishTime(){
private final Log log = LogFactory.getLog(SnmpDataSourceRT.class);
private final SnmpDataSourceVO vo;
- private final Version version;
+ private Version version;
private String address;
private Target target;
private Snmp snmp;
@@ -122,12 +124,6 @@ public SnmpDataSourceRT(SnmpDataSourceVO vo) {
super(vo);
setPollingPeriod(vo.getUpdatePeriodType(), vo.getUpdatePeriods(), false);
this.vo = vo;
- version = Version.getVersion(vo.getSnmpVersion(), vo.getCommunity(),
- vo.getSecurityName(), vo.getAuthProtocol(),
- vo.getAuthPassphrase(), vo.getPrivProtocol(),
- vo.getPrivPassphrase(), vo.getSecurityLevel(),
- vo.getContextName());
- snmpRequests = new SnmpResponses();
}
@Override
@@ -141,10 +137,12 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime,
PDU response = snmpRequests.getResponseBySet();
LocalizableMessage message = validatePdu(response);
- if (message != null)
- raiseEvent(PDU_EXCEPTION_EVENT, valueTime.getTime(), false, message);
- else
+ if (message != null) {
+ raiseEvent(PDU_EXCEPTION_EVENT, valueTime.getTime(), false, message, dataPoint);
+ } else {
dataPoint.setPointValue(valueTime, source);
+ returnToNormal(PDU_EXCEPTION_EVENT, valueTime.getTime(), dataPoint);
+ }
}
public void setDeviceDidNotRespondDespiteTheCounterOfRetries(boolean deviceDidNotRespondDespiteTheCounterOfRetries) {
this.deviceDidNotRespondDespiteTheCounterOfRetries = deviceDidNotRespondDespiteTheCounterOfRetries;
@@ -209,6 +207,7 @@ private void doPollImpl(long time) throws IOException {
}
} else {
if (!isSnmpConnectionIsAlive()) {
+ setUnreliableDataPoints(dataPoints);
// Common.ctx.getRuntimeManager().stopDataSourceAndDontJoinTermination(vo.getId());
} else if (message != null) {
raiseEvent(PDU_EXCEPTION_EVENT, time, true, message);
@@ -226,7 +225,6 @@ private void doPollImpl(long time) throws IOException {
}
} else {
raiseEvent(PDU_EXCEPTION_EVENT, time, true, validatePdu(response));
-
}
}
@@ -273,8 +271,9 @@ private boolean logEventsDependsOnMessageType(MessageType messageType, VariableB
break;
}
- if(messageType!=MessageType.undefined)
- raiseEvent(PDU_EXCEPTION_EVENT,time,true,message);
+ if(messageType!=MessageType.undefined) {
+ raiseEvent(PDU_EXCEPTION_EVENT, time, true, message);
+ }
return messageType!=MessageType.undefined;
}
@@ -334,9 +333,9 @@ void receivedTrap(PDU trap) {
// Take a look at the response.
LocalizableMessage message = validatePdu(trap);
- if (message != null)
- raiseEvent(PDU_EXCEPTION_EVENT, time, false, message);
- else {
+ if (message != null) {
+ raiseEvent(PDU_EXCEPTION_EVENT, time, true, message);
+ } else {
synchronized (pointListChangeLock) {
updateChangedPoints();
@@ -352,9 +351,12 @@ void receivedTrap(PDU trap) {
}
}
- if (!found)
- raiseEvent(TRAP_NOT_HANDLED_EVENT, time, false, new LocalizableMessage("event.snmp.trapNotHandled", vb));
+ if (!found) {
log.warn("Trap not handled: " + vb);
+ raiseEvent(TRAP_NOT_HANDLED_EVENT, time, true, new LocalizableMessage("event.snmp.trapNotHandled", vb));
+ } else {
+ returnToNormal(TRAP_NOT_HANDLED_EVENT, time);
+ }
}
}
}
@@ -364,6 +366,7 @@ private void updatePoint(DataPointRT dp, Variable variable, long time) {
SnmpPointLocatorRT locator = dp.getPointLocator();
dp.updatePointValue(new PointValueTime(locator
.variableToValue(variable), time));
+ returnToNormal(PDU_EXCEPTION_EVENT, time, dp);
}
//
@@ -374,6 +377,12 @@ private void updatePoint(DataPointRT dp, Variable variable, long time) {
@Override
public void initialize() {
try {
+ version = Version.getVersion(vo.getSnmpVersion(), vo.getCommunity(),
+ vo.getSecurityName(), vo.getAuthProtocol(),
+ vo.getAuthPassphrase(), vo.getPrivProtocol(),
+ vo.getPrivPassphrase(), vo.getSecurityLevel(),
+ vo.getContextName());
+ snmpRequests = new SnmpResponses();
initializeComponents();
counterEmptyResponsesOrResponsesWithError=0;
log.info("Counter Empty Responses Or Responses With Error is set 0.");
@@ -383,7 +392,7 @@ public void initialize() {
// Deactivate any existing event.
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT,
System.currentTimeMillis());
- } catch (Exception e) {
+ } catch (Throwable e) {
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(),
true, DataSourceRT.getExceptionMessage(e));
log.debug("Error while initializing data source", e);
diff --git a/src/com/serotonin/mango/rt/dataSource/sql/SqlDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/sql/SqlDataSourceRT.java
index dc9d7a1a62..0d1fa13fbe 100644
--- a/src/com/serotonin/mango/rt/dataSource/sql/SqlDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/sql/SqlDataSourceRT.java
@@ -101,15 +101,17 @@ else if (locatorVO.getDataTypeId() == DataTypes.IMAGE) {
int rows = jdbcOperations.update(locatorVO.getUpdateStatement(), value);
if (rows == 0) {
raiseEvent(STATEMENT_EXCEPTION_EVENT, valueTime.getTime(),
- false, new LocalizableMessage(
+ true, new LocalizableMessage(
"event.sql.noRowsUpdated", dataPoint.getVO()
- .getName()));
- } else
+ .getName()), dataPoint);
+ } else {
dataPoint.setPointValue(valueTime, source);
+ returnToNormal(STATEMENT_EXCEPTION_EVENT, valueTime.getTime());
+ }
} catch (Exception e) {
- raiseEvent(STATEMENT_EXCEPTION_EVENT, valueTime.getTime(), false,
+ raiseEvent(STATEMENT_EXCEPTION_EVENT, valueTime.getTime(), true,
new LocalizableMessage("event.sql.setError", dataPoint
- .getVO().getName(), getExceptionMessage(e)));
+ .getVO().getName(), getExceptionMessage(e)), dataPoint);
}
}
@@ -194,8 +196,10 @@ private void updateByColumn(long time, ResultSet rs) throws SQLException {
raiseEvent(STATEMENT_EXCEPTION_EVENT, time, true,
new LocalizableMessage(
"event.sql.timeNotFound",
- timeOverride));
+ timeOverride), dp);
continue;
+ } else {
+ returnToNormal(STATEMENT_EXCEPTION_EVENT, time, dp);
}
pointTime = getTimeOverride(meta, column, rs, time);
@@ -258,6 +262,8 @@ private void updateByRowId(long time, ResultSet rs) throws SQLException {
if (!found)
raiseEvent(STATEMENT_EXCEPTION_EVENT, time, true,
new LocalizableMessage("event.sql.noDataPoint", rowId));
+ else
+ returnToNormal(STATEMENT_EXCEPTION_EVENT, time);
}
}
diff --git a/src/com/serotonin/mango/rt/dataSource/viconics/ViconicsDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/viconics/ViconicsDataSourceRT.java
index bcd6e9b2e1..00871415e4 100644
--- a/src/com/serotonin/mango/rt/dataSource/viconics/ViconicsDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/viconics/ViconicsDataSourceRT.java
@@ -75,6 +75,8 @@
import com.serotonin.viconics.io.ViconicsOutgoingRequest;
import com.serotonin.web.i18n.LocalizableMessage;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.*;
+
/**
* @author Matthew Lohbihler
*/
@@ -108,7 +110,7 @@ public ViconicsDataSourceRT(ViconicsDataSourceVO vo) {
public void initialize() {
try {
network = new ViconicsNetwork(vo.getCommPortId(), Common.timer);
- } catch (ViconicsConfigurationException e) {
+ } catch (Throwable e) {
raiseEvent(INITIALIZATION_EXCEPTION_EVENT,
System.currentTimeMillis(), true, new LocalizableMessage(
"event.initializationError", e.getMessage()));
@@ -127,7 +129,7 @@ public void initialize() {
try {
network.init();
network.startNetwork(vo.getPanId(), vo.getChannel());
- } catch (Exception e) {
+ } catch (Throwable e) {
raiseEvent(INITIALIZATION_EXCEPTION_EVENT,
System.currentTimeMillis(), true, new LocalizableMessage(
"event.initializationError", e.getMessage()));
@@ -147,7 +149,7 @@ public void addDataPoint(DataPointRT dataPoint) {
super.addDataPoint(dataPoint);
// Mark the point as unreliable.
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ setUnreliableDataPoint(dataPoint);
// Add the point to the lookup map.
pointLookup.put(new PointKey(dataPoint), dataPoint);
@@ -176,12 +178,6 @@ public void terminate() {
// / ViconicsNetworkListener
//
public void viconicsNetworkStatus(boolean online) {
- // Mark all points as unreliable.
- synchronized (dataPoints) {
- for (DataPointRT rt : dataPoints)
- rt.setAttribute(ATTR_UNRELIABLE_KEY, true);
- }
-
if (online)
returnToNormal(NETWORK_OFFLINE_EVENT, System.currentTimeMillis());
else
@@ -386,17 +382,6 @@ public void viconicsDeviceStatus(ViconicsDevice device, boolean online) {
if (online)
returnToNormal(DEVICE_OFFLINE_EVENT, System.currentTimeMillis());
else {
- // Mark all points for the device as unreliable.
- synchronized (dataPoints) {
- for (DataPointRT rt : dataPoints) {
- ViconicsPointLocatorVO locator = rt.getVO()
- .getPointLocator();
- if (Arrays
- .equals(locator.getDeviceIeee(), device.getIeee()))
- rt.setAttribute(ATTR_UNRELIABLE_KEY, true);
- }
- }
-
raiseEvent(DEVICE_OFFLINE_EVENT, System.currentTimeMillis(), true,
new LocalizableMessage("event.viconics.deviceOffline",
device.getIeeeString()));
@@ -427,7 +412,7 @@ public void viconicsReceivedException(Exception e) {
raiseEvent(
MESSAGE_EXCEPTION_EVENT,
System.currentTimeMillis(),
- false,
+ true,
new LocalizableMessage("event.viconics.messagingException", e
.getMessage()));
}
@@ -472,14 +457,13 @@ public void viconicsDevicePointUpdated(ViconicsDevice device,
throw new ShouldNeverHappenException("Unknown point type: "
+ point.getClass());
- rt.setAttribute(ATTR_UNRELIABLE_KEY, false);
-
rt.updatePointValue(new PointValueTime(mangoValue, time));
+ resetUnreliableDataPoint(rt);
}
public void viconicsDuplicateCommAddressDetected(int commAddress) {
raiseEvent(DUPLICATE_COMM_ADDRESS_EVENT, System.currentTimeMillis(),
- false, new LocalizableMessage(
+ true, new LocalizableMessage(
"event.viconics.messagingException", commAddress));
}
@@ -509,13 +493,14 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime pvt,
network.writeValue(locator.getDeviceIeee(),
locator.getPointAddress(), value);
dataPoint.setPointValue(pvt, source);
- } catch (Exception e) {
+ returnToNormal(MESSAGE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
raiseEvent(
MESSAGE_EXCEPTION_EVENT,
System.currentTimeMillis(),
- false,
+ true,
new LocalizableMessage("event.setPointFailed", e
- .getMessage()));
+ .getMessage()), dataPoint);
}
}
@@ -527,13 +512,14 @@ public void forcePointRead(DataPointRT dataPoint) {
// Ignore the result. It will be sent via the listener anyway.
network.readValue(locator.getDeviceIeee(),
locator.getPointAddress());
- } catch (Exception e) {
+ returnToNormal(MESSAGE_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
raiseEvent(
MESSAGE_EXCEPTION_EVENT,
System.currentTimeMillis(),
- false,
+ true,
new LocalizableMessage("event.readPointFailed", e
- .getMessage()));
+ .getMessage()), dataPoint);
}
}
diff --git a/src/com/serotonin/mango/rt/dataSource/vmstat/VMStatDataSourceRT.java b/src/com/serotonin/mango/rt/dataSource/vmstat/VMStatDataSourceRT.java
index e2cfd42874..9ff2fc32c1 100644
--- a/src/com/serotonin/mango/rt/dataSource/vmstat/VMStatDataSourceRT.java
+++ b/src/com/serotonin/mango/rt/dataSource/vmstat/VMStatDataSourceRT.java
@@ -60,7 +60,6 @@ public VMStatDataSourceRT(VMStatDataSourceVO vo) {
//
@Override
public void initialize() {
- super.initialize();
String command = "vmstat -n ";
switch (vo.getOutputScale()) {
@@ -140,10 +139,12 @@ else if ("st".equals(headerParts[i]))
returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
}
- catch (IOException e) {
+ catch (Throwable e) {
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(), true, new LocalizableMessage(
"event.initializationError", e.getMessage()));
+ return;
}
+ super.initialize();
}
@Override
diff --git a/src/com/serotonin/mango/rt/event/type/DataSourceEventType.java b/src/com/serotonin/mango/rt/event/type/DataSourceEventType.java
index 8bab31d912..ba912b8a2a 100644
--- a/src/com/serotonin/mango/rt/event/type/DataSourceEventType.java
+++ b/src/com/serotonin/mango/rt/event/type/DataSourceEventType.java
@@ -19,6 +19,7 @@
package com.serotonin.mango.rt.event.type;
import java.util.Map;
+import java.util.Objects;
import com.serotonin.json.JsonException;
import com.serotonin.json.JsonObject;
@@ -93,28 +94,16 @@ public int getReferenceId2() {
}
@Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + dataSourceEventTypeId;
- result = prime * result + dataSourceId;
- return result;
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof DataSourceEventType)) return false;
+ DataSourceEventType that = (DataSourceEventType) o;
+ return getDataSourceId() == that.getDataSourceId() && getDataSourceEventTypeId() == that.getDataSourceEventTypeId() && getAlarmLevel() == that.getAlarmLevel() && getDuplicateHandling() == that.getDuplicateHandling();
}
@Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- DataSourceEventType other = (DataSourceEventType) obj;
- if (dataSourceEventTypeId != other.dataSourceEventTypeId)
- return false;
- if (dataSourceId != other.dataSourceId)
- return false;
- return true;
+ public int hashCode() {
+ return Objects.hash(getDataSourceId(), getDataSourceEventTypeId(), getAlarmLevel(), getDuplicateHandling());
}
//
diff --git a/src/com/serotonin/mango/rt/event/type/DataSourcePointEventType.java b/src/com/serotonin/mango/rt/event/type/DataSourcePointEventType.java
new file mode 100644
index 0000000000..f0a04b54b9
--- /dev/null
+++ b/src/com/serotonin/mango/rt/event/type/DataSourcePointEventType.java
@@ -0,0 +1,144 @@
+/*
+ Mango - Open Source M2M - http://mango.serotoninsoftware.com
+ Copyright (C) 2006-2011 Serotonin Software Technologies Inc.
+ @author Matthew Lohbihler
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+ */
+package com.serotonin.mango.rt.event.type;
+
+import com.serotonin.json.JsonException;
+import com.serotonin.json.JsonObject;
+import com.serotonin.json.JsonReader;
+import com.serotonin.json.JsonRemoteEntity;
+import com.serotonin.mango.vo.DataPointVO;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.scada_lts.mango.service.DataPointService;
+
+import java.util.Map;
+import java.util.Objects;
+
+@JsonRemoteEntity
+public class DataSourcePointEventType extends DataSourceEventType {
+
+ private DataSourceEventType dataSourceEventType;
+ private int dataPointId;
+ private final int duplicateHandling = DuplicateHandling.IGNORE_SAME_MESSAGE;
+
+ private final Log LOG = LogFactory.getLog(DataSourcePointEventType.class);
+
+ public DataSourcePointEventType() {
+ // Required for reflection.
+ }
+
+ public DataSourcePointEventType(DataSourceEventType dataSourceEventType, int dataPointId) {
+ this.dataSourceEventType = dataSourceEventType;
+ this.dataPointId = dataPointId;
+ }
+
+ @Override
+ public int getEventSourceId() {
+ return EventSources.DATA_SOURCE_POINT;
+ }
+
+ @Override
+ public int getDataSourceEventTypeId() {
+ return dataSourceEventType.getDataSourceEventTypeId();
+ }
+
+ @Override
+ public int getAlarmLevel() {
+ return dataSourceEventType.getAlarmLevel();
+ }
+
+ @Override
+ public int getDataSourceId() {
+ return dataSourceEventType.getDataSourceId();
+ }
+
+ @Override
+ public int getDataPointId() {
+ return dataPointId;
+ }
+
+ @Override
+ public String toString() {
+ return "DataSoureEventType(dataSourceId=" + dataSourceEventType.getDataSourceId() + ", dataPointId=" + dataPointId + ", eventTypeId=" + dataSourceEventType.getDataSourceEventTypeId() + ")";
+ }
+
+ @Override
+ public int getDuplicateHandling() {
+ return duplicateHandling;
+ }
+
+ @Override
+ public int getReferenceId1() {
+ return dataSourceEventType.getDataSourceId();
+ }
+
+ @Override
+ public int getReferenceId2() {
+ return dataSourceEventType.getDataSourceEventTypeId();
+ }
+
+ @Override
+ public int getReferenceId3() {
+ return dataPointId;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ DataSourcePointEventType that = (DataSourcePointEventType) o;
+ return dataPointId == that.dataPointId && Objects.equals(dataSourceEventType, that.dataSourceEventType);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(dataSourceEventType, dataPointId);
+ }
+
+ //
+ // /
+ // / Serialization
+ // /
+ //
+ @Override
+ public void jsonSerialize(Map map) {
+ super.jsonSerialize(map);
+ dataSourceEventType.jsonSerialize(map);
+ DataPointService dataPointService = new DataPointService();
+ DataPointVO dataPoint = dataPointService.getDataPoint(dataPointId);
+ if(dataPoint != null) {
+ map.put("DATA_POINT_XID", dataPoint.getXid());
+ } else {
+ LOG.error("DataPoint for id: " + dataPointId + " does not exist.");
+ }
+ }
+
+ @Override
+ public void jsonDeserialize(JsonReader reader, JsonObject json) throws JsonException {
+ super.jsonDeserialize(reader, json);
+ DataSourceEventType dataSourceEventType = new DataSourceEventType();
+ dataSourceEventType.jsonDeserialize(reader, json);
+ this.dataSourceEventType = dataSourceEventType;
+
+ DataPointVO dataPoint = getDataPoint(json, "DATA_POINT_XID");
+ if(dataPoint != null) {
+ dataPointId = dataPoint.getId();
+ }
+ }
+}
diff --git a/src/com/serotonin/mango/rt/event/type/EventType.java b/src/com/serotonin/mango/rt/event/type/EventType.java
index b1b627636a..e35e0745a0 100644
--- a/src/com/serotonin/mango/rt/event/type/EventType.java
+++ b/src/com/serotonin/mango/rt/event/type/EventType.java
@@ -27,7 +27,6 @@
import com.serotonin.json.JsonSerializable;
import com.serotonin.mango.db.dao.CompoundEventDetectorDao;
import com.serotonin.mango.db.dao.DataPointDao;
-import com.serotonin.mango.db.dao.DataSourceDao;
import com.serotonin.mango.db.dao.MaintenanceEventDao;
import com.serotonin.mango.db.dao.PublisherDao;
import com.serotonin.mango.db.dao.ScheduledEventDao;
@@ -40,6 +39,8 @@
import com.serotonin.mango.vo.event.MaintenanceEventVO;
import com.serotonin.mango.vo.event.ScheduledEventVO;
import com.serotonin.mango.vo.publish.PublisherVO;
+import org.scada_lts.mango.service.DataPointService;
+import org.scada_lts.mango.service.DataSourceService;
/**
* An event class specifies the type of event that was raised.
@@ -102,6 +103,8 @@ public interface EventSources {
* Maintenance events are created when maintenance mode becomes active. See MaintenanceVO for more information.
*/
int MAINTENANCE = 9;
+
+ int DATA_SOURCE_POINT = 10;
}
public static final ExportCodes SOURCE_CODES = new ExportCodes();
@@ -114,6 +117,7 @@ public interface EventSources {
SOURCE_CODES.addElement(EventSources.PUBLISHER, "PUBLISHER");
SOURCE_CODES.addElement(EventSources.AUDIT, "AUDIT");
SOURCE_CODES.addElement(EventSources.MAINTENANCE, "MAINTENANCE");
+ SOURCE_CODES.addElement(EventSources.DATA_SOURCE_POINT, "DATA_SOURCE_POINT");
}
/**
@@ -225,6 +229,10 @@ public int getSystemEventTypeId() {
abstract public int getReferenceId2();
+ public int getReferenceId3() {
+ return -1;
+ }
+
/**
* Determines if the notification of this event to the given user should be suppressed. Useful if the action of the
* user resulted in the event being raised.
@@ -276,9 +284,7 @@ protected int getInt(JsonObject json, String name, ExportCodes codes) throws Jso
// }
//
protected int getCompoundEventDetectorId(JsonObject json, String name) throws JsonException {
- String xid = json.getString(name);
- if (xid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
+ String xid = getXid(json, name);
CompoundEventDetectorVO ced = new CompoundEventDetectorDao().getCompoundEventDetector(xid);
if (ced == null)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
@@ -296,9 +302,7 @@ protected int getCompoundEventDetectorId(JsonObject json, String name) throws Js
// }
//
protected int getScheduledEventId(JsonObject json, String name) throws JsonException {
- String xid = json.getString(name);
- if (xid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
+ String xid = getXid(json, name);
ScheduledEventVO se = new ScheduledEventDao().getScheduledEvent(xid);
if (se == null)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
@@ -306,9 +310,7 @@ protected int getScheduledEventId(JsonObject json, String name) throws JsonExcep
}
protected int getDataPointId(JsonObject json, String name) throws JsonException {
- String xid = json.getString(name);
- if (xid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
+ String xid = getXid(json, name);
DataPointVO dp = new DataPointDao().getDataPoint(xid);
if (dp == null)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
@@ -330,9 +332,7 @@ protected int getPointEventDetectorId(JsonObject json, String dpName, String ped
}
protected int getPointEventDetectorId(JsonObject json, int dpId, String pedName) throws JsonException {
- String pedXid = json.getString(pedName);
- if (pedXid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", pedName);
+ String pedXid = getXid(json, pedName);
int id = new DataPointDao().getDetectorId(pedXid, dpId);
if (id == -1)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", pedName, pedXid);
@@ -341,19 +341,25 @@ protected int getPointEventDetectorId(JsonObject json, int dpId, String pedName)
}
protected DataSourceVO> getDataSource(JsonObject json, String name) throws JsonException {
- String xid = json.getString(name);
- if (xid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
- DataSourceVO> ds = new DataSourceDao().getDataSource(xid);
+ String xid = getXid(json, name);
+ DataSourceService dataSourceService = new DataSourceService();
+ DataSourceVO> ds = dataSourceService.getDataSource(xid);
if (ds == null)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
return ds;
}
+ protected DataPointVO getDataPoint(JsonObject json, String name) throws JsonException {
+ String xid = getXid(json, name);
+ DataPointService dataPointService = new DataPointService();
+ DataPointVO dataPoint = dataPointService.getDataPoint(xid);
+ if (dataPoint == null)
+ throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
+ return dataPoint;
+ }
+
protected PublisherVO> getPublisher(JsonObject json, String name) throws JsonException {
- String xid = json.getString(name);
- if (xid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
+ String xid = getXid(json, name);
PublisherVO> pb = new PublisherDao().getPublisher(xid);
if (pb == null)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
@@ -361,12 +367,17 @@ protected PublisherVO> getPublisher(JsonObject json, String name) throws JsonE
}
protected int getMaintenanceEventId(JsonObject json, String name) throws JsonException {
- String xid = json.getString(name);
- if (xid == null)
- throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
+ String xid = getXid(json, name);
MaintenanceEventVO me = new MaintenanceEventDao().getMaintenanceEvent(xid);
if (me == null)
throw new LocalizableJsonException("emport.error.eventType.invalid.reference", name, xid);
return me.getId();
}
+
+ private static String getXid(JsonObject json, String name) throws LocalizableJsonException {
+ String xid = json.getString(name);
+ if (xid == null)
+ throw new LocalizableJsonException("emport.error.eventType.missing.reference", name);
+ return xid;
+ }
}
diff --git a/src/com/serotonin/mango/util/LoggingUtils.java b/src/com/serotonin/mango/util/LoggingUtils.java
index fade8dfc1b..9d2052ea0d 100644
--- a/src/com/serotonin/mango/util/LoggingUtils.java
+++ b/src/com/serotonin/mango/util/LoggingUtils.java
@@ -1,7 +1,9 @@
package com.serotonin.mango.util;
import br.org.scadabr.vo.scripting.ScriptVO;
+import com.serotonin.db.IntValuePair;
import com.serotonin.mango.Common;
+import com.serotonin.mango.rt.dataImage.DataPointRT;
import com.serotonin.mango.rt.dataImage.PointValueTime;
import com.serotonin.mango.rt.dataImage.SetPointSource;
import com.serotonin.mango.rt.dataSource.DataSourceRT;
@@ -68,7 +70,7 @@ public static String scriptInfo(ScriptVO> script) {
return MessageFormat.format(info, script.getName(), String.valueOf(script.getId()), script.getXid());
}
- public static String exceptionInfo(Exception ex) {
+ public static String exceptionInfo(Throwable ex) {
if(ex == null)
return "";
String info = "exception: {0} (msg: {1})";
@@ -135,12 +137,12 @@ public static String dataSourcePointValueTimeInfo(DataSourceVO> dataSource, Da
return LoggingUtils.dataSourceInfo(dataSource) + ", " + LoggingUtils.dataPointInfo(dataPoint) + ", " + LoggingUtils.pointValueTimeInfo(valueTime, source);
}
- public static String causeInfo(Exception e) {
+ public static String causeInfo(Throwable e) {
return exceptionInfo(getCause(e));
}
- public static Exception getCause(Exception e) {
- return e.getCause() != null ? (Exception) e.getCause() : e;
+ public static Throwable getCause(Throwable e) {
+ return e.getCause() != null ? e.getCause() : e;
}
public static String userInfo(User user) {
@@ -211,6 +213,30 @@ public static String entryInfo(PointValueService.BatchWriteBehindEntry entry) {
return MessageFormat.format(info, entry.getPointId(), entry.getDataType(), entry.getTime(), entry.getDvalue());
}
+ public static String info(Throwable e, DataSourceRT dataSourceRT) {
+ return exceptionInfo(e) + " - " + dataSourceInfo(dataSourceRT);
+ }
+
+ public static String info(Throwable e, DataSourceRT dataSourceRT, DataPointRT dataPointRT) {
+ return exceptionInfo(e) + " - " + dataSourceInfo(dataSourceRT) + " - " + dataPointInfo(dataPointRT);
+ }
+
+ public static String dataPointInfo(DataPointRT dataPointRT) {
+ if(dataPointRT == null)
+ return "";
+ DataPointVO dataPointVO = dataPointRT.getVO();
+ if(dataPointVO == null)
+ return dataPointRtInfo(dataPointRT);
+ return dataPointInfo(dataPointVO);
+ }
+
+ public static String dataPointRtInfo(DataPointRT dataPoint) {
+ if(dataPoint == null)
+ return "";
+ String info = "datapointrt: {0} (id: {0}, xid: {1}, dataSourceId: {2})";
+ return MessageFormat.format(info, String.valueOf(dataPoint.getId()), dataPoint.getDataSourceId());
+ }
+
public static String publisherInfo(PublisherVO> publisher) {
if(publisher == null)
return "";
@@ -218,6 +244,13 @@ public static String publisherInfo(PublisherVO> publisher) {
return MessageFormat.format(info, publisher.getName(), publisher.getId(), publisher.getXid(), publisher.getType());
}
+ public static String varInfo(IntValuePair pair) {
+ if(pair == null)
+ return "";
+ String info = "{0} (key: {1})";
+ return MessageFormat.format(info, pair.getValue(), pair.getKey());
+ }
+
private static String msg(EventHandlerVO eventHandler) {
return StringUtils.isEmpty(eventHandler.getAlias()) && eventHandler.getMessage() != null ? eventHandler.getMessage().getLocalizedMessage(Common.getBundle()) : eventHandler.getAlias();
}
diff --git a/src/com/serotonin/mango/vo/DataPointVO.java b/src/com/serotonin/mango/vo/DataPointVO.java
index 5aa6edef5f..47341e2e44 100644
--- a/src/com/serotonin/mango/vo/DataPointVO.java
+++ b/src/com/serotonin/mango/vo/DataPointVO.java
@@ -709,7 +709,7 @@ public void validate(DwrResponseI18n response) {
if (purgeValuesLimit <= 1)
response.addContextualMessage("purgeValuesLimit", "validate.greaterThanOne");
- pointLocator.validate(response);
+ pointLocator.validate(response, this.getId());
// Check text renderer type
if (textRenderer != null && !textRenderer.getDef().supports(pointLocator.getDataTypeId()))
diff --git a/src/com/serotonin/mango/vo/dataSource/PointLocatorVO.java b/src/com/serotonin/mango/vo/dataSource/PointLocatorVO.java
index 171f88f0b1..4edafc11a3 100644
--- a/src/com/serotonin/mango/vo/dataSource/PointLocatorVO.java
+++ b/src/com/serotonin/mango/vo/dataSource/PointLocatorVO.java
@@ -61,5 +61,9 @@ public interface PointLocatorVO extends Serializable, ChangeComparableObject {
*/
public void validate(DwrResponseI18n response);
+ default void validate(DwrResponseI18n response, int dataPointId) {
+ validate(response);
+ }
+
public DataPointSaveHandler getDataPointSaveHandler();
}
diff --git a/src/com/serotonin/mango/vo/dataSource/http/HttpReceiverDataSourceVO.java b/src/com/serotonin/mango/vo/dataSource/http/HttpReceiverDataSourceVO.java
index 985db8511b..bfa47fd9bb 100644
--- a/src/com/serotonin/mango/vo/dataSource/http/HttpReceiverDataSourceVO.java
+++ b/src/com/serotonin/mango/vo/dataSource/http/HttpReceiverDataSourceVO.java
@@ -47,12 +47,18 @@ public class HttpReceiverDataSourceVO extends DataSourceVO ets) {
- // no op
+ ets.add(createEventType(HttpReceiverDataSourceRT.INITIALIZATION_EXCEPTION_EVENT, new LocalizableMessage(
+ "event.ds.initialization")));
}
@Override
public ExportCodes getEventCodes() {
- return null;
+ return EVENT_CODES;
+ }
+
+ private static final ExportCodes EVENT_CODES = new ExportCodes();
+ static {
+ EVENT_CODES.addElement(HttpReceiverDataSourceRT.INITIALIZATION_EXCEPTION_EVENT, "INITIALIZATION_EXCEPTION");
}
@Override
diff --git a/src/com/serotonin/mango/vo/dataSource/meta/MetaPointLocatorVO.java b/src/com/serotonin/mango/vo/dataSource/meta/MetaPointLocatorVO.java
index ddcbb0f948..3c48b01a59 100644
--- a/src/com/serotonin/mango/vo/dataSource/meta/MetaPointLocatorVO.java
+++ b/src/com/serotonin/mango/vo/dataSource/meta/MetaPointLocatorVO.java
@@ -174,13 +174,26 @@ public void setUpdateCronPattern(String updateCronPattern) {
this.updateCronPattern = updateCronPattern;
}
+ @Override
public void validate(DwrResponseI18n response) {
+ validate(response, Common.NEW_ID);
+ }
+
+ @Override
+ public void validate(DwrResponseI18n response, int dataPointId) {
if (StringUtils.isEmpty(script))
response.addContextualMessage("script", "validate.required");
List varNameSpace = new ArrayList();
for (IntValuePair point : context) {
String varName = point.getValue();
+ int pointId = point.getKey();
+
+ if(pointId != Common.NEW_ID && pointId == dataPointId) {
+ response.addContextualMessage("context", "validate.invalidVariable", varName);
+ break;
+ }
+
if (StringUtils.isEmpty(varName)) {
response.addContextualMessage("context", "validate.allVarNames");
break;
diff --git a/src/com/serotonin/mango/vo/dataSource/modbus/ModbusDataSourceVO.java b/src/com/serotonin/mango/vo/dataSource/modbus/ModbusDataSourceVO.java
index 6f7092c2b0..5189a3338a 100644
--- a/src/com/serotonin/mango/vo/dataSource/modbus/ModbusDataSourceVO.java
+++ b/src/com/serotonin/mango/vo/dataSource/modbus/ModbusDataSourceVO.java
@@ -52,6 +52,10 @@ protected void addEventTypes(List ets) {
new LocalizableMessage("event.ds.pointRead")));
ets.add(createEventType(ModbusDataSource.POINT_WRITE_EXCEPTION_EVENT,
new LocalizableMessage("event.ds.pointWrite")));
+ ets.add(createEventType(ModbusDataSource.MONITOR_WRITE_EXCEPTION_EVENT,
+ new LocalizableMessage("event.ds.monitorWrite")));
+ ets.add(createEventType(ModbusDataSource.INITIALIZATION_EXCEPTION_EVENT,
+ new LocalizableMessage("event.ds.initialization")));
}
private static final ExportCodes EVENT_CODES = new ExportCodes();
@@ -62,6 +66,10 @@ protected void addEventTypes(List ets) {
"POINT_READ_EXCEPTION");
EVENT_CODES.addElement(ModbusDataSource.POINT_WRITE_EXCEPTION_EVENT,
"POINT_WRITE_EXCEPTION");
+ EVENT_CODES.addElement(ModbusDataSource.MONITOR_WRITE_EXCEPTION_EVENT,
+ "MONITOR_WRITE_EXCEPTION");
+ EVENT_CODES.addElement(ModbusDataSource.INITIALIZATION_EXCEPTION_EVENT,
+ "INITIALIZATION_EXCEPTION");
}
@Override
diff --git a/src/com/serotonin/mango/vo/dataSource/pachube/PachubeDataSourceVO.java b/src/com/serotonin/mango/vo/dataSource/pachube/PachubeDataSourceVO.java
index 3761b1f421..c8a7eb34ef 100644
--- a/src/com/serotonin/mango/vo/dataSource/pachube/PachubeDataSourceVO.java
+++ b/src/com/serotonin/mango/vo/dataSource/pachube/PachubeDataSourceVO.java
@@ -54,6 +54,9 @@ protected void addEventTypes(List ets) {
"event.ds.dataParse")));
ets.add(createEventType(PachubeDataSourceRT.POINT_WRITE_EXCEPTION_EVENT, new LocalizableMessage(
"event.ds.pointWrite")));
+ ets.add(createEventType(PachubeDataSourceRT.INITIALIZATION_EXCEPTION_EVENT, new LocalizableMessage(
+ "event.ds.initialization"
+ )));
}
private static final ExportCodes EVENT_CODES = new ExportCodes();
@@ -61,6 +64,7 @@ protected void addEventTypes(List ets) {
EVENT_CODES.addElement(PachubeDataSourceRT.DATA_RETRIEVAL_FAILURE_EVENT, "DATA_RETRIEVAL_FAILURE");
EVENT_CODES.addElement(PachubeDataSourceRT.PARSE_EXCEPTION_EVENT, "PARSE_EXCEPTION");
EVENT_CODES.addElement(PachubeDataSourceRT.POINT_WRITE_EXCEPTION_EVENT, "POINT_WRITE_EXCEPTION");
+ EVENT_CODES.addElement(PachubeDataSourceRT.INITIALIZATION_EXCEPTION_EVENT, "INITIALIZATION_EXCEPTION");
}
@Override
diff --git a/src/com/serotonin/mango/vo/event/EventTypeVO.java b/src/com/serotonin/mango/vo/event/EventTypeVO.java
index b2db0e3410..e21cc5c95d 100644
--- a/src/com/serotonin/mango/vo/event/EventTypeVO.java
+++ b/src/com/serotonin/mango/vo/event/EventTypeVO.java
@@ -29,6 +29,7 @@
import com.serotonin.mango.rt.event.type.PublisherEventType;
import com.serotonin.mango.rt.event.type.ScheduledEventType;
import com.serotonin.mango.rt.event.type.SystemEventType;
+import com.serotonin.mango.rt.event.type.DataSourcePointEventType;
import com.serotonin.web.i18n.LocalizableMessage;
public class EventTypeVO {
@@ -45,6 +46,11 @@ public class EventTypeVO {
* event, undefined
*/
private int typeRef2;
+
+ /**
+ * For data source and data point event, undefined
+ */
+ private int typeRef3;
private LocalizableMessage description;
private List handlers;
private int alarmLevel;
@@ -52,20 +58,25 @@ public class EventTypeVO {
private int duplicateHandling;
public EventTypeVO(int typeId, int typeRef1, int typeRef2) {
+ this(typeId, typeRef1, typeRef2, -1);
+ }
+
+ public EventTypeVO(int typeId, int typeRef1, int typeRef2, int typeRef3) {
this.typeId = typeId;
this.typeRef1 = typeRef1;
this.typeRef2 = typeRef2;
+ this.typeRef3 = typeRef3;
}
public EventTypeVO(int typeId, int typeRef1, int typeRef2, LocalizableMessage description, int alarmLevel) {
- this(typeId, typeRef1, typeRef2);
+ this(typeId, typeRef1, typeRef2, -1);
this.description = description;
this.alarmLevel = alarmLevel;
}
public EventTypeVO(int typeId, int typeRef1, int typeRef2, LocalizableMessage description, int alarmLevel,
int duplicateHandling) {
- this(typeId, typeRef1, typeRef2);
+ this(typeId, typeRef1, typeRef2, -1);
this.description = description;
this.alarmLevel = alarmLevel;
this.duplicateHandling = duplicateHandling;
@@ -94,6 +105,8 @@ public EventType createEventType() {
return new AuditEventType(typeRef1, typeRef2);
if (typeId == EventType.EventSources.MAINTENANCE)
return new MaintenanceEventType(typeRef1);
+ if(typeId == EventType.EventSources.DATA_SOURCE_POINT)
+ return new DataSourcePointEventType(new DataSourceEventType(typeRef1, typeRef2, alarmLevel, duplicateHandling), typeRef3);
return null;
}
@@ -121,6 +134,14 @@ public void setTypeRef2(int typeRef2) {
this.typeRef2 = typeRef2;
}
+ public int getTypeRef3() {
+ return typeRef3;
+ }
+
+ public void setTypeRef3(int typeRef3) {
+ this.typeRef3 = typeRef3;
+ }
+
public LocalizableMessage getDescription() {
return description;
}
diff --git a/src/com/serotonin/mango/vo/permission/Permissions.java b/src/com/serotonin/mango/vo/permission/Permissions.java
index 17369ba9a0..d5ed81e4f4 100644
--- a/src/com/serotonin/mango/vo/permission/Permissions.java
+++ b/src/com/serotonin/mango/vo/permission/Permissions.java
@@ -287,6 +287,8 @@ public static boolean hasEventTypePermission(User user, EventType eventType) {
return hasDataPointReadPermission(user, eventType.getDataSourceId(), eventType.getDataPointId());
case EventType.EventSources.DATA_SOURCE:
return hasDataSourcePermission(user, eventType.getDataSourceId());
+ case EventType.EventSources.DATA_SOURCE_POINT:
+ return hasDataSourcePermission(user, eventType.getDataSourceId()) || hasDataPointReadPermission(user, eventType.getDataSourceId(), eventType.getDataPointId());
case EventType.EventSources.SYSTEM:
case EventType.EventSources.COMPOUND:
case EventType.EventSources.SCHEDULED:
diff --git a/src/com/serotonin/mango/web/dwr/DataSourceEditDwr.java b/src/com/serotonin/mango/web/dwr/DataSourceEditDwr.java
index fe3f72d89b..a15f525fe8 100644
--- a/src/com/serotonin/mango/web/dwr/DataSourceEditDwr.java
+++ b/src/com/serotonin/mango/web/dwr/DataSourceEditDwr.java
@@ -44,6 +44,7 @@
import javax.script.ScriptException;
import com.serotonin.db.KeyValuePair;
+import com.serotonin.mango.util.LoggingUtils;
import com.serotonin.mango.web.dwr.beans.*;
import com.serotonin.modbus4j.SlaveIdLimit255ModbusMaster;
import net.sf.mbus4j.Connection;
@@ -343,7 +344,7 @@ private DwrResponseI18n validatePoint(int id, String xid, String name,
if (StringUtils.isEmpty(name))
response.addContextualMessage("name", "dsEdit.validate.required");
- locator.validate(response);
+ locator.validate(response, dp.getId());
if (!response.getHasMessages()) {
Common.ctx.getRuntimeManager().saveDataPoint(dp);
@@ -1187,8 +1188,8 @@ public DwrResponseI18n validateScript(String script,
response.addMessage("script", e.getLocalizableMessage());
LOG.warn(infoErrorExecutionScript(e, "validateScript: " + script));
} catch (Exception e) {
+ response.addMessage("script", new LocalizableMessage("common.default", e.getMessage()));
LOG.warn(infoErrorExecutionScript(e, "validateScript: " + script));
- throw e;
}
return response;
@@ -2326,7 +2327,7 @@ private DwrResponseI18n validateMultipleDnp3Points(String[] names,
DataPointService dataPointService = new DataPointService();
validateXid(response, dataPointService::isXidUnique, dp.getXid(), Common.NEW_ID);
- locators[i].validate(response);
+ locators[i].validate(response, dp.getId());
if (!response.getHasMessages()) {
Common.ctx.getRuntimeManager().saveDataPoint(dp);
diff --git a/src/com/serotonin/mango/web/dwr/ViewDwr.java b/src/com/serotonin/mango/web/dwr/ViewDwr.java
index cb93dbe5bb..4798a06d51 100644
--- a/src/com/serotonin/mango/web/dwr/ViewDwr.java
+++ b/src/com/serotonin/mango/web/dwr/ViewDwr.java
@@ -303,6 +303,7 @@ private ViewComponentState preparePointComponentState(PointComponent pointCompon
}
state.setInfo(generateContent(request, "infoContent.jsp", model));
+ state.setWarningIcon(generateContent(request, "warningIcon.jsp", model));
setMessages(state, request, "warningContent", model);
return state;
diff --git a/src/com/serotonin/mango/web/dwr/beans/BasePointState.java b/src/com/serotonin/mango/web/dwr/beans/BasePointState.java
index 6075e85533..62fb08a070 100644
--- a/src/com/serotonin/mango/web/dwr/beans/BasePointState.java
+++ b/src/com/serotonin/mango/web/dwr/beans/BasePointState.java
@@ -25,6 +25,7 @@ abstract public class BasePointState implements Cloneable {
private String change;
private String chart;
private String messages;
+ private String warningIcon;
public String getId() {
return id;
@@ -58,6 +59,14 @@ public void setMessages(String messages) {
this.messages = messages;
}
+ public String getWarningIcon() {
+ return warningIcon;
+ }
+
+ public void setWarningIcon(String warningIcon) {
+ this.warningIcon = warningIcon;
+ }
+
public void removeEqualValue(BasePointState that) {
if (StringUtils.isEqual(change, that.change))
change = null;
diff --git a/src/org/scada_lts/dao/PendingEventsDAO.java b/src/org/scada_lts/dao/PendingEventsDAO.java
index 6cebd167eb..b77b7c2d7b 100644
--- a/src/org/scada_lts/dao/PendingEventsDAO.java
+++ b/src/org/scada_lts/dao/PendingEventsDAO.java
@@ -49,6 +49,7 @@ public class PendingEventsDAO {
private final static String COLUMN_NAME_EVENT_TYPE_ID = "typeId";
private final static String COLUMN_NAME_EVENT_TYPE_REF1 = "typeRef1";
private final static String COLUMN_NAME_EVENT_TYPE_REF2 = "typeRef2";
+ private final static String COLUMN_NAME_EVENT_TYPE_REF3 = "typeRef3";
private final static String COLUMN_NAME_EVENT_ACTIVE_TS = "activeTs";
private final static String COLUMN_NAME_EVENT_RTN_APPLICABLE = "rtnApplicable";
private final static String COLUMN_NAME_EVENT_RTN_TS = "rtnTs";
@@ -71,6 +72,7 @@ public class PendingEventsDAO {
+ "e.typeId, "
+ "e.typeRef1, "
+ "e.typeRef2, "
+ + "e.typeRef3, "
+ "e.activeTs, "
+ "e.rtnApplicable, "
+ "e.rtnTs, "
@@ -120,10 +122,7 @@ public List getPendingEvents(int userId, final Map> comments, ResultSet rs) throws SQLException {
- int typeId = rs.getInt(COLUMN_NAME_EVENT_TYPE_ID);
- int typeRef1 = rs.getInt(COLUMN_NAME_EVENT_TYPE_REF1);
- int typeRef2 = rs.getInt(COLUMN_NAME_EVENT_TYPE_REF2);
- EventType type = EventTypeUtil.createEventType(typeId,typeRef1,typeRef2);
+ EventType type = createEventType(rs);
long activeTS = rs.getLong(COLUMN_NAME_EVENT_ACTIVE_TS);
Boolean rtnApplicable = DAO.charToBool(rs.getString(COLUMN_NAME_EVENT_RTN_APPLICABLE));
int alarmLevel = rs.getInt(COLUMN_NAME_EVENT_ALARM_LEVEL);
@@ -176,4 +175,12 @@ private EventInstance mapToEvent(Map> comments, Resul
return event;
}
+
+ private static EventType createEventType(ResultSet rs) throws SQLException {
+ int typeId = rs.getInt(COLUMN_NAME_EVENT_TYPE_ID);
+ int typeRef1 = rs.getInt(COLUMN_NAME_EVENT_TYPE_REF1);
+ int typeRef2 = rs.getInt(COLUMN_NAME_EVENT_TYPE_REF2);
+ int typeRef3 = rs.getInt(COLUMN_NAME_EVENT_TYPE_REF3);
+ return EventTypeUtil.createEventType(typeId, typeRef1, typeRef2, typeRef3);
+ }
}
diff --git a/src/org/scada_lts/dao/event/EventDAO.java b/src/org/scada_lts/dao/event/EventDAO.java
index 9fd0d19578..73fd128ce2 100644
--- a/src/org/scada_lts/dao/event/EventDAO.java
+++ b/src/org/scada_lts/dao/event/EventDAO.java
@@ -31,6 +31,7 @@
import org.apache.commons.logging.LogFactory;
import org.scada_lts.dao.*;
import com.serotonin.mango.rt.event.type.AuditEventUtils;
+import org.scada_lts.utils.EventTypeUtil;
import org.scada_lts.utils.QueryUtils;
import org.scada_lts.utils.SQLPageWithTotal;
import org.scada_lts.web.beans.ApplicationBeans;
@@ -73,6 +74,7 @@ public class EventDAO implements GenericDaoCR {
private static final String COLUMN_NAME_TYPE_ID = "typeId";
private static final String COLUMN_NAME_TYPE_REF_1 = "typeRef1";
private static final String COLUMN_NAME_TYPE_REF_2 = "typeRef2";
+ private static final String COLUMN_NAME_TYPE_REF_3 = "typeRef3";
private static final String COLUMN_NAME_ACTIVE_TS = "activeTs";
private static final String COLUMN_NAME_RTN_APPLICABLE = "rtnApplicable";
private static final String COLUMN_NAME_RTN_TS = "rtnTs";
@@ -126,6 +128,7 @@ public class EventDAO implements GenericDaoCR {
"e." + COLUMN_NAME_TYPE_ID + ", " +
"e." + COLUMN_NAME_TYPE_REF_1 + ", " +
"e." + COLUMN_NAME_TYPE_REF_2 + ", " +
+ "e." + COLUMN_NAME_TYPE_REF_3 + ", " +
"e." + COLUMN_NAME_ACTIVE_TS + ", " +
"e." + COLUMN_NAME_RTN_APPLICABLE + ", " +
"e." + COLUMN_NAME_RTN_TS + ", " +
@@ -145,6 +148,7 @@ public class EventDAO implements GenericDaoCR {
+ "e."+COLUMN_NAME_TYPE_ID+", "
+ "e."+COLUMN_NAME_TYPE_REF_1+", "
+ "e."+COLUMN_NAME_TYPE_REF_2+","
+ + "e."+COLUMN_NAME_TYPE_REF_3+", "
+ "e."+COLUMN_NAME_ACTIVE_TS+","
+ "e."+COLUMN_NAME_RTN_APPLICABLE+", "
+ "e."+COLUMN_NAME_RTN_TS+","
@@ -168,6 +172,7 @@ public class EventDAO implements GenericDaoCR {
+ "e."+COLUMN_NAME_TYPE_ID+", "
+ "e."+COLUMN_NAME_TYPE_REF_1+", "
+ "e."+COLUMN_NAME_TYPE_REF_2+","
+ + "e."+COLUMN_NAME_TYPE_REF_3+","
+ "e."+COLUMN_NAME_ACTIVE_TS+","
+ "e."+COLUMN_NAME_RTN_APPLICABLE+", "
+ "e."+COLUMN_NAME_RTN_TS+","
@@ -200,7 +205,8 @@ public class EventDAO implements GenericDaoCR {
+ "insert events ("
+ COLUMN_NAME_TYPE_ID + ","
+ COLUMN_NAME_TYPE_REF_1 + ","
- + COLUMN_NAME_TYPE_REF_2 + ","
+ + COLUMN_NAME_TYPE_REF_2 + ","
+ + COLUMN_NAME_TYPE_REF_3 + ","
+ COLUMN_NAME_ACTIVE_TS + ","
+ COLUMN_NAME_RTN_APPLICABLE + ","
+ COLUMN_NAME_RTN_TS + ","
@@ -212,7 +218,7 @@ public class EventDAO implements GenericDaoCR {
// userId ?
// ack_source ?
+") "
- + "values (?,?,?,?,?,?,?,?,?,?,?)";
+ + "values (?,?,?,?,?,?,?,?,?,?,?,?)";
private static final String EVENT_UPDATE = ""
+ "update "
@@ -289,6 +295,7 @@ public class EventDAO implements GenericDaoCR {
+ "e."+COLUMN_NAME_TYPE_ID+", "
+ "e."+COLUMN_NAME_TYPE_REF_1+", "
+ "e."+COLUMN_NAME_TYPE_REF_2+","
+ + "e."+COLUMN_NAME_TYPE_REF_3+","
+ "e."+COLUMN_NAME_ACTIVE_TS+","
+ "e."+COLUMN_NAME_RTN_APPLICABLE+", "
+ "e."+COLUMN_NAME_RTN_TS+","
@@ -490,6 +497,7 @@ public class EventDAO implements GenericDaoCR {
"e." + COLUMN_NAME_TYPE_ID + ", " +
"e." + COLUMN_NAME_TYPE_REF_1 + ", " +
"e." + COLUMN_NAME_TYPE_REF_2 + ", " +
+ "e." + COLUMN_NAME_TYPE_REF_3 + ", " +
"e." + COLUMN_NAME_ACTIVE_TS + ", " +
"e." + COLUMN_NAME_RTN_APPLICABLE + ", " +
"e." + COLUMN_NAME_RTN_TS + ", " +
@@ -512,6 +520,7 @@ public class EventDAO implements GenericDaoCR {
"e." + COLUMN_NAME_TYPE_ID + ", " +
"e." + COLUMN_NAME_TYPE_REF_1 + ", " +
"e." + COLUMN_NAME_TYPE_REF_2 + ", " +
+ "e." + COLUMN_NAME_TYPE_REF_3 + ", " +
"e." + COLUMN_NAME_ACTIVE_TS + ", " +
"e." + COLUMN_NAME_RTN_APPLICABLE + ", " +
"e." + COLUMN_NAME_RTN_TS + ", " +
@@ -555,7 +564,7 @@ public class EventDAO implements GenericDaoCR {
+ STATUS_ACTIVE_CONDITION_SQL;
// @formatter:on
-
+ @Deprecated(since = "2.8.0")
//TODO rewrite
static EventType createEventType(ResultSet rs, int offset)
throws SQLException {
@@ -593,7 +602,7 @@ else if (typeId == EventType.EventSources.MAINTENANCE)
public static class EventRowMapper implements RowMapper {
public EventInstance mapRow(ResultSet rs, int rowNum) throws SQLException {
- EventType type = createEventType(rs, 2);
+ EventType type = createEventType(rs);
LocalizableMessage message;
LocalizableMessage shortMessage;
@@ -612,9 +621,9 @@ public EventInstance mapRow(ResultSet rs, int rowNum) throws SQLException {
}
EventInstance event = new EventInstance(
- type,
- rs.getLong(COLUMN_NAME_ACTIVE_TS),
- DAO.charToBool(rs.getString(COLUMN_NAME_RTN_APPLICABLE)),
+ type,
+ rs.getLong(COLUMN_NAME_ACTIVE_TS),
+ DAO.charToBool(rs.getString(COLUMN_NAME_RTN_APPLICABLE)),
rs.getInt(COLUMN_NAME_ALARM_LEVEL),
message,
shortMessage,
@@ -672,7 +681,7 @@ public UserComment mapRow(ResultSet rs, int rowNum) throws SQLException {
//TODO rewrite
private class EventTypeRowMapper implements RowMapper {
public EventType mapRow(ResultSet rs, int rowNum) throws SQLException {
- return createEventType(rs, 1);
+ return createEventType(rs);
}
}
@@ -779,12 +788,21 @@ public EventCommentDTO mapRow(ResultSet rs, int rowNum) throws SQLException {
}
}
+ @Deprecated(since = "2.8.0")
private class TotalRowMapper implements RowMapper {
public Integer mapRow(ResultSet rs, int rowNum) throws SQLException {
return rs.getInt("TOTAL");
}
}
+ private static EventType createEventType(ResultSet rs) throws SQLException {
+ int typeId = rs.getInt(COLUMN_NAME_TYPE_ID);
+ int typeRef1 = rs.getInt(COLUMN_NAME_TYPE_REF_1);
+ int typeRef2 = rs.getInt(COLUMN_NAME_TYPE_REF_2);
+ int typeRef3 = rs.getInt(COLUMN_NAME_TYPE_REF_3);
+ return EventTypeUtil.createEventType(typeId, typeRef1, typeRef2, typeRef3);
+ }
+
/**
* Select from Database Event Rows containing specific Type and Reference
* To increase performance there is provided a pagination function.
@@ -964,6 +982,7 @@ public PreparedStatement createPreparedStatement(Connection connection) throws S
type.getEventSourceId(),
type.getReferenceId1(),
type.getReferenceId2(),
+ type.getReferenceId3(),
entity.getActiveTimestamp(),
DAO.boolToChar(entity.isRtnApplicable()),
(!entity.isActive() ? entity.getRtnTimestamp():0),
diff --git a/src/org/scada_lts/dao/migration/mysql/V2_8_0_1__AddTypeRef3ColumnToEvents.java b/src/org/scada_lts/dao/migration/mysql/V2_8_0_1__AddTypeRef3ColumnToEvents.java
new file mode 100644
index 0000000000..5935bc901d
--- /dev/null
+++ b/src/org/scada_lts/dao/migration/mysql/V2_8_0_1__AddTypeRef3ColumnToEvents.java
@@ -0,0 +1,38 @@
+package org.scada_lts.dao.migration.mysql;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.flywaydb.core.api.migration.BaseJavaMigration;
+import org.flywaydb.core.api.migration.Context;
+import org.scada_lts.dao.DAO;
+import org.springframework.jdbc.core.JdbcTemplate;
+
+public class V2_8_0_1__AddTypeRef3ColumnToEvents extends BaseJavaMigration {
+
+ private static final Log LOG = LogFactory.getLog(V2_8_0_1__AddTypeRef3ColumnToEvents.class);
+
+ @Override
+ public void migrate(Context context) throws Exception {
+
+ final JdbcTemplate jdbcTmp = DAO.getInstance().getJdbcTemp();
+
+ try {
+ migrate(jdbcTmp);
+ } catch (Exception ex) {
+ LOG.error(ex.getMessage(), ex);
+ throw ex;
+ }
+ }
+
+ private void migrate(JdbcTemplate jdbcTmp) {
+ String sql = "ALTER TABLE events ADD COLUMN typeRef3 int not null";
+ try {
+ jdbcTmp.update(sql);
+ } catch (Exception ex) {
+ if(ex.getMessage() != null && !ex.getMessage().contains("Duplicate"))
+ throw ex;
+ LOG.warn(ex.getMessage(), ex);
+ }
+ }
+}
+
diff --git a/src/org/scada_lts/ds/messaging/MessagingDataSourceRT.java b/src/org/scada_lts/ds/messaging/MessagingDataSourceRT.java
index 8904344af3..e1d87c2d47 100644
--- a/src/org/scada_lts/ds/messaging/MessagingDataSourceRT.java
+++ b/src/org/scada_lts/ds/messaging/MessagingDataSourceRT.java
@@ -21,8 +21,6 @@
public class MessagingDataSourceRT extends PollingDataSource {
- private static final String ATTR_UNRELIABLE_KEY = "UNRELIABLE";
- private static final String ATTR_UPDATE_ERROR_KEY = "DP_UPDATE_ERROR";
public static final int DATA_SOURCE_EXCEPTION_EVENT = 1;
public static final int DATA_POINT_PUBLISH_EXCEPTION_EVENT = 2;
@@ -51,32 +49,33 @@ public void setPointValue(DataPointRT dataPoint, PointValueTime valueTime, SetPo
if (!messagingService.isOpen(dataPoint)) {
LOG.warn("Error Publish: " + dataSourcePointValueTimeInfo(vo, dataPointVO, valueTime, source));
raiseEvent(DATA_POINT_PUBLISH_EXCEPTION_EVENT, System.currentTimeMillis(), true,
- getExceptionMessage(new RuntimeException("Error Publish: " + dataSourcePointValueTimeInfo(vo, dataPointVO, valueTime, source) + ", Message: Connection Closed. ")));
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ getExceptionMessage(new RuntimeException("Error Publish: " + dataSourcePointValueTimeInfo(vo, dataPointVO, valueTime, source) + ", Message: Connection Closed. ")),
+ dataPoint);
return;
}
String message = valueTime.getStringValue();
try {
messagingService.publish(dataPoint, message);
- returnToNormal(DATA_POINT_PUBLISH_EXCEPTION_EVENT, System.currentTimeMillis());
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, false);
- } catch (Exception e) {
+ returnToNormal(DATA_POINT_PUBLISH_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
LOG.error(dataSourcePointValueTimeInfo(vo, dataPointVO, valueTime, source) + ", "
+ exceptionInfo(e), e);
raiseEvent(DATA_POINT_PUBLISH_EXCEPTION_EVENT, System.currentTimeMillis(), true,
- new LocalizableMessage("event.ds.publishFailed", dataPointVO.getName()));
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ new LocalizableMessage("event.ds.publishFailed", dataPointVO.getName()), dataPoint);
}
}
@Override
public void initialize() {
try {
+ updateAttemptsCounters.clear();
messagingService.open();
- } catch (Exception e) {
- LOG.error(exceptionInfo(e), e);
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(info(e, this), e);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(),
- false, getExceptionMessage(e));
+ true, getExceptionMessage(e));
+ return;
}
super.initialize();
}
@@ -87,12 +86,13 @@ public void terminate() {
super.terminate();
try {
messagingService.close();
- } catch (Exception e) {
- LOG.error(exceptionInfo(e), e);
+ returnToNormal(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis());
+ } catch (Throwable e) {
+ LOG.error(info(e, this), e);
raiseEvent(DATA_SOURCE_EXCEPTION_EVENT, System.currentTimeMillis(),
- false, getExceptionMessage(e));
+ true, getExceptionMessage(e));
} finally {
- updateAttemptsCounters.clear();
+ updateAttemptsCounters.values().stream().peek(a -> a.set(0)).close();
}
}
@@ -100,13 +100,12 @@ public void terminate() {
public void addDataPoint(DataPointRT dataPoint) {
try {
updateAttemptsCounters.putIfAbsent(dataPoint.getId(), new AtomicInteger());
- messagingService.initReceiver(dataPoint, getPointUpdateExceptionHandler(dataPoint), ATTR_UPDATE_ERROR_KEY);
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, false);
- } catch (Exception e) {
- LOG.error(exceptionInfo(e), e);
+ messagingService.initReceiver(dataPoint, getPointUpdateExceptionHandler(dataPoint), getPointUpdateReturnToNormalHandler());
+ returnToNormal(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
+ LOG.error(info(e, this), e);
raiseEvent(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(),
- false, getExceptionMessage(e));
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ true, getExceptionMessage(e), dataPoint);
}
super.addDataPoint(dataPoint);
}
@@ -115,12 +114,13 @@ public void addDataPoint(DataPointRT dataPoint) {
public void removeDataPoint(DataPointRT dataPoint) {
try {
messagingService.removeReceiver(dataPoint);
- } catch (Exception e) {
- LOG.error(exceptionInfo(e), e);
+ returnToNormal(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ } catch (Throwable e) {
+ LOG.error(info(e, this), e);
raiseEvent(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(),
- false, getExceptionMessage(e));
+ true, getExceptionMessage(e), dataPoint);
} finally {
- updateAttemptsCounters.remove(dataPoint.getId());
+ updateAttemptsCounters.get(dataPoint.getId()).set(0);
}
super.removeDataPoint(dataPoint);
}
@@ -129,35 +129,41 @@ public void removeDataPoint(DataPointRT dataPoint) {
protected void doPoll(long time) {
for (DataPointRT dataPoint : dataPoints) {
try {
- updateAttemptsCounters.putIfAbsent(dataPoint.getId(), new AtomicInteger());
- if(updateAttemptsCounters.get(dataPoint.getId()).get() < updateAttempts) {
- messagingService.initReceiver(dataPoint, getPointUpdateExceptionHandler(dataPoint), ATTR_UPDATE_ERROR_KEY);
- updateAttemptsCounters.get(dataPoint.getId()).set(0);
- returnToNormal(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis());
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, false);
+ if(!messagingService.isOpen(dataPoint)) {
+ updateAttemptsCounters.putIfAbsent(dataPoint.getId(), new AtomicInteger());
+ if (updateAttemptsCounters.get(dataPoint.getId()).get() < updateAttempts) {
+ messagingService.initReceiver(dataPoint, getPointUpdateExceptionHandler(dataPoint), getPointUpdateReturnToNormalHandler());
+ updateAttemptsCounters.get(dataPoint.getId()).set(0);
+ returnToNormal(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
+ }
+ } else {
+ returnToNormal(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(), dataPoint);
}
- } catch (Exception e) {
- LOG.warn(exceptionInfo(e), e);
+ } catch (Throwable e) {
+ LOG.error(info(e, this), e);
int dataPointId = dataPoint.getId();
- AtomicInteger counter = updateAttemptsCounters.get(dataPointId);
- if(counter != null) {
- counter.incrementAndGet();
- }
+ updateAttemptsCounters.computeIfPresent(dataPointId, (a,b) -> {b.incrementAndGet(); return b;});
raiseEvent(DATA_POINT_INIT_EXCEPTION_EVENT, System.currentTimeMillis(),
- true, getExceptionMessage(e));
- dataPoint.setAttribute(ATTR_UNRELIABLE_KEY, true);
+ true, getExceptionMessage(e), dataPoint);
}
}
}
- private java.util.function.Consumer getPointUpdateExceptionHandler(DataPointRT dataPoint) {
+ private java.util.function.Consumer getPointUpdateExceptionHandler(DataPointRT dataPoint) {
return ex -> {
LOG.warn("Error Update: " + dataPointInfo(dataPoint.getVO()) + ", " + dataSourceInfo(vo) + ", "
+ exceptionInfo(ex), ex);
raiseEvent(DATA_POINT_UPDATE_EXCEPTION_EVENT, System.currentTimeMillis(),
- false, getExceptionMessage(new Exception("Error Update Data Point: " + dataPointInfo(dataPoint.getVO())
+ true, getExceptionMessage(new Exception("Error Update Data Point: " + dataPointInfo(dataPoint.getVO())
+ ", " + exceptionInfo(ex), ex)
- ));
+ ), dataPoint);
+ };
+ }
+
+ private java.util.function.Supplier getPointUpdateReturnToNormalHandler() {
+ return () -> {
+ returnToNormal(DATA_POINT_UPDATE_EXCEPTION_EVENT, System.currentTimeMillis());
+ return null;
};
}
}
\ No newline at end of file
diff --git a/src/org/scada_lts/ds/messaging/channel/InitMessagingChannels.java b/src/org/scada_lts/ds/messaging/channel/InitMessagingChannels.java
index a301f549ee..94ff8d43de 100644
--- a/src/org/scada_lts/ds/messaging/channel/InitMessagingChannels.java
+++ b/src/org/scada_lts/ds/messaging/channel/InitMessagingChannels.java
@@ -4,7 +4,8 @@
import org.scada_lts.ds.messaging.exception.MessagingChannelException;
import java.util.function.Consumer;
+import java.util.function.Supplier;
public interface InitMessagingChannels extends MessagingChannels {
- void initChannel(DataPointRT dataPoint, Consumer exceptionHandler, String updateErrorKey) throws MessagingChannelException;
+ void initChannel(DataPointRT dataPoint, Consumer exceptionHandler, Supplier returnToNormal) throws MessagingChannelException;
}
diff --git a/src/org/scada_lts/ds/messaging/channel/MessagingChannelsImpl.java b/src/org/scada_lts/ds/messaging/channel/MessagingChannelsImpl.java
index 810439797e..e9e718185a 100644
--- a/src/org/scada_lts/ds/messaging/channel/MessagingChannelsImpl.java
+++ b/src/org/scada_lts/ds/messaging/channel/MessagingChannelsImpl.java
@@ -26,7 +26,7 @@ public void removeChannel(DataPointRT dataPoint) throws MessagingChannelExceptio
channel.close(timeout);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Remove Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -46,7 +46,7 @@ public void initChannel(DataPointRT dataPoint, Supplier create
getChannelIfOpen(dataPoint).orElseGet(() -> operationChannels.createChannelIfNotExists(dataPoint.getId(), a -> create.get()));
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Init Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -58,7 +58,7 @@ public void publish(DataPointRT dataPoint, String message) {
channel.publish(message);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Publish: " + dataPointInfo(dataPoint.getVO()) + ", Value: " + message + ", " + exceptionInfo(e), e);
}
});
diff --git a/src/org/scada_lts/ds/messaging/channel/NonSyncOperationChannels.java b/src/org/scada_lts/ds/messaging/channel/NonSyncOperationChannels.java
index 347018a3a9..82c912ee71 100644
--- a/src/org/scada_lts/ds/messaging/channel/NonSyncOperationChannels.java
+++ b/src/org/scada_lts/ds/messaging/channel/NonSyncOperationChannels.java
@@ -23,7 +23,7 @@ public void closeChannels(int timeout) throws MessagingChannelException {
for(MessagingChannel channel: chs.values()) {
try {
channel.close(timeout);
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.warn("Error Init Channel: " + channel.getClass().getName() + ", " + exceptionInfo(ex), ex);
}
}
diff --git a/src/org/scada_lts/ds/messaging/channel/SyncOperationChannels.java b/src/org/scada_lts/ds/messaging/channel/SyncOperationChannels.java
index 08e823af3f..438208248c 100644
--- a/src/org/scada_lts/ds/messaging/channel/SyncOperationChannels.java
+++ b/src/org/scada_lts/ds/messaging/channel/SyncOperationChannels.java
@@ -1,7 +1,9 @@
package org.scada_lts.ds.messaging.channel;
-import net.bull.javamelody.internal.common.LOG;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.scada_lts.ds.messaging.exception.MessagingChannelException;
+import org.scada_lts.ds.messaging.protocol.amqp.client.AmqpMessagingChannels;
import java.util.HashMap;
import java.util.Map;
@@ -12,6 +14,8 @@
class SyncOperationChannels implements OperationChannels {
+ private static final Log LOG = LogFactory.getLog(AmqpMessagingChannels.class);
+
private final Map channels;
private final ReentrantReadWriteLock lock;
@@ -28,7 +32,7 @@ public void closeChannels(int timeout) throws MessagingChannelException {
for(MessagingChannel channel: chs.values()) {
try {
channel.close(timeout);
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.warn("Error Init Channel: " + channel.getClass().getName() + ", " + exceptionInfo(ex), ex);
}
}
diff --git a/src/org/scada_lts/ds/messaging/channel/UpdatePointValueConsumer.java b/src/org/scada_lts/ds/messaging/channel/UpdatePointValueConsumer.java
index 29bdb9963e..ea50e9c3b1 100644
--- a/src/org/scada_lts/ds/messaging/channel/UpdatePointValueConsumer.java
+++ b/src/org/scada_lts/ds/messaging/channel/UpdatePointValueConsumer.java
@@ -4,20 +4,20 @@
import java.nio.charset.StandardCharsets;
import java.util.function.Consumer;
+import java.util.function.Supplier;
public class UpdatePointValueConsumer implements Consumer {
private final DataPointRT dataPoint;
private final Writable writable;
- private final String updateErrorKey;
- private final Consumer exceptionHandler;
+ private final Consumer exceptionHandler;
+ private final Supplier returnToNormal;
- public UpdatePointValueConsumer(DataPointRT dataPoint, Writable writable,
- String updateErrorKey, Consumer exceptionHandler) {
+ public UpdatePointValueConsumer(DataPointRT dataPoint, Writable writable, Consumer exceptionHandler, Supplier returnToNormal) {
this.dataPoint = dataPoint;
this.writable = writable;
- this.updateErrorKey = updateErrorKey;
this.exceptionHandler = exceptionHandler;
+ this.returnToNormal = returnToNormal;
}
@Override
@@ -26,10 +26,9 @@ public void accept(byte[] payload) {
try {
String message = new String(payload, StandardCharsets.UTF_8);
dataPoint.updatePointValue(message);
- dataPoint.setAttribute(updateErrorKey, false);
- } catch (Exception ex) {
+ returnToNormal.get();
+ } catch (Throwable ex) {
exceptionHandler.accept(ex);
- dataPoint.setAttribute(updateErrorKey, true);
}
}
}
diff --git a/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpChannelFactory.java b/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpChannelFactory.java
index 5589435ec0..f6d6762461 100644
--- a/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpChannelFactory.java
+++ b/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpChannelFactory.java
@@ -8,17 +8,17 @@
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
+import java.util.function.Supplier;
final class AmqpChannelFactory {
private AmqpChannelFactory() {}
- static AmqpChannel createReceiver(DataPointRT dataPoint, AmqpConnection connection, Consumer exceptionHandler,
- String updateErrorKey) throws IOException {
+ static AmqpChannel createReceiver(DataPointRT dataPoint, AmqpConnection connection, Consumer exceptionHandler, Supplier returnToNormal) throws IOException {
AmqpChannel receive = configChannel(dataPoint, connection);
if(receive == null)
return null;
- basicConsume(dataPoint, receive, exceptionHandler, updateErrorKey);
+ basicConsume(dataPoint, receive, exceptionHandler, returnToNormal);
return receive;
}
@@ -59,13 +59,11 @@ private static void basicQos(AmqpChannel channel, AmqpPointLocatorVO vo) throws
channel.basicQos(vo.getQos());
}
- private static void basicConsume(DataPointRT dataPoint, AmqpChannel channel, Consumer exceptionHandler,
- String updateErrorKey) throws IOException {
+ private static void basicConsume(DataPointRT dataPoint, AmqpChannel channel, Consumer exceptionHandler, Supplier returnToNormal) throws IOException {
AmqpPointLocatorRT locator = dataPoint.getPointLocator();
AmqpPointLocatorVO vo = locator.getVO();
boolean noAck = vo.getMessageAck() == MessageAckType.NO_ACK;
- channel.basicConsume(vo.getQueueName(), noAck, new UpdatePointValueConsumer(dataPoint, vo::isWritable,
- updateErrorKey, exceptionHandler));
+ channel.basicConsume(vo.getQueueName(), noAck, new UpdatePointValueConsumer(dataPoint, vo::isWritable, exceptionHandler, returnToNormal));
}
private static void declare(AmqpChannel channel, AmqpPointLocatorVO vo) throws IOException {
diff --git a/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannel.java b/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannel.java
index b10b51c995..c5ef9311e1 100644
--- a/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannel.java
+++ b/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannel.java
@@ -32,7 +32,7 @@ public void close(int timeout) throws MessagingChannelException {
channel.close();
} catch (IOException e) {
throw new MessagingChannelException("Error Close Channel: " + dataPointInfo(dataPointRT.getVO()) + ", " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Close Channel: " + dataPointInfo(dataPointRT.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -43,7 +43,7 @@ public void publish(String message) throws MessagingChannelException {
basicPublish(dataPointRT, channel, message);
} catch (IOException e) {
throw new MessagingChannelException("Error Publish: " + dataPointInfo(dataPointRT.getVO()) + ", " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Publish: " + dataPointInfo(dataPointRT.getVO()) + ", " + exceptionInfo(e), e);
}
}
diff --git a/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannels.java b/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannels.java
index d07485cd71..ccbb63a99e 100644
--- a/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannels.java
+++ b/src/org/scada_lts/ds/messaging/protocol/amqp/client/AmqpMessagingChannels.java
@@ -37,11 +37,11 @@ public void openConnection() throws MessagingChannelException {
} catch (IOException e) {
try {
connectionManager.close();
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.warn("Error Close Channel: " + exceptionInfo(e), e);
}
throw new MessagingChannelException("Error Open Channel: " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
try {
connectionManager.close();
} catch (Exception ex) {
@@ -57,7 +57,7 @@ public void removeChannel(DataPointRT dataPoint) throws MessagingChannelExceptio
channels.removeChannel(dataPoint);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Remove Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
} finally {
if (channels.size() == 0) {
@@ -76,20 +76,20 @@ public boolean isOpenChannel(DataPointRT dataPoint) {
}
@Override
- public void initChannel(DataPointRT dataPoint, Consumer exceptionHandler, String updateErrorKey) throws MessagingChannelException {
+ public void initChannel(DataPointRT dataPoint, Consumer exceptionHandler, Supplier returnToNormal) throws MessagingChannelException {
connectionManager.getIfOpen().or(() -> {
try {
return Optional.ofNullable(connectionManager.open(vo));
} catch (IOException e) {
throw new MessagingChannelException("Error Open Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Open Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}).ifPresent(conn -> {
try {
channels.initChannel(dataPoint, () -> {
try {
- return new AmqpMessagingChannel(AmqpChannelFactory.createReceiver(dataPoint, conn, exceptionHandler, updateErrorKey), dataPoint);
+ return new AmqpMessagingChannel(AmqpChannelFactory.createReceiver(dataPoint, conn, exceptionHandler, returnToNormal), dataPoint);
} catch (IOException e) {
throw new MessagingChannelException("Error Create Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + causeInfo(e), e.getCause());
} catch (Exception e) {
@@ -97,7 +97,7 @@ public void initChannel(DataPointRT dataPoint, Consumer exceptionHand
}});
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Init Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
});
@@ -110,7 +110,7 @@ public void initChannel(DataPointRT dataPoint, Supplier create
return Optional.ofNullable(connectionManager.open(vo));
} catch (IOException e) {
throw new MessagingChannelException("Error Open Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Open Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}).ifPresent(conn -> {
@@ -118,7 +118,7 @@ public void initChannel(DataPointRT dataPoint, Supplier create
channels.initChannel(dataPoint, create);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Init Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
});
@@ -131,7 +131,7 @@ public void publish(DataPointRT dataPoint, String message) throws MessagingChann
return Optional.ofNullable(connectionManager.open(vo));
} catch (IOException e) {
throw new MessagingChannelException("Error Open Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Open Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}).ifPresent(conn -> {
@@ -139,7 +139,7 @@ public void publish(DataPointRT dataPoint, String message) throws MessagingChann
channels.publish(dataPoint, message);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Publish: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
});
@@ -154,12 +154,12 @@ public boolean isOpenConnection() {
public void closeChannels() throws MessagingChannelException {
try {
channels.closeChannels();
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.warn("Error Close Channels: " + exceptionInfo(ex), ex);
} finally {
try {
connectionManager.close();
- } catch (IOException e) {
+ } catch (Throwable e) {
LOG.warn("Error Close Connection: " + exceptionInfo(e), e);
}
}
diff --git a/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannel.java b/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannel.java
index 02a63ba2eb..365dc64e1c 100644
--- a/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannel.java
+++ b/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannel.java
@@ -36,12 +36,12 @@ public void close(int timeout) throws MessagingChannelException {
client.disconnect(timeout);
} catch (IOException e) {
throw new MessagingChannelException("Error Disconnect Channel: " + dataPointInfo(dataPointRT.getVO()) + ", " + causeInfo(e), e.getCause());
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Disconnect Channel: " + dataPointInfo(dataPointRT.getVO()) + ", " + exceptionInfo(e), e);
} finally {
try {
client.close();
- } catch (Exception e) {
+ } catch (Throwable e) {
LOG.warn("Error Close Channel: " + dataPointInfo(dataPointRT.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -54,7 +54,7 @@ public void publish(String message) throws MessagingChannelException {
try {
client.publish(locator.getTopicFilter(), message.getBytes(StandardCharsets.UTF_8),
locator.getQos(), locator.isRetained());
- } catch (Exception ex) {
+ } catch (Throwable ex) {
throw new RuntimeException("Error Publish: " + dataPointInfo(dataPointRT.getVO())+ ", Value: " + message + ", " + exceptionInfo(ex), ex);
}
}
diff --git a/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannels.java b/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannels.java
index 1dfa13dc8b..3bd5825f7e 100644
--- a/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannels.java
+++ b/src/org/scada_lts/ds/messaging/protocol/mqtt/client/MqttMessagingChannels.java
@@ -35,7 +35,7 @@ public void removeChannel(DataPointRT dataPoint) throws MessagingChannelExceptio
channels.removeChannel(dataPoint);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Remove Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -46,18 +46,18 @@ public boolean isOpenChannel(DataPointRT dataPoint) {
}
@Override
- public void initChannel(DataPointRT dataPoint, Consumer exceptionHandler, String updateErrorKey) throws MessagingChannelException {
+ public void initChannel(DataPointRT dataPoint, Consumer exceptionHandler, Supplier returnToNormal) throws MessagingChannelException {
try {
channels.initChannel(dataPoint, () -> {
try {
- return new MqttMessagingChannel(createClient(dataPoint, exceptionHandler, updateErrorKey), dataPoint);
- } catch (Exception e) {
+ return new MqttMessagingChannel(createClient(dataPoint, exceptionHandler, returnToNormal), dataPoint);
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Create Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + causeInfo(e), e.getCause());
}
});
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Init Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -68,7 +68,7 @@ public void initChannel(DataPointRT dataPoint, Supplier create
channels.initChannel(dataPoint, create);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Init Channel: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -79,7 +79,7 @@ public void publish(DataPointRT dataPoint, String message) throws MessagingChann
channels.publish(dataPoint, message);
} catch (MessagingChannelException e) {
throw e;
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Publish: " + dataPointInfo(dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
}
@@ -93,8 +93,8 @@ public boolean isOpenConnection() {
public void closeChannels() throws MessagingChannelException {
try {
channels.closeChannels();
- } catch (Exception ex) {
- LOG.warn("Error Close Channels: " + exceptionInfo(ex), ex);
+ } catch (Throwable ex) {
+ LOG.warn("Error Close Channels: " + dataSourceInfo(vo) + ", " + exceptionInfo(ex), ex);
}
}
@@ -103,7 +103,7 @@ public int size() {
return channels.size();
}
- private MqttVClient createClient(DataPointRT dataPoint, Consumer exceptionHandler, String updateErrorKey) throws MessagingChannelException {
+ private MqttVClient createClient(DataPointRT dataPoint, Consumer exceptionHandler, Supplier returnToNormal) throws MessagingChannelException {
MqttPointLocatorRT pointLocator = dataPoint.getPointLocator();
MqttPointLocatorVO locator = pointLocator.getVO();
@@ -111,21 +111,21 @@ private MqttVClient createClient(DataPointRT dataPoint, Consumer exce
try {
MqttVersion mqttVersion = (MqttVersion) vo.getProtocolVersion();
client = mqttVersion.newClient(vo, locator);
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Create Client: " + dataSourcePointInfo(vo, dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
try {
client.connect();
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingChannelException("Error Connect Client: " + dataSourcePointInfo(vo, dataPoint.getVO()) + ", " + exceptionInfo(e), e);
}
try {
client.subscribe(locator.getTopicFilter(), locator.getQos(), (topic, mqttMessage) ->
- new UpdatePointValueConsumer(dataPoint, locator::isWritable, updateErrorKey, exceptionHandler).accept(mqttMessage.getPayload()));
- } catch (Exception e) {
+ new UpdatePointValueConsumer(dataPoint, locator::isWritable, exceptionHandler, returnToNormal).accept(mqttMessage.getPayload()));
+ } catch (Throwable e) {
try {
close(client);
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.warn("Error Close Client: " + dataSourcePointInfo(vo, dataPoint.getVO()) + ", " + exceptionInfo(ex), ex);
}
throw new MessagingChannelException("Error Subscribe Client: " + dataSourcePointInfo(vo, dataPoint.getVO()) + ", " + exceptionInfo(e), e);
diff --git a/src/org/scada_lts/ds/messaging/service/MessagingService.java b/src/org/scada_lts/ds/messaging/service/MessagingService.java
index 9d66fd17d3..5ad44202e4 100644
--- a/src/org/scada_lts/ds/messaging/service/MessagingService.java
+++ b/src/org/scada_lts/ds/messaging/service/MessagingService.java
@@ -4,6 +4,7 @@
import org.scada_lts.ds.messaging.exception.MessagingServiceException;
import java.util.function.Consumer;
+import java.util.function.Supplier;
public interface MessagingService {
@@ -12,7 +13,7 @@ public interface MessagingService {
void open() throws MessagingServiceException;
void close() throws MessagingServiceException;
- void initReceiver(DataPointRT dataPoint, Consumer updateExceptionHandler, String updateErrorKey) throws MessagingServiceException;
+ void initReceiver(DataPointRT dataPoint, Consumer updateExceptionHandler, Supplier returnToNormal) throws MessagingServiceException;
void removeReceiver(DataPointRT dataPoint) throws MessagingServiceException;
void publish(DataPointRT dataPoint, String message) throws MessagingServiceException;
}
diff --git a/src/org/scada_lts/ds/messaging/service/MessagingServiceImpl.java b/src/org/scada_lts/ds/messaging/service/MessagingServiceImpl.java
index cb9d44768f..a1f3fbe0f1 100644
--- a/src/org/scada_lts/ds/messaging/service/MessagingServiceImpl.java
+++ b/src/org/scada_lts/ds/messaging/service/MessagingServiceImpl.java
@@ -8,6 +8,7 @@
import org.scada_lts.ds.messaging.exception.MessagingServiceException;
import java.util.function.Consumer;
+import java.util.function.Supplier;
import static com.serotonin.mango.util.LoggingUtils.*;
@@ -30,27 +31,27 @@ class MessagingServiceImpl implements MessagingService {
@Override
public void publish(DataPointRT dataPoint, String message) throws MessagingServiceException {
if(blocked) {
- throw new MessagingServiceException("Stop Publish: " + dataSourceInfo(vo) + ", Service of shutting down: " + dataSourceInfo(vo) + ", Value: " + message);
+ throw new MessagingServiceException("Stop Publish: " + dataPointInfo(dataPoint) + ", Service of shutting down: " + dataSourceInfo(vo) + ", Value: " + message);
}
try {
channels.publish(dataPoint, message);
- } catch (Exception e) {
- throw new MessagingServiceException("Error Publish: " + dataSourceInfo(vo) + ", Value: " + message + ", " + exceptionInfo(e), e);
+ } catch (Throwable e) {
+ throw new MessagingServiceException("Error Publish: " + dataPointInfo(dataPoint) + ", Value: " + message + ", " + exceptionInfo(e), e);
}
}
@Override
- public void initReceiver(DataPointRT dataPoint, Consumer exceptionHandler, String updateErrorKey) throws MessagingServiceException {
+ public void initReceiver(DataPointRT dataPoint, Consumer exceptionHandler, Supplier returnToNormal) throws MessagingServiceException {
if(blocked) {
- LOG.warn("Stop Init Receiver: " + dataSourceInfo(vo) + ", Service of shutting down: " + dataSourceInfo(vo));
+ LOG.warn("Stop Init Receiver: " + dataPointInfo(dataPoint) + ", Service of shutting down: " + dataSourceInfo(vo));
return;
}
if(isOpen(dataPoint)) {
return;
}
try {
- channels.initChannel(dataPoint, exceptionHandler, updateErrorKey);
- } catch (Exception e) {
+ channels.initChannel(dataPoint, exceptionHandler, returnToNormal);
+ } catch (Throwable e) {
throw new MessagingServiceException("Error Init Receiver: " + dataSourceInfo(vo) + ", " + exceptionInfo(e), e);
}
}
@@ -58,12 +59,12 @@ public void initReceiver(DataPointRT dataPoint, Consumer exceptionHan
@Override
public void removeReceiver(DataPointRT dataPoint) throws MessagingServiceException {
if(blocked) {
- LOG.warn("Stop Remove Receiver: " + dataSourceInfo(vo) + ", Service of shutting down: " + dataSourceInfo(vo));
+ LOG.warn("Stop Remove Receiver: " + dataPointInfo(dataPoint) + ", Service of shutting down: " + dataSourceInfo(vo));
return;
}
try {
channels.removeChannel(dataPoint);
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingServiceException("Error Remove Receiver: " + dataSourceInfo(vo) + ", " + exceptionInfo(e), e);
}
}
@@ -80,16 +81,14 @@ public boolean isOpen(DataPointRT dataPoint) {
@Override
public void open() throws MessagingServiceException {
- if(blocked) {
- throw new MessagingServiceException("Stop Open Connection: Service of shutting down: " + dataSourceInfo(vo));
- }
if(channels.isOpenConnection()) {
+ blocked = false;
LOG.warn("Stop Open Connection: Connection is opened: " + dataSourceInfo(vo));
return;
}
try {
channels.openConnection();
- } catch (Exception e) {
+ } catch (Throwable e) {
throw new MessagingServiceException("Error Open Connection: " + dataSourceInfo(vo) + ", " + exceptionInfo(e), e);
}
blocked = false;
@@ -100,7 +99,7 @@ public void close() throws MessagingServiceException {
blocked = true;
try {
channels.closeChannels();
- } catch (Exception ex) {
+ } catch (Throwable ex) {
LOG.warn("Error Close Receivers: " + dataSourceInfo(vo) + ", " + exceptionInfo(ex), ex);
}
}
diff --git a/src/org/scada_lts/mango/service/PointValueService.java b/src/org/scada_lts/mango/service/PointValueService.java
index 5caa052eb9..ea9811c293 100644
--- a/src/org/scada_lts/mango/service/PointValueService.java
+++ b/src/org/scada_lts/mango/service/PointValueService.java
@@ -681,7 +681,7 @@ public void updateMetaDataPointByScript(User user, String xid) {
ScriptExecutor scriptExecutor = new ScriptExecutor();
- Map context = scriptExecutor.convertContext(metaPointLocatorVO.getContext());
+ Map context = scriptExecutor.convertContext(metaPointLocatorVO.getContext(), dataPointRT, metaDataSourceRT);
PointValueTime pointValueTime = scriptExecutor.execute(metaPointLocatorVO.getScript(), context, System.currentTimeMillis(), metaPointLocatorVO.getDataTypeId(), System.currentTimeMillis());
Common.ctx.getRuntimeManager().setDataPointValue(dataPoint.getId(), pointValueTime, user);
diff --git a/src/org/scada_lts/serial/gnu/io/ScadaCommPortIdentifier.java b/src/org/scada_lts/serial/gnu/io/ScadaCommPortIdentifier.java
new file mode 100644
index 0000000000..3876e196ce
--- /dev/null
+++ b/src/org/scada_lts/serial/gnu/io/ScadaCommPortIdentifier.java
@@ -0,0 +1,11 @@
+package org.scada_lts.serial.gnu.io;
+
+
+import java.util.Enumeration;
+
+public class ScadaCommPortIdentifier {
+
+ public static Enumeration getPortIdentifiers() {
+ return gnu.io.CommPortIdentifier.getPortIdentifiers();
+ }
+}
diff --git a/src/org/scada_lts/utils/EventTypeUtil.java b/src/org/scada_lts/utils/EventTypeUtil.java
index 61e627f136..8ebdd0caf0 100644
--- a/src/org/scada_lts/utils/EventTypeUtil.java
+++ b/src/org/scada_lts/utils/EventTypeUtil.java
@@ -29,6 +29,7 @@
import com.serotonin.mango.rt.event.type.PublisherEventType;
import com.serotonin.mango.rt.event.type.ScheduledEventType;
import com.serotonin.mango.rt.event.type.SystemEventType;
+import com.serotonin.mango.rt.event.type.DataSourcePointEventType;
/**
* Deliver type corresponding with mango.
@@ -38,7 +39,7 @@
*/
public class EventTypeUtil {
- public static EventType createEventType(int typeId, int typeRef1, int typeRef2)
+ public static EventType createEventType(int typeId, int typeRef1, int typeRef2, int typeRef3)
throws SQLException {
EventType type;
@@ -58,6 +59,8 @@ public static EventType createEventType(int typeId, int typeRef1, int typeRef2)
type = new AuditEventType(typeRef1,typeRef2);
} else if (typeId == EventType.EventSources.MAINTENANCE) {
type = new MaintenanceEventType(typeRef1);
+ } else if (typeId == EventType.EventSources.DATA_SOURCE_POINT) {
+ type = new DataSourcePointEventType(new DataSourceEventType(typeRef1, typeRef2), typeRef3);
} else {
throw new ShouldNeverHappenException("Unknown event type: " + typeId);
}
diff --git a/src/org/scada_lts/utils/MetaDataPointUtils.java b/src/org/scada_lts/utils/MetaDataPointUtils.java
new file mode 100644
index 0000000000..cb0c222341
--- /dev/null
+++ b/src/org/scada_lts/utils/MetaDataPointUtils.java
@@ -0,0 +1,33 @@
+package org.scada_lts.utils;
+
+import com.serotonin.db.IntValuePair;
+import com.serotonin.mango.rt.dataImage.DataPointRT;
+import com.serotonin.mango.rt.dataSource.meta.MetaPointLocatorRT;
+import com.serotonin.mango.vo.dataSource.meta.MetaPointLocatorVO;
+
+import java.util.Objects;
+
+
+public final class MetaDataPointUtils {
+
+ private MetaDataPointUtils() {}
+
+ public static boolean isDataPointInContext(DataPointRT dataPoint, int dataPointInContextId) {
+ if (isMetaDataPointRT(dataPoint)) {
+ MetaPointLocatorRT metaPointLocatorRT = dataPoint.getPointLocator();
+ if(metaPointLocatorRT != null) {
+ MetaPointLocatorVO metaPointLocatorVO = metaPointLocatorRT.getPointLocatorVO();
+ if(metaPointLocatorVO != null && metaPointLocatorVO.getContext() != null) {
+ return metaPointLocatorVO.getContext().stream()
+ .map(IntValuePair::getKey)
+ .anyMatch(a -> a == dataPointInContextId);
+ }
+ }
+ }
+ return false;
+ }
+
+ public static boolean isMetaDataPointRT(DataPointRT dataPoint) {
+ return Objects.nonNull(dataPoint) && dataPoint.getPointLocator() instanceof MetaPointLocatorRT;
+ }
+}
diff --git a/test/br/org/scadabr/db/utils/TestUtils.java b/test/br/org/scadabr/db/utils/TestUtils.java
index 7da49f533a..1818966727 100644
--- a/test/br/org/scadabr/db/utils/TestUtils.java
+++ b/test/br/org/scadabr/db/utils/TestUtils.java
@@ -6,6 +6,7 @@
import com.serotonin.mango.vo.DataPointVO;
import com.serotonin.mango.vo.User;
import com.serotonin.mango.vo.dataSource.DataSourceVO;
+import com.serotonin.mango.vo.dataSource.PointLocatorVO;
import com.serotonin.mango.vo.dataSource.virtual.VirtualDataSourceVO;
import com.serotonin.mango.vo.dataSource.virtual.VirtualPointLocatorVO;
import com.serotonin.mango.vo.permission.DataPointAccess;
@@ -59,8 +60,8 @@ public static User createUser() {
user.setHomeUrl("url");
user.setReceiveAlarmEmails(1);
user.setReceiveOwnAuditEvents(true);
- user.setDataSourcePermissions(new ArrayList());
- user.setDataPointPermissions(new ArrayList());
+ user.setDataSourcePermissions(new ArrayList<>());
+ user.setDataPointPermissions(new ArrayList<>());
new UserDao().saveUser(user);
return user;
@@ -78,8 +79,8 @@ public static User newUser(int id) {
user.setHomeUrl("url");
user.setReceiveAlarmEmails(1);
user.setReceiveOwnAuditEvents(true);
- user.setDataSourcePermissions(new ArrayList());
- user.setDataPointPermissions(new ArrayList());
+ user.setDataSourcePermissions(new ArrayList<>());
+ user.setDataPointPermissions(new ArrayList<>());
return user;
}
@@ -96,6 +97,7 @@ public static DataPointVO newPointSettable(int id, int folderId) {
VirtualPointLocatorVO pointLocatorVO = new VirtualPointLocatorVO();
pointLocatorVO.setSettable(true);
dataPoint1.setPointLocator(pointLocatorVO);
+ dataPoint1.setEventDetectors(new ArrayList<>());
return dataPoint1;
}
@@ -112,6 +114,23 @@ public static DataPointVO newPointSettable(int id, DataSourceVO> dataSource, i
VirtualPointLocatorVO pointLocatorVO = new VirtualPointLocatorVO();
pointLocatorVO.setSettable(true);
dataPoint1.setPointLocator(pointLocatorVO);
+ dataPoint1.setEventDetectors(new ArrayList<>());
+ return dataPoint1;
+ }
+
+ public static DataPointVO newPointSettable(int id, DataSourceVO> dataSource,
+ int folderId, PointLocatorVO metaPointLocatorVO) {
+ DataPointVO dataPoint1 = new DataPointVO(DataPointVO.LoggingTypes.ON_CHANGE);
+ dataPoint1.setId(id);
+ dataPoint1.setXid("DP_" + id);
+ dataPoint1.setName("dp_" + id);
+ dataPoint1.setDataSourceId(dataSource.getId());
+ dataPoint1.setDataSourceName(dataSource.getName());
+ dataPoint1.setDataSourceTypeId(dataSource.getType().getId());
+ dataPoint1.setDataSourceXid(dataSource.getXid());
+ dataPoint1.setPointFolderId(folderId);
+ dataPoint1.setPointLocator(metaPointLocatorVO);
+ dataPoint1.setEventDetectors(new ArrayList<>());
return dataPoint1;
}
@@ -128,6 +147,7 @@ public static DataPointVO newPointNonSettable(int id, DataSourceVO> dataSource
VirtualPointLocatorVO pointLocatorVO = new VirtualPointLocatorVO();
pointLocatorVO.setSettable(false);
dataPoint1.setPointLocator(pointLocatorVO);
+ dataPoint1.setEventDetectors(new ArrayList<>());
return dataPoint1;
}
diff --git a/test/br/org/scadabr/view/component/GenerateAlarmListComponentTest.java b/test/br/org/scadabr/view/component/GenerateAlarmListComponentTest.java
index bd86f3e548..1cc59623fb 100644
--- a/test/br/org/scadabr/view/component/GenerateAlarmListComponentTest.java
+++ b/test/br/org/scadabr/view/component/GenerateAlarmListComponentTest.java
@@ -77,10 +77,7 @@ public void when_generateContent_with_eventsSubList_after_modifying_events_and_i
CopyOnWriteArrayList events = new CopyOnWriteArrayList<>();
when(eventService.getPendingEvents(anyInt())).thenReturn(events);
- HashMap model = new HashMap<>();
- whenNew(HashMap.class).withNoArguments().thenReturn(model);
-
- when(BaseDwr.generateContent(any(), any(), eq(model)))
+ when(BaseDwr.generateContent(any(), anyString(), anyMap()))
.thenAnswer(invocation -> {
Map modelArgs = (Map)invocation.getArguments()[2];
List eventsSubList = (List)modelArgs.get("events");
diff --git a/test/com/serotonin/mango/rt/dataSource/DataPointUnreliableUtilsTest.java b/test/com/serotonin/mango/rt/dataSource/DataPointUnreliableUtilsTest.java
new file mode 100644
index 0000000000..167ebcd17a
--- /dev/null
+++ b/test/com/serotonin/mango/rt/dataSource/DataPointUnreliableUtilsTest.java
@@ -0,0 +1,526 @@
+package com.serotonin.mango.rt.dataSource;
+
+import br.org.scadabr.db.utils.TestUtils;
+import com.serotonin.db.IntValuePair;
+import com.serotonin.mango.Common;
+import com.serotonin.mango.db.dao.DataPointDao;
+import com.serotonin.mango.db.dao.PointValueDao;
+import com.serotonin.mango.rt.EventManager;
+import com.serotonin.mango.rt.RuntimeManager;
+import com.serotonin.mango.rt.dataImage.DataPointRT;
+import com.serotonin.mango.rt.dataImage.PointValueCache;
+import com.serotonin.mango.vo.DataPointVO;
+import com.serotonin.mango.vo.TimePeriodType;
+import com.serotonin.mango.vo.dataSource.meta.MetaDataSourceVO;
+import com.serotonin.mango.vo.dataSource.meta.MetaPointLocatorVO;
+import com.serotonin.mango.vo.dataSource.virtual.VirtualDataSourceVO;
+import com.serotonin.mango.vo.dataSource.virtual.VirtualPointLocatorVO;
+import com.serotonin.mango.web.dwr.MiscDwr;
+import com.serotonin.web.content.ContentGenerator;
+import org.directwebremoting.WebContextFactory;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.scada_lts.dao.SystemSettingsDAO;
+import org.scada_lts.web.beans.ApplicationBeans;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.*;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.resetUnreliableDataPoints;
+import static com.serotonin.mango.util.InitializeDataSourceRtMockUtils.resetUnreliable;
+import static com.serotonin.mango.util.InitializeDataSourceRtMockUtils.setUnreliable;
+import static org.mockito.Mockito.mock;
+import static utils.mock.RuntimeMockUtils.runtimeManagerMock;
+
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({WebContextFactory.class, Common.class, MiscDwr.class, SystemSettingsDAO.class,
+ ContentGenerator.class, PointValueCache.class, DataPointRT.class, RuntimeManager.class, DataPointDao.class,
+ PointValueDao.class, ApplicationBeans.class, PollingDataSource.class})
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*",
+ "javax.activation.*", "javax.management.*"})
+public class DataPointUnreliableUtilsTest {
+
+ private RuntimeManager runtimeManager;
+
+ private DataPointVO metaDataPoint1;
+ private DataPointVO metaDataPoint2;
+
+ private DataPointVO metaDataPoint6WithVirtualDataPoint1;
+ private DataPointVO metaDataPoint7WithVirtualDataPoint1;
+ private DataPointVO metaDataPoint8;
+ private DataPointVO metaDataPoint9WithVirtualDataPoint2;
+ private DataPointVO metaDataPoint10WithVirtualDataPoint1;
+
+ private DataPointVO virtualDataPoint1;
+ private DataPointVO virtualDataPoint2;
+
+ private MetaDataSourceVO metaDataSourceVO1;
+ private MetaDataSourceVO metaDataSourceVO2;
+ private VirtualDataSourceVO virtualDataSourceVO;
+
+ private final List metaDataPoints = new ArrayList<>();
+ private final List metaDataPointsWithContext = new ArrayList<>();
+ private final List virtualDataPoints = new ArrayList<>();
+
+
+ @Before
+ public void configMock() throws Exception {
+
+ runtimeManagerMock(this.runtimeManager = new RuntimeManager(), mock(EventManager.class));
+
+ configData();
+ }
+
+ private void configData() {
+
+ metaDataSourceVO1 = new MetaDataSourceVO();
+ metaDataSourceVO1.setId(123);
+ metaDataSourceVO1.setEnabled(true);
+ metaDataSourceVO1.setXid("TEST_DS_XID1");
+ metaDataSourceVO1.setName("Meta_Test1");
+
+ metaDataSourceVO2 = new MetaDataSourceVO();
+ metaDataSourceVO2.setId(345);
+ metaDataSourceVO2.setEnabled(true);
+ metaDataSourceVO2.setXid("TEST_DS_XID2");
+ metaDataSourceVO2.setName("Meta_Test2");
+
+ virtualDataSourceVO = new VirtualDataSourceVO();
+ virtualDataSourceVO.setEnabled(true);
+ virtualDataSourceVO.setId(567);
+ virtualDataSourceVO.setXid("TEST_DS_XID3");
+ virtualDataSourceVO.setName("Virtual_Test");
+ virtualDataSourceVO.setUpdatePeriods(1);
+ virtualDataSourceVO.setUpdatePeriodType(TimePeriodType.SECONDS.getCode());
+
+
+ metaDataPoint1 = TestUtils.newPointSettable(111, metaDataSourceVO1, -1, new MetaPointLocatorVO());
+ metaDataPoint1.setEnabled(true);
+
+ metaDataPoint2 = TestUtils.newPointSettable(112, metaDataSourceVO1, -1, new MetaPointLocatorVO());
+ metaDataPoint2.setEnabled(true);
+
+ MetaPointLocatorVO metaPointLocatorVO1 = new MetaPointLocatorVO();
+ metaPointLocatorVO1.setContext(Arrays.asList(new IntValuePair(117,""), new IntValuePair(121,"")));
+ metaDataPoint6WithVirtualDataPoint1 = TestUtils.newPointSettable(116, metaDataSourceVO2, -1, metaPointLocatorVO1);
+ metaDataPoint6WithVirtualDataPoint1.setEnabled(true);
+
+ MetaPointLocatorVO metaPointLocatorVO2 = new MetaPointLocatorVO();
+ metaPointLocatorVO2.setContext(Arrays.asList(new IntValuePair(118,""), new IntValuePair(121,"")));
+ metaDataPoint7WithVirtualDataPoint1 = TestUtils.newPointSettable(117, metaDataSourceVO2, -1, metaPointLocatorVO2);
+ metaDataPoint7WithVirtualDataPoint1.setEnabled(true);
+
+ MetaPointLocatorVO metaPointLocatorVO3 = new MetaPointLocatorVO();
+ metaPointLocatorVO3.setContext(Arrays.asList(new IntValuePair(119,"")));
+ metaDataPoint8 = TestUtils.newPointSettable(118, metaDataSourceVO2, -1, metaPointLocatorVO3);
+ metaDataPoint8.setEnabled(true);
+
+ MetaPointLocatorVO metaPointLocatorVO4 = new MetaPointLocatorVO();
+ metaPointLocatorVO4.setContext(Arrays.asList(new IntValuePair(120,""), new IntValuePair(122,"")));
+ metaDataPoint9WithVirtualDataPoint2 = TestUtils.newPointSettable(119, metaDataSourceVO2, -1, metaPointLocatorVO4);
+ metaDataPoint9WithVirtualDataPoint2.setEnabled(true);
+
+ MetaPointLocatorVO metaPointLocatorVO5 = new MetaPointLocatorVO();
+ metaPointLocatorVO5.setContext(Arrays.asList(new IntValuePair(118,""), new IntValuePair(121,"")));
+ metaDataPoint10WithVirtualDataPoint1 = TestUtils.newPointSettable(120, metaDataSourceVO2, -1, metaPointLocatorVO5);
+ metaDataPoint10WithVirtualDataPoint1.setEnabled(true);
+
+ virtualDataPoint1 = TestUtils.newPointSettable(121, virtualDataSourceVO, -1, new VirtualPointLocatorVO());
+ virtualDataPoint1.setEnabled(true);
+
+ virtualDataPoint2 = TestUtils.newPointSettable(122, virtualDataSourceVO, -1, new VirtualPointLocatorVO());
+ virtualDataPoint2.setEnabled(true);
+
+
+ runtimeManager.saveDataSource(metaDataSourceVO1);
+ runtimeManager.saveDataPoint(metaDataPoint1);
+ runtimeManager.saveDataPoint(metaDataPoint2);
+
+ runtimeManager.saveDataSource(metaDataSourceVO2);
+ runtimeManager.saveDataPoint(metaDataPoint8);
+ runtimeManager.saveDataPoint(metaDataPoint6WithVirtualDataPoint1);
+ runtimeManager.saveDataPoint(metaDataPoint7WithVirtualDataPoint1);
+ runtimeManager.saveDataPoint(metaDataPoint9WithVirtualDataPoint2);
+ runtimeManager.saveDataPoint(metaDataPoint10WithVirtualDataPoint1);
+
+ runtimeManager.saveDataSource(virtualDataSourceVO);
+ runtimeManager.saveDataPoint(virtualDataPoint1);
+ runtimeManager.saveDataPoint(virtualDataPoint2);
+
+
+ virtualDataPoints.add(runtimeManager.getDataPoint(virtualDataPoint1.getId()));
+ virtualDataPoints.add(runtimeManager.getDataPoint(virtualDataPoint2.getId()));
+
+ metaDataPoints.add(runtimeManager.getDataPoint(metaDataPoint1.getId()));
+ metaDataPoints.add(runtimeManager.getDataPoint(metaDataPoint2.getId()));
+
+ metaDataPointsWithContext.add(runtimeManager.getDataPoint(metaDataPoint6WithVirtualDataPoint1.getId()));
+ metaDataPointsWithContext.add(runtimeManager.getDataPoint(metaDataPoint7WithVirtualDataPoint1.getId()));
+ metaDataPointsWithContext.add(runtimeManager.getDataPoint(metaDataPoint8.getId()));
+ metaDataPointsWithContext.add(runtimeManager.getDataPoint(metaDataPoint9WithVirtualDataPoint2.getId()));
+ metaDataPointsWithContext.add(runtimeManager.getDataPoint(metaDataPoint10WithVirtualDataPoint1.getId()));
+
+ }
+
+ @Test
+ public void when_setUnreliableDataPoints_with_virtual_points_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+
+ //when:
+ setUnreliableDataPoints(virtualDataPoints);
+
+ //then:
+ for(DataPointRT dataPoint: virtualDataPoints) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoints_with_meta_points_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+
+ //when:
+ setUnreliableDataPoints(metaDataPoints);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPoints) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoints_with_meta_points_with_context_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+
+ //when:
+ setUnreliableDataPoints(metaDataPointsWithContext);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPointsWithContext) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_getRunningDataSource_virtual_data_source_then_initialized_true() {
+
+ //when:
+ DataSourceRT dataSourceRT = runtimeManager.getRunningDataSource(virtualDataSourceVO.getId());
+
+ //then:
+ Assert.assertEquals(true, dataSourceRT.isInitialized());
+
+ }
+
+ @Test
+ public void when_getRunningDataSource_meta_data_source_then_initialized_true() {
+
+ //when:
+ DataSourceRT dataSourceRT = runtimeManager.getRunningDataSource(metaDataSourceVO1.getId());
+
+ //then:
+ Assert.assertEquals(true, dataSourceRT.isInitialized());
+
+ }
+
+ @Test
+ public void when_getRunningDataSource_meta_data_source_with_context_then_initialized_true() {
+
+ //when:
+ DataSourceRT dataSourceRT = runtimeManager.getRunningDataSource(metaDataSourceVO2.getId());
+
+ //then:
+ Assert.assertEquals(true, dataSourceRT.isInitialized());
+
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_virtual_point_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(virtualDataPoint1.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(true, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_meta_point_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint1.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(true, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_meta_point_with_context_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint6WithVirtualDataPoint1.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(true, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_setUnreliableDataPoints_with_virtual_points_then_meta_points_unreliable_false() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+
+ //when:
+ setUnreliableDataPoints(virtualDataPoints);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPoints) {
+ Assert.assertEquals(false, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoints_with_virtual_points_from_meta_points_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+
+ //when:
+ setUnreliableDataPoints(virtualDataPoints);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPointsWithContext) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_meta_point_from_context_meta_points_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint10WithVirtualDataPoint1.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPointsWithContext) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_meta_point_from_context_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint10WithVirtualDataPoint1.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ for(DataPointRT dataPoint: runtimeManager.getRunningMetaDataPoints(dataPointRT.getId())) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoints_with_virtual_points_from_context_meta_points_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+
+ //when:
+ setUnreliableDataPoints(virtualDataPoints);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPointsWithContext) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_virtual_point_from_context_meta_points_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(virtualDataPoint1.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ for(DataPointRT dataPoint: runtimeManager.getRunningMetaDataPoints(dataPointRT.getId())) {
+ Assert.assertEquals(true, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_setUnreliableDataPoint_with_virtual_point_from_context_meta_point_then_unreliable_true() {
+
+ //given:
+ resetUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(virtualDataPoint2.getId());
+ DataPointRT metaDataPointRT = runtimeManager.getDataPoint(metaDataPoint9WithVirtualDataPoint2.getId());
+
+ //when:
+ setUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(true, metaDataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoint_with_virtual_point_then_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(virtualDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(false, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoint_with_meta_point_then_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(false, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoint_with_meta_point_with_context_then_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint6WithVirtualDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(false, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoint_with_meta_point_from_context_meta_point_then_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint10WithVirtualDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ for(DataPointRT dataPoint: metaDataPointsWithContext) {
+ Assert.assertEquals(false, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoints_with_meta_point_then_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(false, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoints_with_meta_points_then_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(metaDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoints(metaDataPoints);
+
+ //then:
+ Assert.assertEquals(false, dataPointRT.isUnreliable());
+
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoints_with_virtual_point_from_context_meta_point_then_meta_points_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(virtualDataPoint1.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ for(DataPointRT dataPoint: runtimeManager.getRunningMetaDataPoints(dataPointRT.getId())) {
+ Assert.assertEquals(false, dataPoint.isUnreliable());
+ }
+ }
+
+ @Test
+ public void when_resetUnreliableDataPoints_with_virtual_point_from_context_meta_point_then_meta_point_unreliable_false() {
+
+ //given:
+ setUnreliable(virtualDataPoints, metaDataPoints, metaDataPointsWithContext);
+ DataPointRT dataPointRT = runtimeManager.getDataPoint(virtualDataPoint2.getId());
+ DataPointRT metaDataPointRT = runtimeManager.getDataPoint(metaDataPoint9WithVirtualDataPoint2.getId());
+
+ //when:
+ resetUnreliableDataPoint(dataPointRT);
+
+ //then:
+ Assert.assertEquals(false, metaDataPointRT.isUnreliable());
+
+ }
+}
\ No newline at end of file
diff --git a/test/com/serotonin/mango/rt/dataSource/InitializeDataSourceRtTest.java b/test/com/serotonin/mango/rt/dataSource/InitializeDataSourceRtTest.java
new file mode 100644
index 0000000000..1c004ab372
--- /dev/null
+++ b/test/com/serotonin/mango/rt/dataSource/InitializeDataSourceRtTest.java
@@ -0,0 +1,244 @@
+package com.serotonin.mango.rt.dataSource;
+
+import br.org.scadabr.rt.dataSource.alpha2.Alpha2DataSource;
+import br.org.scadabr.rt.dataSource.asciiFile.ASCIIFileDataSource;
+import br.org.scadabr.rt.dataSource.asciiSerial.ASCIISerialDataSource;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3IpDataSource;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3SerialDataSource;
+import br.org.scadabr.rt.dataSource.drStorageHt5b.DrStorageHt5bDataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101EthernetDataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101SerialDataSource;
+import br.org.scadabr.rt.dataSource.nodaves7.NodaveS7DataSource;
+import br.org.scadabr.rt.dataSource.opc.OPCDataSource;
+import br.org.scadabr.vo.dataSource.asciiFile.ASCIIFileDataSourceVO;
+import br.org.scadabr.vo.dataSource.nodaves7.NodaveS7DataSourceVO;
+import cc.radiuino.scadabr.rt.datasource.radiuino.RadiuinoEventDataSource;
+import cc.radiuino.scadabr.rt.datasource.radiuino.RadiuinoPollingDataSource;
+import com.i2msolucoes.alpha24j.layer.user.Alpha2Master;
+import com.serotonin.mango.Common;
+import com.serotonin.mango.rt.EventManager;
+import com.serotonin.mango.rt.dataSource.bacnet.BACnetIPDataSourceRT;
+import com.serotonin.mango.rt.dataSource.ebro.EBI25Constants;
+import com.serotonin.mango.rt.dataSource.ebro.EBI25DataSourceRT;
+import com.serotonin.mango.rt.dataSource.galil.GalilDataSourceRT;
+import com.serotonin.mango.rt.dataSource.http.*;
+import com.serotonin.mango.rt.dataSource.internal.InternalDataSourceRT;
+import com.serotonin.mango.rt.dataSource.jmx.JmxDataSourceRT;
+import com.serotonin.mango.rt.dataSource.mbus.MBusDataSourceRT;
+import com.serotonin.mango.rt.dataSource.meta.MetaDataSourceRT;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusIpDataSource;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusSerialDataSource;
+import com.serotonin.mango.rt.dataSource.nmea.NmeaDataSourceRT;
+import com.serotonin.mango.rt.dataSource.onewire.OneWireDataSourceRT;
+import com.serotonin.mango.rt.dataSource.openv4j.OpenV4JDataSourceRT;
+import com.serotonin.mango.rt.dataSource.pachube.PachubeDataSourceRT;
+import com.serotonin.mango.rt.dataSource.persistent.PersistentDataSourceRT;
+import com.serotonin.mango.rt.dataSource.pop3.Pop3DataSourceRT;
+import com.serotonin.mango.rt.dataSource.snmp.SnmpDataSourceRT;
+import com.serotonin.mango.rt.dataSource.sql.SqlDataSourceRT;
+import com.serotonin.mango.rt.dataSource.viconics.ViconicsDataSourceRT;
+import com.serotonin.mango.rt.dataSource.virtual.VirtualDataSourceRT;
+import com.serotonin.mango.rt.dataSource.vmstat.VMStatDataSourceRT;
+import com.serotonin.mango.util.InitializeDataSourceRtMockUtils;
+import com.serotonin.mango.util.SqlDataSourceUtils;
+import com.serotonin.mango.util.timeout.TimeoutTask;
+import com.serotonin.mango.vo.dataSource.http.HttpImageDataSourceVO;
+import com.serotonin.mango.vo.dataSource.http.HttpRetrieverDataSourceVO;
+import com.serotonin.mango.vo.dataSource.internal.InternalDataSourceVO;
+import com.serotonin.mango.vo.dataSource.jmx.JmxDataSourceVO;
+import com.serotonin.mango.vo.dataSource.mbus.MBusDataSourceVO;
+import com.serotonin.mango.vo.dataSource.meta.MetaDataSourceVO;
+import com.serotonin.mango.vo.dataSource.openv4j.OpenV4JDataSourceVO;
+import com.serotonin.mango.vo.dataSource.persistent.PersistentDataSourceVO;
+import com.serotonin.mango.vo.dataSource.pop3.Pop3DataSourceVO;
+import com.serotonin.mango.vo.dataSource.virtual.VirtualDataSourceVO;
+import com.serotonin.mango.vo.dataSource.vmstat.VMStatDataSourceVO;
+import com.serotonin.mango.web.ContextWrapper;
+import com.serotonin.modbus4j.ModbusFactory;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.scada_lts.ds.messaging.protocol.amqp.AmqpDataSourceVO;
+import org.scada_lts.ds.messaging.protocol.mqtt.MqttDataSourceVO;
+import org.scada_lts.serial.gnu.io.ScadaCommPortIdentifier;
+
+import org.springframework.security.web.savedrequest.Enumerator;
+
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.function.Supplier;
+
+import static com.serotonin.mango.util.InitializeDataSourceRtMockUtils.supplier;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.whenNew;
+
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(Parameterized.class)
+@PrepareForTest({Common.class, ASCIISerialDataSource.class, ScadaCommPortIdentifier.class, Alpha2DataSource.class,
+ Alpha2Master.class, BACnetIPDataSourceRT.class, Dnp3IpDataSource.class, Dnp3SerialDataSource.class,
+ EBI25DataSourceRT.class, EBI25Constants.class, NmeaDataSourceRT.class, Runtime.class, VMStatDataSourceRT.class,
+ ViconicsDataSourceRT.class, GalilDataSourceRT.class, IEC101EthernetDataSource.class, IEC101SerialDataSource.class,
+ ModbusFactory.class, OPCDataSource.class, OneWireDataSourceRT.class, SqlDataSourceUtils.class, PollingDataSource.class})
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*",
+ "javax.activation.*", "javax.management.*"})
+public class InitializeDataSourceRtTest {
+
+ @Parameterized.Parameters(name = "{index}: data source: {0}, raiseEventTimes: {2}, returnToNormalTimes: {3}")
+ public static Object[][] data() throws Exception {
+
+ return new Object[][] {
+
+ {ASCIISerialDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createAsciiSerial), 1, 0},
+ {Alpha2DataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createAlpha2), 1, 0},
+ {BACnetIPDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createBacNet), 3, 0},
+ {Dnp3IpDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createDnp3Ip), 1, 0},
+ {Dnp3SerialDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createDnp3Serial), 1, 0},
+ {DrStorageHt5bDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createDrStorageMock), 1, 0},
+ {EBI25DataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createEbi25), 1, 0},
+ {NmeaDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createNmea), 1, 0},
+ {RadiuinoEventDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createRadiuino), 1, 0},
+ {RadiuinoPollingDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createRadiuinoPolling), 1, 0},
+ {VMStatDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtTest::createVmStat), 1, 0},
+ {ViconicsDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createViconics), 1, 0},
+ {GalilDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createGalil), 1, 0},
+ {IEC101EthernetDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createIec101Ethernet), 1, 0},
+ {IEC101SerialDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createIec101Serial), 1, 0},
+ {AmqpDataSourceVO.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createAmqp), 1, 0},
+ {MqttDataSourceVO.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createMqtt), 1, 0},
+ {ModbusIpDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createModbusIpDataSource), 1, 0},
+ {ModbusSerialDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createModbusSerialDataSource), 1, 0},
+ {OPCDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createOpc), 1, 0},
+ {OneWireDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createOneWire), 1, 0},
+ {SqlDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createSql), 1, 0},
+ {HttpReceiverDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createSql), 1, 0},
+ {PachubeDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createPachube), 1, 0},
+ {SnmpDataSourceRT.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createSnmp), 1, 0},
+ {PersistentDataSourceRT.class.getSimpleName(), supplier(() -> new PersistentDataSourceRT(new PersistentDataSourceVO())), 1, 0},
+ {ModbusIpDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createModbusIpDataSource), 1, 0},
+ {ModbusSerialDataSource.class.getSimpleName(), supplier(InitializeDataSourceRtMockUtils::createModbusSerialDataSource), 1, 0},
+
+
+ {VirtualDataSourceRT.class.getSimpleName(), supplier(() -> new VirtualDataSourceRT(new VirtualDataSourceVO())), 0, 0},
+ {ASCIIFileDataSource.class.getSimpleName(), supplier(() -> new ASCIIFileDataSource(new ASCIIFileDataSourceVO<>())), 0, 0},
+ {HttpImageDataSourceRT.class.getSimpleName(), supplier(() -> new HttpImageDataSourceRT(new HttpImageDataSourceVO())), 0, 0},
+ {HttpRetrieverDataSourceRT.class.getSimpleName(), supplier(() -> new HttpRetrieverDataSourceRT(new HttpRetrieverDataSourceVO())), 0, 0},
+ {InternalDataSourceRT.class.getSimpleName(), supplier(() -> new InternalDataSourceRT(new InternalDataSourceVO())), 0, 0},
+ {JmxDataSourceRT.class.getSimpleName(), supplier(() -> new JmxDataSourceRT(new JmxDataSourceVO())), 0, 0},
+ {MBusDataSourceRT.class.getSimpleName(), supplier(() -> new MBusDataSourceRT(new MBusDataSourceVO())), 0, 0},
+ {MetaDataSourceRT.class.getSimpleName(), supplier(() -> new MetaDataSourceRT(new MetaDataSourceVO())), 0, 0},
+ {NodaveS7DataSource.class.getSimpleName(), supplier(() -> new NodaveS7DataSource(new NodaveS7DataSourceVO<>())), 0, 0},
+ {OpenV4JDataSourceRT.class.getSimpleName(), supplier(() -> new OpenV4JDataSourceRT(new OpenV4JDataSourceVO())), 0, 0},
+ {Pop3DataSourceRT.class.getSimpleName(), supplier(() -> new Pop3DataSourceRT(new Pop3DataSourceVO())), 0, 0},
+
+ };
+ }
+
+ private DataSourceRT dataSourceRT;
+ private final int raiseEventTimes;
+ private final int returnToNormalTimes;
+ private final Supplier mockConfig;
+
+ public InitializeDataSourceRtTest(String name, Supplier mockConfig, int returnToNormalTimes, int raiseEventTimes) {
+ this.raiseEventTimes = raiseEventTimes;
+ this.returnToNormalTimes = returnToNormalTimes;
+ this.mockConfig = mockConfig;
+ }
+
+ private EventManager eventManager;
+
+ @Before
+ public void config() {
+ eventManager = mock(EventManager.class);
+ HttpReceiverMulticaster multicastListener = mock(HttpReceiverMulticaster.class);
+
+ ContextWrapper contextWrapper = mock(ContextWrapper.class);
+ when(contextWrapper.getEventManager()).thenReturn(eventManager);
+ when(contextWrapper.getHttpReceiverMulticaster()).thenReturn(multicastListener);
+
+ Common.ctx = contextWrapper;
+
+ PowerMockito.mockStatic(ScadaCommPortIdentifier.class);
+ when(ScadaCommPortIdentifier.getPortIdentifiers()).thenReturn(new Enumerator(new ArrayList()));
+
+ dataSourceRT = mockConfig.get();
+ reset(eventManager);
+ }
+
+ @After
+ public void clean() {
+ dataSourceRT.terminate();
+ reset(eventManager);
+ }
+
+ @Test
+ public void when_invoke_initialize_then_initialized() {
+
+ //when:
+ dataSourceRT.initialize();
+
+ //then:
+ Assert.assertEquals(true, dataSourceRT.isInitialized());
+ }
+
+
+ @Test
+ public void when_never_invoke_initialize_then_not_initialized() {
+
+ //then:
+ Assert.assertEquals(false, dataSourceRT.isInitialized());
+ }
+
+ @Test
+ public void when_invoke_initialize_then_invoke_returnToNormal_times() {
+
+ //when:
+ dataSourceRT.initialize();
+
+ //then:
+ Mockito.verify(eventManager, times(returnToNormalTimes)).returnToNormal(any(), anyLong());
+ }
+
+ @Test
+ public void when_invoke_initialize_with_errors_then_invoke_raiseEvent_times() {
+
+ //when:
+ dataSourceRT.initialize();
+
+ //then:
+ Mockito.verify(eventManager, times(raiseEventTimes)).raiseEvent(any(), anyLong(), anyBoolean(), anyInt(), any(), anyMap());
+ }
+
+ public static DataSourceRT createVmStat() {
+ InputStream inputStreamMock = mock(InputStream.class);
+ Process processMock = mock(Process.class);
+ when(processMock.getInputStream()).thenReturn(inputStreamMock);
+
+ java.lang.Runtime runtimeMock = mock(Runtime.class);
+ try {
+ when(runtimeMock.exec(anyString())).thenReturn(processMock);
+ PowerMockito.mockStatic(java.lang.Runtime.class);
+ when(java.lang.Runtime.getRuntime()).thenReturn(runtimeMock);
+
+ BufferedReader bufferedReader = mock(BufferedReader.class);
+ when(bufferedReader.readLine()).thenReturn("abc");
+ PowerMockito.whenNew(BufferedReader.class).withAnyArguments()
+ .thenReturn(bufferedReader);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return new VMStatDataSourceRT(new VMStatDataSourceVO());
+ }
+}
diff --git a/test/com/serotonin/mango/rt/dataSource/InitializeDataSourceRtTestsSuite.java b/test/com/serotonin/mango/rt/dataSource/InitializeDataSourceRtTestsSuite.java
new file mode 100644
index 0000000000..fb1f98a238
--- /dev/null
+++ b/test/com/serotonin/mango/rt/dataSource/InitializeDataSourceRtTestsSuite.java
@@ -0,0 +1,12 @@
+package com.serotonin.mango.rt.dataSource;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({
+ InitializeDataSourceRtTest.class,
+ //InitializeWithErrorsDataSourceRtTest.class
+})
+public class InitializeDataSourceRtTestsSuite {
+}
diff --git a/test/com/serotonin/mango/rt/dataSource/InitializeWithErrorsDataSourceRtTest.java b/test/com/serotonin/mango/rt/dataSource/InitializeWithErrorsDataSourceRtTest.java
new file mode 100644
index 0000000000..085e3130bc
--- /dev/null
+++ b/test/com/serotonin/mango/rt/dataSource/InitializeWithErrorsDataSourceRtTest.java
@@ -0,0 +1,243 @@
+package com.serotonin.mango.rt.dataSource;
+
+import br.org.scadabr.rt.dataSource.alpha2.Alpha2DataSource;
+import br.org.scadabr.rt.dataSource.asciiSerial.ASCIISerialDataSource;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3IpDataSource;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3SerialDataSource;
+import br.org.scadabr.rt.dataSource.drStorageHt5b.DrStorageHt5bDataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101EthernetDataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101SerialDataSource;
+import br.org.scadabr.rt.dataSource.opc.OPCDataSource;
+import br.org.scadabr.vo.dataSource.alpha2.Alpha2DataSourceVO;
+import br.org.scadabr.vo.dataSource.asciiSerial.ASCIISerialDataSourceVO;
+import br.org.scadabr.vo.dataSource.dnp3.Dnp3IpDataSourceVO;
+import br.org.scadabr.vo.dataSource.dnp3.Dnp3SerialDataSourceVO;
+import br.org.scadabr.vo.dataSource.drStorageHt5b.DrStorageHt5bDataSourceVO;
+import br.org.scadabr.vo.dataSource.iec101.IEC101EthernetDataSourceVO;
+import br.org.scadabr.vo.dataSource.iec101.IEC101SerialDataSourceVO;
+import br.org.scadabr.vo.dataSource.opc.OPCDataSourceVO;
+import cc.radiuino.scadabr.rt.datasource.radiuino.RadiuinoEventDataSource;
+import cc.radiuino.scadabr.rt.datasource.radiuino.RadiuinoPollingDataSource;
+import cc.radiuino.scadabr.vo.datasource.radiuino.RadiuinoDataSourceVO;
+import com.serotonin.mango.Common;
+import com.serotonin.mango.rt.EventManager;
+import com.serotonin.mango.rt.dataSource.bacnet.BACnetIPDataSourceRT;
+import com.serotonin.mango.rt.dataSource.ebro.EBI25DataSourceRT;
+import com.serotonin.mango.rt.dataSource.galil.GalilDataSourceRT;
+import com.serotonin.mango.rt.dataSource.http.HttpReceiverDataSourceRT;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusIpDataSource;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusSerialDataSource;
+import com.serotonin.mango.rt.dataSource.nmea.NmeaDataSourceRT;
+import com.serotonin.mango.rt.dataSource.onewire.OneWireDataSourceRT;
+import com.serotonin.mango.rt.dataSource.pachube.PachubeDataSourceRT;
+import com.serotonin.mango.rt.dataSource.persistent.PersistentDataSourceRT;
+import com.serotonin.mango.rt.dataSource.snmp.SnmpDataSourceRT;
+import com.serotonin.mango.rt.dataSource.sql.SqlDataSourceRT;
+import com.serotonin.mango.rt.dataSource.viconics.ViconicsDataSourceRT;
+import com.serotonin.mango.rt.dataSource.vmstat.VMStatDataSourceRT;
+import com.serotonin.mango.util.timeout.TimeoutTask;
+import com.serotonin.mango.vo.dataSource.bacnet.BACnetIPDataSourceVO;
+import com.serotonin.mango.vo.dataSource.ebro.EBI25DataSourceVO;
+import com.serotonin.mango.vo.dataSource.galil.GalilDataSourceVO;
+import com.serotonin.mango.vo.dataSource.http.HttpReceiverDataSourceVO;
+import com.serotonin.mango.vo.dataSource.modbus.ModbusIpDataSourceVO;
+import com.serotonin.mango.vo.dataSource.modbus.ModbusSerialDataSourceVO;
+import com.serotonin.mango.vo.dataSource.nmea.NmeaDataSourceVO;
+import com.serotonin.mango.vo.dataSource.onewire.OneWireDataSourceVO;
+import com.serotonin.mango.vo.dataSource.pachube.PachubeDataSourceVO;
+import com.serotonin.mango.vo.dataSource.persistent.PersistentDataSourceVO;
+import com.serotonin.mango.vo.dataSource.snmp.SnmpDataSourceVO;
+import com.serotonin.mango.vo.dataSource.sql.SqlDataSourceVO;
+import com.serotonin.mango.vo.dataSource.viconics.ViconicsDataSourceVO;
+import com.serotonin.mango.vo.dataSource.vmstat.VMStatDataSourceVO;
+import com.serotonin.mango.web.ContextWrapper;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.mockito.Mockito;
+import org.powermock.api.mockito.PowerMockito;
+import org.powermock.core.classloader.annotations.PowerMockIgnore;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+import org.powermock.modules.junit4.PowerMockRunnerDelegate;
+import org.scada_lts.ds.messaging.MessagingDataSourceRT;
+import org.scada_lts.ds.messaging.exception.MessagingServiceException;
+import org.scada_lts.ds.messaging.protocol.amqp.AmqpDataSourceVO;
+import org.scada_lts.ds.messaging.protocol.mqtt.MqttDataSourceVO;
+import org.scada_lts.ds.messaging.service.MessagingService;
+import org.scada_lts.ds.messaging.service.MessagingServiceFactory;
+import org.scada_lts.web.beans.ApplicationBeans;
+import utils.mock.MockUtils;
+
+import java.io.IOException;
+import java.util.function.Supplier;
+
+import static com.serotonin.mango.util.InitializeDataSourceRtMockUtils.supplier;
+import static org.mockito.ArgumentMatchers.*;
+import static org.mockito.Mockito.*;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.whenNew;
+
+
+@RunWith(PowerMockRunner.class)
+@PowerMockRunnerDelegate(Parameterized.class)
+@PrepareForTest({Common.class, Runtime.class, VMStatDataSourceRT.class, PollingDataSource.class, ApplicationBeans.class})
+@PowerMockIgnore({"com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*", "com.sun.org.apache.xalan.*",
+ "javax.activation.*", "javax.management.*"})
+public class InitializeWithErrorsDataSourceRtTest {
+
+ @Parameterized.Parameters(name = "{index}: data source: {1}")
+ public static Object[][] data() {
+ PersistentDataSourceVO persistentDataSourceVO = new PersistentDataSourceVO();
+ persistentDataSourceVO.setPort(-1);
+
+ ModbusIpDataSourceVO modbusIpDataSourceVO = new ModbusIpDataSourceVO();
+ modbusIpDataSourceVO.setTransportType(ModbusIpDataSourceVO.TransportType.TCP_KEEP_ALIVE);
+
+ BACnetIPDataSourceVO baCnetIPDataSourceVO = new BACnetIPDataSourceVO();
+ baCnetIPDataSourceVO.setPort(47808);
+
+ AmqpDataSourceVO amqpDataSourceVO = new AmqpDataSourceVO();
+ MqttDataSourceVO mqttDataSourceVO = new MqttDataSourceVO();
+ mqttDataSourceVO.setServerHost("localhost");
+ mqttDataSourceVO.setServerPortNumber(1234);
+
+ ModbusSerialDataSourceVO modbusSerialDataSourceVO = new ModbusSerialDataSourceVO();
+ modbusSerialDataSourceVO.setCommPortId("123");
+
+ MessagingService messageServiceMock = mock(MessagingService.class);
+ doAnswer(a -> {
+ throw new MessagingServiceException("From test");
+ }).when(messageServiceMock).open();
+
+ return new Object[][] {
+
+ {supplier(() -> new ASCIISerialDataSource(new ASCIISerialDataSourceVO<>())), ASCIISerialDataSource.class.getSimpleName()},
+ {supplier(() -> new Alpha2DataSource(new Alpha2DataSourceVO<>())), Alpha2DataSource.class.getSimpleName()},
+ {supplier(() -> new BACnetIPDataSourceRT(baCnetIPDataSourceVO)), BACnetIPDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new Dnp3IpDataSource(new Dnp3IpDataSourceVO())), Dnp3IpDataSource.class.getSimpleName()},
+ {supplier(() -> new Dnp3SerialDataSource(new Dnp3SerialDataSourceVO())), Dnp3SerialDataSource.class.getSimpleName()},
+ {supplier(() -> new DrStorageHt5bDataSource(new DrStorageHt5bDataSourceVO<>())), DrStorageHt5bDataSource.class.getSimpleName()},
+ {supplier(() -> new EBI25DataSourceRT(new EBI25DataSourceVO())), EBI25DataSourceRT.class.getSimpleName()},
+ {supplier(() -> new NmeaDataSourceRT(new NmeaDataSourceVO())), NmeaDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new RadiuinoEventDataSource(new RadiuinoDataSourceVO<>())), RadiuinoEventDataSource.class.getSimpleName()},
+ {supplier(() -> new RadiuinoPollingDataSource(new RadiuinoDataSourceVO<>())), RadiuinoPollingDataSource.class.getSimpleName()},
+ {supplier(() -> new VMStatDataSourceRT(new VMStatDataSourceVO())), VMStatDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new ViconicsDataSourceRT(new ViconicsDataSourceVO())), ViconicsDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new GalilDataSourceRT(new GalilDataSourceVO())), GalilDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new IEC101EthernetDataSource(new IEC101EthernetDataSourceVO())), IEC101EthernetDataSource.class.getSimpleName()},
+ {supplier(() -> new IEC101SerialDataSource(new IEC101SerialDataSourceVO())), IEC101SerialDataSource.class.getSimpleName()},
+ {supplier(() -> new MessagingDataSourceRT(amqpDataSourceVO, MessagingServiceFactory.newService(amqpDataSourceVO))), AmqpDataSourceVO.class.getSimpleName()},
+ {supplier(() -> new MessagingDataSourceRT(mqttDataSourceVO, messageServiceMock)), MqttDataSourceVO.class.getSimpleName()},
+
+ {supplier(() -> new ModbusSerialDataSource(new ModbusSerialDataSourceVO())), ModbusSerialDataSource.class.getSimpleName()},
+ {supplier(() -> new ModbusIpDataSource(modbusIpDataSourceVO)), ModbusIpDataSource.class.getSimpleName()},
+ {supplier(() -> new OPCDataSource(new OPCDataSourceVO<>())), OPCDataSource.class.getSimpleName()},
+ {supplier(() -> new OneWireDataSourceRT(new OneWireDataSourceVO())), OneWireDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new SqlDataSourceRT(new SqlDataSourceVO())), SqlDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new HttpReceiverDataSourceRT(new HttpReceiverDataSourceVO())), HttpReceiverDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new PachubeDataSourceRT(new PachubeDataSourceVO())), PachubeDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new SnmpDataSourceRT(new SnmpDataSourceVO())), SnmpDataSourceRT.class.getSimpleName()},
+ {supplier(() -> new PersistentDataSourceRT(persistentDataSourceVO)), PersistentDataSourceRT.class.getSimpleName()},
+
+ };
+ }
+
+ private DataSourceRT dataSourceRT;
+ private final Supplier createDataSource;
+
+ public InitializeWithErrorsDataSourceRtTest(Supplier createDataSource, String name) {
+ this.createDataSource = createDataSource;
+ }
+
+ private EventManager eventManager;
+
+ @Before
+ public void config() throws Exception {
+
+ MockUtils.configDaoMock();
+
+ eventManager = PowerMockito.mock(EventManager.class);
+
+ ContextWrapper contextWrapper = PowerMockito.mock(ContextWrapper.class);
+ PowerMockito.when(contextWrapper.getEventManager()).thenReturn(eventManager);
+
+ Common.ctx = contextWrapper;
+
+ this.dataSourceRT = this.createDataSource.get();
+
+ if(dataSourceRT instanceof BACnetIPDataSourceRT) {
+ DataSourceRT dataSourceRT1 = this.createDataSource.get();
+ dataSourceRT1.initialize();
+ }
+
+ TimeoutTask timeoutTaskMock = mock(TimeoutTask.class);
+ try {
+ whenNew(TimeoutTask.class).withAnyArguments()
+ .thenReturn(timeoutTaskMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ reset(eventManager);
+
+ if(dataSourceRT instanceof VMStatDataSourceRT) {
+ java.lang.Runtime runtimeMock = mock(Runtime.class);
+ try {
+ doAnswer(a -> {
+ throw new IOException("From test");
+ }).when(runtimeMock).exec(anyString());
+ PowerMockito.mockStatic(java.lang.Runtime.class);
+ when(java.lang.Runtime.getRuntime()).thenReturn(runtimeMock);
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @After
+ public void clean() {
+ dataSourceRT.terminate();
+ }
+
+ @Test
+ public void when_invoke_initialize_with_errors_then_not_initialized() {
+
+ //when:
+ dataSourceRT.initialize();
+
+ //then:
+ Assert.assertEquals(false, dataSourceRT.isInitialized());
+ }
+
+ @Test
+ public void when_never_invoke_initialize_then_not_initialized() {
+
+ //then:
+ Assert.assertEquals(false, dataSourceRT.isInitialized());
+ }
+
+ @Test
+ public void when_invoke_initialize_with_errors_then_one_raiseEvent() {
+
+ //when:
+ dataSourceRT.initialize();
+
+ //then:
+ Mockito.verify(eventManager, times(1)).raiseEvent(any(), anyLong(), anyBoolean(), anyInt(), any(), anyMap());
+ }
+
+ @Test
+ public void when_invoke_initialize_with_errors_then_never_returnToNormal() {
+
+ //when:
+ dataSourceRT.initialize();
+
+ //then:
+ Mockito.verify(eventManager, never()).returnToNormal(any(), anyLong());
+ }
+}
diff --git a/test/com/serotonin/mango/rt/scripting/ScriptTest.java b/test/com/serotonin/mango/rt/scripting/ScriptTest.java
index 0c661feb73..809ad9691f 100644
--- a/test/com/serotonin/mango/rt/scripting/ScriptTest.java
+++ b/test/com/serotonin/mango/rt/scripting/ScriptTest.java
@@ -135,12 +135,14 @@ public ScriptTest(MangoValue mangoValue,
this.script = script;
}
- private RuntimeManager runtimeManager = mock(RuntimeManager.class);
- private DPCommandsScriptContextObject scriptContextObject = mock(DPCommandsScriptContextObject.class);
+ private RuntimeManager runtimeManager;
+ private DPCommandsScriptContextObject scriptContextObject;
@Before
public void config() throws Exception {
- ScriptTestUtils.configMock(runtimeManager, scriptContextObject);
+ runtimeManager = mock(RuntimeManager.class);
+ scriptContextObject = mock(DPCommandsScriptContextObject.class);
+ ScriptTestUtils.configScriptMock(runtimeManager, scriptContextObject);
}
@Test
diff --git a/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataPointTest.java b/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataPointTest.java
index 92ae1e075c..d82f7e4b65 100644
--- a/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataPointTest.java
+++ b/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataPointTest.java
@@ -42,14 +42,17 @@
"javax.activation.*", "javax.management.*"})
public class ScriptWithObjectContextEnableDisableDataPointTest {
- private static String pointToChangeXid = "DP_093765";
- private final List objectContext = Arrays.asList(new IntValuePair(2, "dp"));
- private RuntimeManager runtimeManager = mock(RuntimeManager.class);
- private DPCommandsScriptContextObject scriptContextObject = mock(DPCommandsScriptContextObject.class);
+ private static final String pointToChangeXid = "DP_093765";
+ private List objectContext;
+ private RuntimeManager runtimeManager;
+ private DPCommandsScriptContextObject scriptContextObject;
@Before
public void config() throws Exception {
- ScriptTestUtils.configMock(runtimeManager, scriptContextObject);
+ objectContext = Arrays.asList(new IntValuePair(2, "dp"));
+ runtimeManager = mock(RuntimeManager.class);
+ scriptContextObject = mock(DPCommandsScriptContextObject.class);
+ ScriptTestUtils.configScriptMock(runtimeManager, scriptContextObject);
}
@After
diff --git a/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataSourceTest.java b/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataSourceTest.java
index 87c831c8ad..fb5dcad504 100644
--- a/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataSourceTest.java
+++ b/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextEnableDisableDataSourceTest.java
@@ -39,16 +39,19 @@
"javax.activation.*", "javax.management.*"})
public class ScriptWithObjectContextEnableDisableDataSourceTest {
- private static String sourceToChangeXid = "DP_093765";
+ private static final String sourceToChangeXid = "DP_093765";
- private final List objectContext = Arrays.asList(new IntValuePair(1, "ds"));
+ private List objectContext;
- private RuntimeManager runtimeManager = mock(RuntimeManager.class);
- private DSCommandsScriptContextObject scriptContextObject = mock(DSCommandsScriptContextObject.class);
+ private RuntimeManager runtimeManager;
+ private DSCommandsScriptContextObject scriptContextObject;
@Before
public void config() throws Exception {
- ScriptTestUtils.configMock(runtimeManager, scriptContextObject);
+ objectContext = Arrays.asList(new IntValuePair(2, "ds"));
+ runtimeManager = mock(RuntimeManager.class);
+ scriptContextObject = mock(DSCommandsScriptContextObject.class);
+ ScriptTestUtils.configScriptMock(runtimeManager, scriptContextObject);
}
@After
diff --git a/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextWriteDataPointTest.java b/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextWriteDataPointTest.java
index ba02101a6b..2fa57b8a70 100644
--- a/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextWriteDataPointTest.java
+++ b/test/com/serotonin/mango/rt/scripting/ScriptWithObjectContextWriteDataPointTest.java
@@ -125,12 +125,14 @@ public ScriptWithObjectContextWriteDataPointTest(MangoValue mangoValue,
this.script = script;
}
- private RuntimeManager runtimeManager = mock(RuntimeManager.class);
- private DPCommandsScriptContextObject scriptContextObject = mock(DPCommandsScriptContextObject.class);
+ private RuntimeManager runtimeManager;
+ private DPCommandsScriptContextObject scriptContextObject;
@Before
public void config() throws Exception {
- ScriptTestUtils.configMock(runtimeManager, scriptContextObject);
+ runtimeManager = mock(RuntimeManager.class);
+ scriptContextObject = mock(DPCommandsScriptContextObject.class);
+ ScriptTestUtils.configScriptMock(runtimeManager, scriptContextObject);
}
@After
diff --git a/test/com/serotonin/mango/util/InitializeDataSourceRtMockUtils.java b/test/com/serotonin/mango/util/InitializeDataSourceRtMockUtils.java
new file mode 100644
index 0000000000..c3b011cebc
--- /dev/null
+++ b/test/com/serotonin/mango/util/InitializeDataSourceRtMockUtils.java
@@ -0,0 +1,477 @@
+package com.serotonin.mango.util;
+
+import br.org.scadabr.RealOPCMaster;
+import br.org.scadabr.rt.dataSource.alpha2.Alpha2DataSource;
+import br.org.scadabr.rt.dataSource.asciiSerial.ASCIISerialDataSource;
+import br.org.scadabr.rt.dataSource.dnp3.DNP3Master;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3DataSource;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3IpDataSource;
+import br.org.scadabr.rt.dataSource.dnp3.Dnp3SerialDataSource;
+import br.org.scadabr.rt.dataSource.drStorageHt5b.DrStorageHt5bDataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101DataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101EthernetDataSource;
+import br.org.scadabr.rt.dataSource.iec101.IEC101Master;
+import br.org.scadabr.rt.dataSource.iec101.IEC101SerialDataSource;
+import br.org.scadabr.rt.dataSource.opc.OPCDataSource;
+import br.org.scadabr.vo.dataSource.alpha2.Alpha2DataSourceVO;
+import br.org.scadabr.vo.dataSource.asciiSerial.ASCIISerialDataSourceVO;
+import br.org.scadabr.vo.dataSource.dnp3.Dnp3IpDataSourceVO;
+import br.org.scadabr.vo.dataSource.dnp3.Dnp3SerialDataSourceVO;
+import br.org.scadabr.vo.dataSource.drStorageHt5b.DrStorageHt5bDataSourceVO;
+import br.org.scadabr.vo.dataSource.iec101.IEC101EthernetDataSourceVO;
+import br.org.scadabr.vo.dataSource.iec101.IEC101SerialDataSourceVO;
+import br.org.scadabr.vo.dataSource.opc.OPCDataSourceVO;
+import cc.radiuino.scadabr.rt.datasource.radiuino.RadiuinoEventDataSource;
+import cc.radiuino.scadabr.rt.datasource.radiuino.RadiuinoPollingDataSource;
+import cc.radiuino.scadabr.vo.datasource.radiuino.RadiuinoDataSourceVO;
+import com.i2msolucoes.alpha24j.layer.user.Alpha2Master;
+import com.serotonin.bacnet4j.LocalDevice;
+import com.serotonin.bacnet4j.event.DeviceEventHandler;
+import com.serotonin.mango.Common;
+import com.serotonin.mango.rt.dataImage.DataPointRT;
+import com.serotonin.mango.rt.dataSource.bacnet.BACnetIPDataSourceRT;
+import com.serotonin.mango.rt.dataSource.ebro.EBI25Constants;
+import com.serotonin.mango.rt.dataSource.ebro.EBI25DataSourceRT;
+import com.serotonin.mango.rt.dataSource.galil.GalilDataSourceRT;
+import com.serotonin.mango.rt.dataSource.galil.GalilRequest;
+import com.serotonin.mango.rt.dataSource.galil.GalilResponse;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusDataSource;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusIpDataSource;
+import com.serotonin.mango.rt.dataSource.modbus.ModbusSerialDataSource;
+import com.serotonin.mango.rt.dataSource.nmea.NmeaDataSourceRT;
+import com.serotonin.mango.rt.dataSource.nmea.NmeaReceiver;
+import com.serotonin.mango.rt.dataSource.onewire.Network;
+import com.serotonin.mango.rt.dataSource.onewire.OneWireDataSourceRT;
+import com.serotonin.mango.rt.dataSource.pachube.PachubeDataSourceRT;
+import com.serotonin.mango.rt.dataSource.snmp.SnmpDataSourceRT;
+import com.serotonin.mango.rt.dataSource.sql.SqlDataSourceRT;
+import com.serotonin.mango.rt.dataSource.viconics.ViconicsDataSourceRT;
+import com.serotonin.mango.util.timeout.TimeoutTask;
+import com.serotonin.mango.vo.DataPointVO;
+import com.serotonin.mango.vo.dataSource.DataSourceVO;
+import com.serotonin.mango.vo.dataSource.bacnet.BACnetIPDataSourceVO;
+import com.serotonin.mango.vo.dataSource.ebro.EBI25DataSourceVO;
+import com.serotonin.mango.vo.dataSource.galil.GalilDataSourceVO;
+import com.serotonin.mango.vo.dataSource.modbus.ModbusIpDataSourceVO;
+import com.serotonin.mango.vo.dataSource.modbus.ModbusSerialDataSourceVO;
+import com.serotonin.mango.vo.dataSource.nmea.NmeaDataSourceVO;
+import com.serotonin.mango.vo.dataSource.onewire.OneWireDataSourceVO;
+import com.serotonin.mango.vo.dataSource.pachube.PachubeDataSourceVO;
+import com.serotonin.mango.vo.dataSource.snmp.SnmpDataSourceVO;
+import com.serotonin.mango.vo.dataSource.sql.SqlDataSourceVO;
+import com.serotonin.mango.vo.dataSource.viconics.ViconicsDataSourceVO;
+import com.serotonin.messaging.MessageControl;
+import com.serotonin.messaging.StreamTransport;
+import com.serotonin.modbus4j.ModbusMaster;
+import com.serotonin.modbus4j.exception.ModbusInitException;
+import com.serotonin.modbus4j.ip.tcp.TcpMaster;
+import com.serotonin.modbus4j.serial.ascii.AsciiMaster;
+import com.serotonin.modbus4j.serial.rtu.RtuMaster;
+import com.serotonin.viconics.ViconicsNetwork;
+import gnu.io.SerialPort;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.params.HttpClientParams;
+import org.scada_lts.ds.messaging.MessagingDataSourceRT;
+import org.scada_lts.ds.messaging.protocol.amqp.AmqpDataSourceVO;
+import org.scada_lts.ds.messaging.protocol.mqtt.MqttDataSourceVO;
+import org.scada_lts.ds.messaging.service.MessagingService;
+import org.scada_lts.ds.messaging.service.MessagingServiceFactory;
+import org.snmp4j.mp.SnmpConstants;
+import org.springframework.jdbc.core.JdbcOperations;
+
+import javax.naming.NamingException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.function.Function;
+import java.util.function.Supplier;
+
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.resetUnreliableDataPoints;
+import static com.serotonin.mango.rt.dataSource.DataPointUnreliableUtils.setUnreliableDataPoints;
+import static org.mockito.ArgumentMatchers.*;
+import static org.powermock.api.mockito.PowerMockito.*;
+import static org.powermock.api.mockito.PowerMockito.whenNew;
+
+public final class InitializeDataSourceRtMockUtils {
+
+ private InitializeDataSourceRtMockUtils() {}
+
+ public static SqlDataSourceRT createSql() {
+ SqlDataSourceRT dataSource = new SqlDataSourceRT(new SqlDataSourceVO());
+ sqlMock(dataSource);
+ return dataSource;
+ }
+
+ public static OneWireDataSourceRT createOneWire() {
+ OneWireDataSourceRT dataSource = new OneWireDataSourceRT(new OneWireDataSourceVO());
+ oneWireMock(dataSource);
+ return dataSource;
+ }
+
+ public static OPCDataSource createOpc() {
+ OPCDataSource dataSource = new OPCDataSource(new OPCDataSourceVO<>());
+ opcMock(dataSource);
+ return dataSource;
+ }
+
+ public static ModbusDataSource createModbusIpDataSource() {
+ ModbusDataSource dataSource = new ModbusIpDataSource(new ModbusIpDataSourceVO());
+ modbusMock(dataSource);
+ return dataSource;
+ }
+
+ public static ModbusDataSource createModbusSerialDataSource() {
+ ModbusDataSource dataSource = new ModbusSerialDataSource(new ModbusSerialDataSourceVO());
+ modbusMock(dataSource);
+ return dataSource;
+ }
+
+ public static IEC101DataSource createIec101Ethernet() {
+ IEC101DataSource dataSource = new IEC101EthernetDataSource(new IEC101EthernetDataSourceVO());
+ iec101Mock(dataSource);
+ return dataSource;
+ }
+
+ public static IEC101DataSource createIec101Serial() {
+ IEC101DataSource dataSource = new IEC101SerialDataSource(new IEC101SerialDataSourceVO());
+ iec101Mock(dataSource);
+ return dataSource;
+ }
+
+ public static ViconicsDataSourceRT createViconics() {
+ ViconicsDataSourceRT dataSource = new ViconicsDataSourceRT(new ViconicsDataSourceVO());
+ viconicsMock(dataSource);
+ return dataSource;
+ }
+
+ public static NmeaDataSourceRT createNmea() {
+ NmeaDataSourceRT dataSource = new NmeaDataSourceRT(new NmeaDataSourceVO());
+ nmeaMock(dataSource);
+ return dataSource;
+ }
+
+ public static EBI25DataSourceRT createEbi25() {
+ EBI25DataSourceRT dataSource = new EBI25DataSourceRT(new EBI25DataSourceVO());
+ ebi25Mock(dataSource);
+ return dataSource;
+ }
+
+ public static Alpha2DataSource createAlpha2() {
+ Alpha2DataSource dataSource = new Alpha2DataSource(new Alpha2DataSourceVO<>());
+ alpha2Mock(dataSource);
+ return dataSource;
+ }
+
+ public static Dnp3DataSource createDnp3Ip() {
+ Dnp3DataSource dataSource = new Dnp3IpDataSource(new Dnp3IpDataSourceVO());
+ dnp3Mock(dataSource);
+ return dataSource;
+ }
+
+ public static Dnp3DataSource createDnp3Serial() {
+ Dnp3DataSource dataSource = new Dnp3SerialDataSource(new Dnp3SerialDataSourceVO());
+ dnp3Mock(dataSource);
+ return dataSource;
+ }
+
+ public static BACnetIPDataSourceRT createBacNet() {
+ BACnetIPDataSourceRT dataSource = new BACnetIPDataSourceRT(new BACnetIPDataSourceVO());
+ bacNetMock(dataSource);
+ return dataSource;
+ }
+
+ public static PachubeDataSourceRT createPachube() {
+ PachubeDataSourceRT dataSource = new PachubeDataSourceRT(new PachubeDataSourceVO());
+ pachubeMock(dataSource);
+ return dataSource;
+ }
+
+ public static ASCIISerialDataSource createAsciiSerial() {
+ ASCIISerialDataSource dataSource = new ASCIISerialDataSource(new ASCIISerialDataSourceVO<>());
+ asciiSerialMock(dataSource);
+ return dataSource;
+ }
+
+ public static RadiuinoEventDataSource createRadiuino() {
+ RadiuinoEventDataSource dataSource = new RadiuinoEventDataSource(new RadiuinoDataSourceVO<>());
+ radiuinoMock(dataSource);
+ return dataSource;
+ }
+
+ public static RadiuinoPollingDataSource createRadiuinoPolling() {
+ RadiuinoPollingDataSource dataSource = new RadiuinoPollingDataSource(new RadiuinoDataSourceVO<>());
+ radiuinoPollingMock(dataSource);
+ return dataSource;
+ }
+
+ public static DrStorageHt5bDataSource createDrStorageMock() {
+ DrStorageHt5bDataSource dataSource = new DrStorageHt5bDataSource(new DrStorageHt5bDataSourceVO<>());
+ drStorageMock(dataSource);
+ return dataSource;
+ }
+
+ public static MessagingDataSourceRT createAmqp() {
+ AmqpDataSourceVO amqpDataSourceVO = new AmqpDataSourceVO();
+ MessagingService messagingService = mock(MessagingService.class);
+ return new MessagingDataSourceRT(amqpDataSourceVO, messagingService);
+ }
+
+ public static MessagingDataSourceRT createMqtt() {
+ MqttDataSourceVO mqttDataSourceVO = new MqttDataSourceVO();
+ MessagingService messagingService = MessagingServiceFactory.newService(mqttDataSourceVO);
+ return new MessagingDataSourceRT(mqttDataSourceVO, messagingService);
+ }
+
+ public static SnmpDataSourceRT createSnmp() {
+ SnmpDataSourceVO snmpDataSourceVO = new SnmpDataSourceVO();
+ snmpDataSourceVO.setSnmpVersion(SnmpConstants.version1);
+ snmpDataSourceVO.setCommunity("comm");
+ SnmpDataSourceRT dataSource = new SnmpDataSourceRT(snmpDataSourceVO);
+ return dataSource;
+ }
+
+ public static GalilDataSourceRT createGalil() {
+ GalilDataSourceVO galilDataSourceVO = new GalilDataSourceVO();
+ galilDataSourceVO.setHost("localhost");
+ galilDataSourceVO.setTimeout(1);
+ galilDataSourceVO.setPort(1111);
+ GalilDataSourceRT dataSource = new GalilDataSourceRT(galilDataSourceVO);
+ galilMock(dataSource);
+ return dataSource;
+ }
+
+ public static Consumer consumer(Consumer consumer) {
+ return consumer;
+ }
+
+ public static Supplier supplier(Supplier function) {
+ return function;
+ }
+
+ public static > Function function(Function function) {
+ return function;
+ }
+
+ public static void resetUnreliable(List list1, List list2, List list3) {
+ resetUnreliableDataPoints(list1);
+ resetUnreliableDataPoints(list2);
+ resetUnreliableDataPoints(list3);
+ }
+
+ public static void setUnreliable(List list1, List list2, List list3) {
+ setUnreliableDataPoints(list1);
+ setUnreliableDataPoints(list2);
+ setUnreliableDataPoints(list3);
+ }
+
+ public static void sqlMock(SqlDataSourceRT dataSource) {
+ mockStatic(SqlDataSourceUtils.class);
+ JdbcOperations jdbcOperations = mock(JdbcOperations.class);
+ when(jdbcOperations.queryForObject(anyString(), eq(int.class))).thenReturn(1);
+ try {
+ when(SqlDataSourceUtils.createJdbcOperations(any()))
+ .thenReturn(jdbcOperations);
+ } catch (NamingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void oneWireMock(OneWireDataSourceRT dataSource) {
+ Network networkMock = mock(Network.class);
+ try {
+ whenNew(Network.class).withAnyArguments()
+ .thenReturn(networkMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void opcMock(OPCDataSource dataSource) {
+ RealOPCMaster realOPCMasterMock = mock(RealOPCMaster.class);
+ try {
+ whenNew(RealOPCMaster.class).withAnyArguments()
+ .thenReturn(realOPCMasterMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void modbusMock(ModbusDataSource dataSource) {
+ AsciiMaster asciiMasterMock = mock(AsciiMaster.class);
+ TcpMaster tcpMasterMock = mock(TcpMaster.class);
+ RtuMaster rtuMasterMock = mock(RtuMaster.class);
+ try {
+ whenNew(AsciiMaster.class).withAnyArguments()
+ .thenReturn(asciiMasterMock);
+ whenNew(TcpMaster.class).withAnyArguments()
+ .thenReturn(tcpMasterMock);
+ whenNew(RtuMaster.class).withAnyArguments()
+ .thenReturn(rtuMasterMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void iec101Mock(IEC101DataSource dataSource) {
+ IEC101Master iec101MasterMock = mock(IEC101Master.class);
+ try {
+ whenNew(IEC101Master.class).withAnyArguments()
+ .thenReturn(iec101MasterMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void galilMock(GalilDataSourceRT dataSource) {
+ InputStream inputStreamMock = mock(InputStream.class);
+ OutputStream outputStreamMock = mock(OutputStream.class);
+
+ Socket socketMock = mock(Socket.class);
+
+ MessageControl messageControlMock = mock(MessageControl.class);
+ try {
+ when(messageControlMock.send(any(GalilRequest.class)))
+ .thenReturn(new GalilResponse(new byte[]{}));
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+
+ StreamTransport streamTransportMock = mock(StreamTransport.class);
+ doAnswer(a -> {
+ return null;
+ }).when(streamTransportMock).start(anyString());
+
+ try {
+ doAnswer(a -> {
+ return null;
+ }).when(socketMock).connect(any());
+
+ when(socketMock.getInputStream()).thenReturn(inputStreamMock);
+ when(socketMock.getOutputStream()).thenReturn(outputStreamMock);
+
+ whenNew(Socket.class).withAnyArguments()
+ .thenReturn(socketMock);
+
+ whenNew(MessageControl.class).withAnyArguments()
+ .thenReturn(messageControlMock);
+
+ whenNew(StreamTransport.class).withAnyArguments()
+ .thenReturn(streamTransportMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void viconicsMock(ViconicsDataSourceRT dataSource) {
+ ViconicsNetwork viconicsNetworkMock = mock(ViconicsNetwork.class);
+ try {
+ whenNew(ViconicsNetwork.class).withAnyArguments()
+ .thenReturn(viconicsNetworkMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void nmeaMock(NmeaDataSourceRT dataSource) {
+ NmeaReceiver nmeaReceiverMock = mock(NmeaReceiver.class);
+ TimeoutTask timeoutTaskMock = mock(TimeoutTask.class);
+ try {
+ whenNew(NmeaReceiver.class).withAnyArguments()
+ .thenReturn(nmeaReceiverMock);
+ whenNew(TimeoutTask.class).withAnyArguments()
+ .thenReturn(timeoutTaskMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void ebi25Mock(EBI25DataSourceRT dataSource) {
+ ModbusMaster modbusMasterMock = mock(ModbusMaster.class);
+ mockStatic(EBI25Constants.class);
+ try {
+ when(EBI25Constants.initModbusMaster(anyString(), anyInt(), anyBoolean(), anyInt(), anyInt(), any()))
+ .thenReturn(modbusMasterMock);
+ } catch (ModbusInitException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void alpha2Mock(Alpha2DataSource dataSource) {
+ Alpha2Master alpha2MasterMock = mock(Alpha2Master.class);
+ try {
+ doAnswer(invocation -> {
+ return null;
+ }).when(alpha2MasterMock).init();
+ whenNew(Alpha2Master.class)
+ .withAnyArguments()
+ .thenReturn(alpha2MasterMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void dnp3Mock(Dnp3DataSource dataSource) {
+ DNP3Master dnp3MasterMock = mock(DNP3Master.class);
+ try {
+ whenNew(DNP3Master.class)
+ .withAnyArguments()
+ .thenReturn(dnp3MasterMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void bacNetMock(BACnetIPDataSourceRT dataSource) {
+ LocalDevice localDeviceMock = mock(LocalDevice.class);
+
+ DeviceEventHandler deviceEventHandlerMock = mock(DeviceEventHandler.class);
+ when(localDeviceMock.getEventHandler()).thenReturn(deviceEventHandlerMock);
+ when(localDeviceMock.isInitialized()).thenReturn(true);
+
+ try {
+ whenNew(LocalDevice.class)
+ .withAnyArguments()
+ .thenReturn(localDeviceMock);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public static void pachubeMock(PachubeDataSourceRT dataSource) {
+ HttpClient httpClient = mock(HttpClient.class);
+ when(httpClient.getParams()).thenReturn(new HttpClientParams());
+ mockStatic(Common.class);
+ when(Common.getHttpClient(anyInt())).thenReturn(httpClient);
+ }
+
+ public static void asciiSerialMock(ASCIISerialDataSource dataSource) {
+ SerialPort serialPortMock = mock(SerialPort.class);
+ dataSource.setsPort(serialPortMock);
+ }
+
+ public static void radiuinoMock(RadiuinoEventDataSource dataSource) {
+ SerialPort serialPortMock = mock(SerialPort.class);
+ dataSource.setsPort(serialPortMock);
+ }
+
+ public static void radiuinoPollingMock(RadiuinoPollingDataSource dataSource) {
+ SerialPort serialPortMock = mock(SerialPort.class);
+ dataSource.setsPort(serialPortMock);
+ }
+
+ public static void drStorageMock(DrStorageHt5bDataSource dataSource) {
+ SerialPort serialPortMock = mock(SerialPort.class);
+ dataSource.setsPort(serialPortMock);
+ InputStream inputStreamMock = mock(InputStream.class);
+ try {
+ when(inputStreamMock.available()).thenReturn(1);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ dataSource.setInSerialStream(inputStreamMock);
+ dataSource.setsPort(serialPortMock);
+ }
+}
diff --git a/test/messages_de.properties b/test/messages_de.properties
index a3ee01559b..cf9b9a22a7 100644
--- a/test/messages_de.properties
+++ b/test/messages_de.properties
@@ -756,7 +756,7 @@ dsEdit.mbus.vifeLabel=Vifes
dsEdit.mbus.vifeLabels=Vife Label
dsEdit.mbus.vifeTypes=Vife Typen
dsEdit.meta=Meta Datenquelle
-dsEdit.meta.delay=Berechnungsverz\u00f6gerung
+dsEdit.meta.delay=Berechnungsverz\u00f6gerung
dsEdit.meta.desc=Meta Datenquelle Konfiguration
dsEdit.meta.event=Aktualisierungsereignis
dsEdit.meta.event.context=\u00c4nderung der Eingangsvariablen
@@ -1160,8 +1160,8 @@ dsEdit.validate.required=Required value
dsEdit.viconics=Viconics Wireless Thermostats
dsEdit.viconics.channel=Channel
dsEdit.viconics.chipRevision=Chip revision
-dsEdit.viconics.chipRevisionBr=Chip
revision
-dsEdit.viconics.commAddress=Comm
address
+dsEdit.viconics.chipRevisionBr=Chip revision
+dsEdit.viconics.commAddress=Comm address
dsEdit.viconics.convertCelsius=Convert temperatures to celsius
dsEdit.viconics.crss=CRSS
dsEdit.viconics.dataSourceNotStarted=Data source is not started
@@ -1170,9 +1170,9 @@ dsEdit.viconics.deviceRemove=Device remove (s)
dsEdit.viconics.deviceWarning=Device offline timeone (s)
dsEdit.viconics.devices=Devices
dsEdit.viconics.dpconn=Port: {0}, PAN ID: {1}, Channel: {2}
-dsEdit.viconics.firmwareRevision=Firmware
revision
+dsEdit.viconics.firmwareRevision=Firmware revision
dsEdit.viconics.ieee=IEEE
-dsEdit.viconics.modelNumber=Model
number
+dsEdit.viconics.modelNumber=Model number
dsEdit.viconics.networkIdentifyFailure=Network identify failed: {0}
dsEdit.viconics.networkInfo=Network information
dsEdit.viconics.networkTimeout=Network offline timeout (s)
@@ -1186,9 +1186,9 @@ dsEdit.viconics.timeout=Message timeout
dsEdit.viconics.trss=TRSS
dsEdit.viconics.unreliable=Point value may not be reliable
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee firmware revision
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
dsEdit.viconics.zigbeeNetworkAddress=Zigbee network address
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
dsEdit.virtual=Virtuelle Datenquelle
dsEdit.virtual.attractionPoint=Datenpunkt Attraktor
dsEdit.virtual.change=\u00c4nderung
@@ -1254,17 +1254,17 @@ dsedit.opc.tagName=Tag Tag
emport.added=added
emport.causedBy=caused by:
emport.compoundEvent.prefix=Compound event detector ''{0}'': {1}
-emport.compoundEvent.xid=A compound event detector does not have an 'xid' value. Ignored.
+emport.compoundEvent.xid=A compound event detector does not have an ’xid’ value. Ignored.
emport.confirmImport=Warn: the current database will be erased! Are you sure you want to import a new project?
emport.data=Daten
emport.dataPoint.badReference=Data point with XID ''{0}'' does not already exist and references a data source that does not exist. Ignored.
emport.dataPoint.prefix=Data point ''{0}'': {1}
-emport.dataPoint.xid=A data point with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataPoint.xid=A data point with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.dataPoints=Datenpunkte
-emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
-emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
+emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.dataSource.prefix=Datenquelle ''{0}'' : {1}
-emport.dataSource.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataSource.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.error.alarmLevel=Invalid alarm level ''{0}'' for event ''{1}''. Valid values are {2}
emport.error.attractor.missingPoint=Data point with ''{0}'' XID ''{1}'' not found
emport.error.chart.invalid=Chart renderer has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
@@ -1272,7 +1272,7 @@ emport.error.chart.missing=Chart renderer must have a ''{0}''. Valid values are
emport.error.component.imageChart.invalid=Image chart component has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
emport.error.component.imageChart.missing=Image chart component must have a ''{0}''. Valid values are {1}
emport.error.component.imageIndex=Image index {0} is too high for image set ''{1}''. Valid values are 0 to {2}
-emport.error.component.incompatibleDataType=Data point with 'XID' ''{0}'' has a data type that is not compatible with view component type ''{1}''
+emport.error.component.incompatibleDataType=Data point with ’XID’ ''{0}'' has a data type that is not compatible with view component type ''{1}''
emport.error.component.invalid=View component has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
emport.error.component.missing=View component must have a ''{0}''. Valid values are {1}
emport.error.component.unknownDynamicImage=Dynamic image id ''{0}'' not found. Known dynamic image ids are {1}
@@ -1311,7 +1311,7 @@ emport.error.text.missing=Text renderer must have a ''{0}''. Valid values are {1
emport.error.viewShare.missing=Missing ''{0}'' in view share
emport.errorMessage=Errors:
emport.eventHandler.prefix=Point link ''{0}'': {1}
-emport.eventHandler.xid=A point link does not have an 'xid' value. Ignored.
+emport.eventHandler.xid=A point link does not have an ’xid’ value. Ignored.
emport.export=Export
emport.exportDate=Export date
emport.exportJson=Generate JSON
@@ -1334,29 +1334,29 @@ emport.importProjectTitle=Import Project (Upload)
emport.includePointValues=Include point values
emport.indent=Einr\u00fcckung
emport.invalidFile=File reading failed ({0})
-emport.invalidImportData=Zu importierende Daten sind ung\u00fctig: kein JSON object.
+emport.invalidImportData=Zu importierende Daten sind ung\u00fctig: kein JSON object. (www.json.org)
emport.invalidProjectName=Invalid name
emport.mailingList.prefix=Mailing list ''{0}'': {1}
-emport.mailingList.xid=A mailing list does not have an 'xid' value. Ignored.
+emport.mailingList.xid=A mailing list does not have an ’xid’ value. Ignored.
emport.maintenanceEvent.prefix=Maintenance event ''{0}'': {1}
-emport.maintenanceEvent.xid=A maintenance event does not have an 'xid' value. Ignored.
+emport.maintenanceEvent.xid=A maintenance event does not have an ’xid’ value. Ignored.
emport.noMessages=No result message. Nothing to import?
emport.parseError=JSON-Parser Fehler: {0}
emport.pointHierarchy.prefix=Datenpunkthierarchie: {0}
emport.pointLink.prefix=Point link ''{0}'': {1}
-emport.pointLink.xid=A point link does not have an 'xid' value. Ignored.
+emport.pointLink.xid=A point link does not have an ’xid’ value. Ignored.
emport.pointValue.missingPoint=Point value ''{0}'': Data point not found
emport.pointValues=Point values
emport.pointValuesMax= Max point values
emport.projectDescription=Description
emport.projectName=Project name
-emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
-emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
+emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.publisher.prefix=Publisher ''{0}'': {1}
-emport.publisher.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.publisher.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.saved=gespeichert
emport.scheduledEvent.prefix=Scheduled event ''{0}'': {1}
-emport.scheduledEvent.xid=A scheduled event does not have an 'xid' value. Ignored.
+emport.scheduledEvent.xid=A scheduled event does not have an ’xid’ value. Ignored.
emport.script.prefix=Script ''{0}'': {1}
emport.select=Markieren Sie, was Sie exportieren m\u00f6chten
emport.selectAll=alles markieren
@@ -1367,14 +1367,14 @@ emport.unselectAll=alle Markierungen l\u00f6schen
emport.uploadError=Upload failed ({0})
emport.uploadsFolder=Include Uploads folder
emport.user.prefix=Benutzer ''{0} : {1}
-emport.user.username=A user does not have a 'username' value. Ignored.
+emport.user.username=A user does not have a ’username’ value. Ignored.
emport.userPermission.prefix=Recte f\u00fcr Benutzer ''{0}'' : {1}
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
-emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.versionError=The project version ({0}) isn’t compatible with current system version ({1})
+emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.view.prefix=Prozessbild ''{0}'' : {1}
-emport.view.xid=A graphical view does not have an 'xid' value. Ignored.
+emport.view.xid=A graphical view does not have an ’xid’ value. Ignored.
emport.watchList.prefix=Watch list ''{0}'': {1}
-emport.watchList.xid=A watch list does not have an 'xid' value. Ignored.
+emport.watchList.xid=A watch list does not have an ’xid’ value. Ignored.
engUnit.0=square meters
engUnit.1=square feet
engUnit.10=megavolt amperes
@@ -1567,8 +1567,8 @@ engUnit.98=percent
engUnit.99=percent per second
engUnit.190=kilometers
engUnit.abbr.190=km
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.10=megavolt amperes
engUnit.abbr.100=per minute
engUnit.abbr.101=per second
@@ -1789,7 +1789,7 @@ event.alarmMaxDecreased=H\u00f6chste Alarmpriorit\u00e4t verringerte sich von {0
event.alarmMaxIncreased=H\u00f6chste Alarmpriorit\u00e4t erh\u00f6te sich von {0} auf {1}
event.audit.added=Benutzer "{0}" erzeugte {1} mit id {2}: {3}
event.audit.changed=Benutzer "{0}" \u00e4nderte {1} mit id {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" zu "{2}"
+event.audit.changedProperty={0}: "{1}" zu "{2}"
event.audit.compoundEventDetector=Compound event detector
event.audit.dataPoint=Datenpunkt
event.audit.dataSource=Datenquelle
@@ -1798,7 +1798,7 @@ event.audit.eventHandler=Event handler
event.audit.maintenanceEvent=Maintenance event
event.audit.pointEventDetector=Point event detector
event.audit.pointLink=Point link
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2053,8 +2053,8 @@ event.valueParse.generalParsePoint={0}, result={1}, point={2}
event.valueParse.noData=No data to match against for point {0}
event.valueParse.noTime=No time match made {0}
event.valueParse.noValue=No value match made for point {0}
-event.valueParse.numericParse=Couldn't parse to numeric, result={0}
-event.valueParse.numericParsePoint=Couldn't parse to numeric, result={0}, point={1}
+event.valueParse.numericParse=Couldn’t parse to numeric, result={0}
+event.valueParse.numericParsePoint=Couldn’t parse to numeric, result={0}, point={1}
event.valueParse.textParse=Value did not match any multistate text and was not parsable, result={0}
event.valueParse.textParsePoint=Value did not match any multistate text and was not parsable, result={0}, point={1}
event.valueParse.timeParse=Failed to parse time "{0}"
@@ -2093,7 +2093,7 @@ eventHandlers.inactiveNotif=Benachrichtigung Gegangen
eventHandlers.inactiveOverride=Override inactive recipients
eventHandlers.inactiveRecipients=Inactive recipients
eventHandlers.inactiveScript=When inactive script
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
eventHandlers.invalidActiveSource=Invalid active source point
eventHandlers.invalidActiveSourceType=Invalid active source point data type
eventHandlers.invalidActiveValue=Invalid active value to set
@@ -2103,14 +2103,14 @@ eventHandlers.invalidInactiveSourceType=Invalid inactive source point data type
eventHandlers.invalidInactiveValue=Invalid inactive value to set
eventHandlers.invalidScripts=Selecione ao menos um script
eventHandlers.maintenanceEvents=Maintenance events
-eventHandlers.noEmailRecips=Keine Email Empf\u00e4nger!
Sie m\u00fcssen mindestens einen Email Empf\u00e4nger hinzuf\u00fcgen
-eventHandlers.noEscalRecips=Kein Eskalations Email Empf\u00e4nger!
Sie m\u00fcssen mindestens einen Eskalations Email Empf\u00e4nger hinzuf\u00fcgen
+eventHandlers.noEmailRecips=Keine Email Empf\u00e4nger! Sie m\u00fcssen mindestens einen Email Empf\u00e4nger hinzuf\u00fcgen
+eventHandlers.noEscalRecips=Kein Eskalations Email Empf\u00e4nger! Sie m\u00fcssen mindestens einen Eskalations Email Empf\u00e4nger hinzuf\u00fcgen
eventHandlers.noInactiveRecips=You must add inactive recipients
eventHandlers.noSetPointAction=No set point action has been defined
eventHandlers.noTargetPoint=No target point selected. You may not have any settable points defined.
eventHandlers.pointEventDetector=Datenpunktereignisse
eventHandlers.publisherEvents=Ereignisse Ver\u00f6ffentlichung
-eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler's email recipient list
+eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler’s email recipient list
eventHandlers.recipientType.active=Active
eventHandlers.recipientType.escalation=Escalation
eventHandlers.recipientType.inactive=Inactive
@@ -2266,7 +2266,7 @@ header.scripts=Scripting
header.setHomeUrl=setze diese Seite als Lesezeichen
header.sql=SQL
header.systemSettings=Mango Einstellungen
-header.title=Mango, von Serotonin
+header.title=Scada-LTS
header.toggleMute=Stumm schalten
header.unmute=Unmute
header.user=Benutzer
@@ -2294,7 +2294,7 @@ login.nag=Hinweis: Sie k\u00f6nnten Probleme mit ScadaLTS haben, da dierser Brow
login.password=Kennwort
login.supportedBrowser=Dieser Browser wird unterst\u00fctzt
login.unknownBrowser=Unbekannter Browser
-login.unsupportedBrowser=Dieser Browser wird offiziell nicht von Serotonin Software unterst\u00fctzt. Wir empfehlen Firefox, Chrome, oder Internet Explorer 7.
+login.unsupportedBrowser=Dieser Browser wird offiziell nicht von Serotonin Software unterst\u00fctzt. Wir empfehlen Mozilla Firefox, Google Chrome.
login.userId=Benutzername
login.validation.accountDisabled=Ihr Account wurde gesperrt, bitte wenden Sie sich an Ihren Administrator
login.validation.invalidLogin=Login gescheitert, bitte versuchen Sie es noch einmal
@@ -2412,7 +2412,7 @@ pointDetails.username=Benutzername
pointDetails.views=Ansichten
pointEdit.buttons.disable=Ausschalten
pointEdit.buttons.enable=Einschalten
-pointEdit.buttons.note=Hinweis: speichern, deaktivieren oder neu starten setzen alle aktiven Ereignisse zur\u00fcck.
+pointEdit.buttons.note=speichern, deaktivieren oder neu starten setzen alle aktiven Ereignisse zur\u00fcck.
pointEdit.buttons.restart=Neustart
pointEdit.chart.includeSum=Summe berechnen
pointEdit.chart.invalidLimit=Tabelle: Anzahl muss zwischen 2 und 50 liegen
@@ -2561,7 +2561,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.movedElement=Moved element
@@ -2722,7 +2722,7 @@ reports.pointComments=Point comments
reports.pointComments.empty=No point comments to list
reports.pointName=Name
reports.previous=Vorherige(r)
-reports.recipTestEmailMessage=This message was sent as a test of a report's email recipient list
+reports.recipTestEmailMessage=This message was sent as a test of a report’s email recipient list
reports.relative=Relativ zur Erstellungszeit
reports.rendered=Erstellt
reports.report=Report
@@ -2801,7 +2801,7 @@ sql.query=SQL-Abfrage starten
sql.rowsUpdated=Datens\u00e4tze aktualisiert
sql.sql=SQL
sql.update=SQL-Update ausf\u00fchren
-sql.warning=Achtung: Benutzen Sie die SQL Abfragen mit Vorsicht. Benutzerfehler k\u00f6nnen zu Datenverlust und/oder Fehlfunktionen des Systems f\u00fcren..
+sql.warning=Benutzen Sie die SQL Abfragen mit Vorsicht. Benutzerfehler k\u00f6nnen zu Datenverlust und/oder Fehlfunktionen des Systems f\u00fcren.
systemSettings.auditAlarmLevels=Audit event alarm levels
systemSettings.auditAlarmLevelsSaved=Audit event alarm levels have been saved
systemSettings.auth=Server erfordert Legitimation
@@ -2824,8 +2824,8 @@ systemSettings.emailSettingsSaved=E-Mail Einstellungen gespeichert
systemSettings.eventCount=Gespeicherte Ereignisse
systemSettings.filedataSize=Datendateigr\u00f6\u00dfe
systemSettings.files=Dateien
-systemSettings.fromAddress='Von' Adresse
-systemSettings.fromName='Von' Name
+systemSettings.fromAddress=’Von’ Adresse
+systemSettings.fromName=’Von’ Name
systemSettings.futureDateLimit=Discard point values future dated more than
systemSettings.groveLogging=Sende Fehler an Serotonin
systemSettings.historyCount=Gespeicherte Zeitstempel
@@ -2994,7 +2994,7 @@ viewEdit.compound.name=Name
viewEdit.compound.width=Breite
viewEdit.deletePointView=Delete point component
viewEdit.deleteStaticView=Delete static content
-viewEdit.deleteView=Remove yourself from the view's share list
+viewEdit.deleteView=Remove yourself from the view’s share list
viewEdit.editGraphicalRenderer=Bearbeite Darstellung
viewEdit.editPointView=Bearbeite Datenpunkt des Bausteins
viewEdit.editStaticView=Edit static content
@@ -3065,7 +3065,7 @@ viewEdit.viewDelete=L\u00f6schen:
viewEdit.viewDeleteConfirm=Confirm
viedEdit.viewSize=Gr\u00f6\u00dfe
views.newView=Neue Prozessansicht
-views.noViews=Sie haben noch kein Prozessbild. Erstellen Sie jetzt eins.
+views.noViews=Sie haben noch kein Prozessbild. Erstellen Sie
views.title=Prozessbild
watchlist.addNewList=Neue Beobachtungsliste
watchlist.addToWatchlist=Zur Beobachtungsliste hinzuf\u00fcgen
@@ -3335,4 +3335,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Hinweis:
+sql.warning.prefix=Achtung:
+views.noViews.prefix=jetzt.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_en.properties b/test/messages_en.properties
index b30109299b..db04560d04 100644
--- a/test/messages_en.properties
+++ b/test/messages_en.properties
@@ -756,7 +756,7 @@ dsEdit.mbus.vifeLabel=Vifes
dsEdit.mbus.vifeLabels=Vife labels
dsEdit.mbus.vifeTypes=Vife types
dsEdit.meta=Meta Data Source
-dsEdit.meta.delay=Execution delay
+dsEdit.meta.delay=Execution delay
dsEdit.meta.desc=Meta data source properties
dsEdit.meta.event=Update event
dsEdit.meta.event.context=Context update
@@ -1160,8 +1160,8 @@ dsEdit.validate.required=Required value
dsEdit.viconics=Viconics Wireless Thermostats
dsEdit.viconics.channel=Channel
dsEdit.viconics.chipRevision=Chip revision
-dsEdit.viconics.chipRevisionBr=Chip
revision
-dsEdit.viconics.commAddress=Comm
address
+dsEdit.viconics.chipRevisionBr=Chip revision
+dsEdit.viconics.commAddress=Comm address
dsEdit.viconics.convertCelsius=Convert temperatures to celsius
dsEdit.viconics.crss=CRSS
dsEdit.viconics.dataSourceNotStarted=Data source is not started
@@ -1170,9 +1170,9 @@ dsEdit.viconics.deviceRemove=Device remove (s)
dsEdit.viconics.deviceWarning=Device offline timeone (s)
dsEdit.viconics.devices=Devices
dsEdit.viconics.dpconn=Port: {0}, PAN ID: {1}, Channel: {2}
-dsEdit.viconics.firmwareRevision=Firmware
revision
+dsEdit.viconics.firmwareRevision=Firmware revision
dsEdit.viconics.ieee=IEEE
-dsEdit.viconics.modelNumber=Model
number
+dsEdit.viconics.modelNumber=Model number
dsEdit.viconics.networkIdentifyFailure=Network identify failed: {0}
dsEdit.viconics.networkInfo=Network information
dsEdit.viconics.networkTimeout=Network offline timeout (s)
@@ -1186,9 +1186,9 @@ dsEdit.viconics.timeout=Message timeout
dsEdit.viconics.trss=TRSS
dsEdit.viconics.unreliable=Point value may not be reliable
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee firmware revision
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
dsEdit.viconics.zigbeeNetworkAddress=Zigbee network address
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
dsEdit.virtual=Virtual Data Source
dsEdit.virtual.attractionPoint=Attraction point
dsEdit.virtual.change=Change
@@ -1254,17 +1254,17 @@ dsedit.opc.tagName=Tag Tag
emport.added=added
emport.causedBy=caused by:
emport.compoundEvent.prefix=Compound event detector ''{0}'': {1}
-emport.compoundEvent.xid=A compound event detector does not have an 'xid' value. Ignored.
+emport.compoundEvent.xid=A compound event detector does not have an ’xid’ value. Ignored.
emport.confirmImport=Warn: the current database will be erased! Are you sure you want to import a new project?
emport.data=Data
emport.dataPoint.badReference=Data point with XID ''{0}'' does not already exist and references a data source that does not exist. Ignored.
emport.dataPoint.prefix=Data point ''{0}'': {1}
-emport.dataPoint.xid=A data point with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataPoint.xid=A data point with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.dataPoints=Data points
-emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
-emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
+emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.dataSource.prefix=Data source ''{0}'': {1}
-emport.dataSource.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataSource.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.error.alarmLevel=Invalid alarm level ''{0}'' for event ''{1}''. Valid values are {2}
emport.error.attractor.missingPoint=Data point with ''{0}'' XID ''{1}'' not found
emport.error.chart.invalid=Chart renderer has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
@@ -1272,7 +1272,7 @@ emport.error.chart.missing=Chart renderer must have a ''{0}''. Valid values are
emport.error.component.imageChart.invalid=Image chart component has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
emport.error.component.imageChart.missing=Image chart component must have a ''{0}''. Valid values are {1}
emport.error.component.imageIndex=Image index {0} is too high for image set ''{1}''. Valid values are 0 to {2}
-emport.error.component.incompatibleDataType=Data point with 'XID' ''{0}'' has a data type that is not compatible with view component type ''{1}''
+emport.error.component.incompatibleDataType=Data point with ’XID’ ''{0}'' has a data type that is not compatible with view component type ''{1}''
emport.error.component.invalid=View component has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
emport.error.component.missing=View component must have a ''{0}''. Valid values are {1}
emport.error.component.unknownDynamicImage=Dynamic image id ''{0}'' not found. Known dynamic image ids are {1}
@@ -1311,7 +1311,7 @@ emport.error.text.missing=Text renderer must have a ''{0}''. Valid values are {1
emport.error.viewShare.missing=Missing ''{0}'' in view share
emport.errorMessage=Errors:
emport.eventHandler.prefix=Point link ''{0}'': {1}
-emport.eventHandler.xid=A point link does not have an 'xid' value. Ignored.
+emport.eventHandler.xid=A point link does not have an ’xid’ value. Ignored.
emport.export=Export
emport.exportDate=Export date
emport.exportJson=Generate JSON
@@ -1334,29 +1334,29 @@ emport.importProjectTitle=Import Project (Upload)
emport.includePointValues=Include point values
emport.indent=Indent level
emport.invalidFile=File reading failed ({0})
-emport.invalidImportData=Import data is invalid: not a JSON object
+emport.invalidImportData=Import data is invalid: not a JSON object. (www.json.org)
emport.invalidProjectName=Invalid name
emport.mailingList.prefix=Mailing list ''{0}'': {1}
-emport.mailingList.xid=A mailing list does not have an 'xid' value. Ignored.
+emport.mailingList.xid=A mailing list does not have an ’xid’ value. Ignored.
emport.maintenanceEvent.prefix=Maintenance event ''{0}'': {1}
-emport.maintenanceEvent.xid=A maintenance event does not have an 'xid' value. Ignored.
+emport.maintenanceEvent.xid=A maintenance event does not have an ’xid’ value. Ignored.
emport.noMessages=No result message. Nothing to import?
emport.parseError=JSON parse error: {0}
emport.pointHierarchy.prefix=Point hierarchy: {0}
emport.pointLink.prefix=Point link ''{0}'': {1}
-emport.pointLink.xid=A point link does not have an 'xid' value. Ignored.
+emport.pointLink.xid=A point link does not have an ’xid’ value. Ignored.
emport.pointValue.missingPoint=Point value ''{0}'': Data point not found
emport.pointValues=Point values
emport.pointValuesMax= Max point values
emport.projectDescription=Description
emport.projectName=Project name
-emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
-emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
+emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.publisher.prefix=Publisher ''{0}'': {1}
-emport.publisher.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.publisher.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.saved=saved
emport.scheduledEvent.prefix=Scheduled event ''{0}'': {1}
-emport.scheduledEvent.xid=A scheduled event does not have an 'xid' value. Ignored.
+emport.scheduledEvent.xid=A scheduled event does not have an ’xid’ value. Ignored.
emport.script.prefix=Script ''{0}'': {1}
emport.select=Select what you would like to export
emport.selectAll=Select all
@@ -1367,14 +1367,14 @@ emport.unselectAll=Unselect all
emport.uploadError=Upload failed ({0})
emport.uploadsFolder=Include Uploads folder
emport.user.prefix=User ''{0}'': {1}
-emport.user.username=A user does not have a 'username' value. Ignored.
+emport.user.username=A user does not have a ’username’ value. Ignored.
emport.userPermission.prefix=Permissions for user ''{0}'': {1}
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
-emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.versionError=The project version ({0}) isn’t compatible with current system version ({1})
+emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.view.prefix=View ''{0}'': {1}
-emport.view.xid=A graphical view does not have an 'xid' value. Ignored.
+emport.view.xid=A graphical view does not have an ’xid’ value. Ignored.
emport.watchList.prefix=Watch list ''{0}'': {1}
-emport.watchList.xid=A watch list does not have an 'xid' value. Ignored.
+emport.watchList.xid=A watch list does not have an ’xid’ value. Ignored.
engUnit.0=square meters
engUnit.1=square feet
engUnit.10=megavolt amperes
@@ -1567,8 +1567,8 @@ engUnit.98=percent
engUnit.99=percent per second
engUnit.190=kilometers
engUnit.abbr.190=km
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.10=megavolt amperes
engUnit.abbr.100=per minute
engUnit.abbr.101=per second
@@ -1789,7 +1789,7 @@ event.alarmMaxDecreased=Maximum alarm level has decreased from {0} to {1}
event.alarmMaxIncreased=Maximum alarm level has increased from {0} to {1}
event.audit.added=User "{0}" created {1} with id {2}: {3}
event.audit.changed=User "{0}" changed {1} with id {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" to "{2}"
+event.audit.changedProperty= {0}: "{1}" to "{2}",
event.audit.compoundEventDetector=Compound event detector
event.audit.dataPoint=Data point
event.audit.dataSource=Data source
@@ -1798,7 +1798,7 @@ event.audit.eventHandler=Event handler
event.audit.maintenanceEvent=Maintenance event
event.audit.pointEventDetector=Point event detector
event.audit.pointLink=Point link
-event.audit.property=
{0}="{1}"
+event.audit.property= {0}="{1}",
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2053,8 +2053,8 @@ event.valueParse.generalParsePoint={0}, result={1}, point={2}
event.valueParse.noData=No data to match against for point {0}
event.valueParse.noTime=No time match made {0}
event.valueParse.noValue=No value match made for point {0}
-event.valueParse.numericParse=Couldn't parse to numeric, result={0}
-event.valueParse.numericParsePoint=Couldn't parse to numeric, result={0}, point={1}
+event.valueParse.numericParse=Couldn’t parse to numeric, result={0}
+event.valueParse.numericParsePoint=Couldn’t parse to numeric, result={0}, point={1}
event.valueParse.textParse=Value did not match any multistate text and was not parsable, result={0}
event.valueParse.textParsePoint=Value did not match any multistate text and was not parsable, result={0}, point={1}
event.valueParse.timeParse=Failed to parse time "{0}"
@@ -2084,7 +2084,7 @@ eventHandlers.escal=Send escalation
eventHandlers.escalDelayError=Escalation delay must be greater than zero
eventHandlers.escalPeriod=Escalate if active for
eventHandlers.escalRecipients=Escalation recipients
-eventHandlers.escalTestEmailMessage=This message was sent as a test of an event handler's escalation list
+eventHandlers.escalTestEmailMessage=This message was sent as a test of an event handler’s escalation list
eventHandlers.eventHandler=Event handler
eventHandlers.eventHandlers=Event handlers
eventHandlers.inactiveAction=Inactive action
@@ -2093,7 +2093,7 @@ eventHandlers.inactiveNotif=Send inactive notification
eventHandlers.inactiveOverride=Override inactive recipients
eventHandlers.inactiveRecipients=Inactive recipients
eventHandlers.inactiveScript=When inactive script
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
eventHandlers.invalidActiveSource=Invalid active source point
eventHandlers.invalidActiveSourceType=Invalid active source point data type
eventHandlers.invalidActiveValue=Invalid active value to set
@@ -2110,7 +2110,7 @@ eventHandlers.noSetPointAction=No set point action has been defined
eventHandlers.noTargetPoint=No target point selected. You may not have any settable points defined.
eventHandlers.pointEventDetector=Point event detectors
eventHandlers.publisherEvents=Publisher events
-eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler's email recipient list
+eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler’s email recipient list
eventHandlers.recipientType.active=Active
eventHandlers.recipientType.escalation=Escalation
eventHandlers.recipientType.inactive=Inactive
@@ -2295,7 +2295,7 @@ login.nag=NOTE: you may have problems with ScadaLTS because your browser is not
login.password=Password
login.supportedBrowser=This browser is supported.
login.unknownBrowser=Checking your browser for compatibility...
-login.unsupportedBrowser=Your browser may work with this product, but is not officially supported by Serotonin Software. We instead recommend the use of Firefox, Chrome, or Internet Explorer 7
+login.unsupportedBrowser=Your browser may work with this product, but is not officially supported by Serotonin Software. We instead recommend the use of Mozilla Firefox, Google Chrome.
login.userId=User id
login.validation.accountDisabled=Your account has been disabled. Please contact your administrator
login.validation.invalidLogin=Invalid login, please try again
@@ -2368,7 +2368,7 @@ notes.timeByUsername=time by username
notes.userNotes=User notes
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pagination.ascending=Ascending
pagination.descending=Descending
pagination.next=Next
@@ -2413,7 +2413,7 @@ pointDetails.username=Username
pointDetails.views=Views
pointEdit.buttons.disable=Disable
pointEdit.buttons.enable=Enable
-pointEdit.buttons.note=Note: saving, disabling, or restarting a point causes all active events to be returned to normal.
+pointEdit.buttons.note=saving, disabling, or restarting a point causes all active events to be returned to normal.
pointEdit.buttons.restart=Restart
pointEdit.chart.includeSum=Include sum
pointEdit.chart.invalidLimit=Chart renderer: limit must be between 2 and 50
@@ -2561,7 +2561,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -2725,7 +2725,7 @@ reports.pointComments=Point comments
reports.pointComments.empty=No point comments to list
reports.pointName=Point name
reports.previous=Previous
-reports.recipTestEmailMessage=This message was sent as a test of a report's email recipient list
+reports.recipTestEmailMessage=This message was sent as a test of a report’s email recipient list
reports.relative=Relative to report time
reports.rendered=Rendered
reports.report=Report
@@ -2804,7 +2804,7 @@ sql.query=Submit query
sql.rowsUpdated=records(s) updated.
sql.sql=SQL
sql.update=Submit update
-sql.warning=Warning: use this facility at your own risk. Incorrect usage may result in corrupted data and/or system failures.
+sql.warning=use this facility at your own risk. Incorrect usage may result in corrupted data and/or system failures.
systemSettings.auditAlarmLevels=Audit event alarm levels
systemSettings.auditAlarmLevelsSaved=Audit event alarm levels have been saved
systemSettings.auth=Use authorization
@@ -2827,8 +2827,8 @@ systemSettings.emailSettingsSaved=Email settings have been saved
systemSettings.eventCount=Event count
systemSettings.filedataSize=Filedata size
systemSettings.files=files
-systemSettings.fromAddress='From' address
-systemSettings.fromName='From' name
+systemSettings.fromAddress=’From’ address
+systemSettings.fromName=’From’ name
systemSettings.futureDateLimit=Discard point values future dated more than
systemSettings.groveLogging=Send errors to Serotonin
systemSettings.historyCount=History count
@@ -3001,7 +3001,7 @@ viewEdit.compound.name=Name
viewEdit.compound.width=Width
viewEdit.deletePointView=Delete point component
viewEdit.deleteStaticView=Delete static content
-viewEdit.deleteView=Remove yourself from the view's share list
+viewEdit.deleteView=Remove yourself from the view’s share list
viewEdit.editGraphicalRenderer=Edit graphical renderer
viewEdit.editPointView=Edit point component settings
viewEdit.editStaticView=Edit static content
@@ -3072,7 +3072,7 @@ viewEdit.viewDelete=Delete view:
viewEdit.viewDeleteConfirm=Confirm
viedEdit.viewSize=Size
views.newView=New view
-views.noViews=You have not created any graphical views. Create one now.
+views.noViews=You have not created any graphical views. Create one
views.title=Graphic views
watchlist.addNewList=Add new watch list
watchlist.addToWatchlist=Add to watch list
@@ -3089,7 +3089,7 @@ watchlist.imageChartButton=Get Chart
watchlist.imageChartLiveButton=Start/Stop Live Chart
watchlist.moveDown=Move down
watchlist.moveUp=Move up
-watchlist.newListName=Enter the watch list's new name
+watchlist.newListName=Enter the watch list’s new name
watchlist.noChartables=No chartable points in watch list
watchlist.noExportables=No points selected for export
watchlist.pointDetails=Point details
@@ -3338,4 +3338,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Note:
+sql.warning.prefix=Warning:
+views.noViews.prefix=now.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_es.properties b/test/messages_es.properties
index d34a747fdd..2ca2afdf82 100644
--- a/test/messages_es.properties
+++ b/test/messages_es.properties
@@ -13,7 +13,7 @@
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
+# along with this program. If not, see .
#
# This file incorporates work covered by the following copyright and
# permission notice:
@@ -780,7 +780,7 @@ dsEdit.mbus.vifeTypes=Tipos de Vife
dsEdit.mbus.vifLabel=Etiqueta Vif
dsEdit.mbus.vifType=Tipo de Vif
dsEdit.meta=Fuente de datos Meta
-dsEdit.meta.delay=Demorar la Ejecuci\u00f3n
+dsEdit.meta.delay=Demorar la Ejecuci\u00f3n
dsEdit.meta.desc=Propiedades de fuente de datos Meta
dsEdit.meta.event=Actualizar evento
dsEdit.meta.event.context=Actualizar contexto
@@ -1145,8 +1145,8 @@ dsEdit.validate.required=Valor requerido
dsEdit.viconics=Termostato inal\u00e1mbrico Viconics
dsEdit.viconics.channel=Canal
dsEdit.viconics.chipRevision=Revisi\u00f3n de Chip
-dsEdit.viconics.chipRevisionBr=Chip
revisi\u00f3n
-dsEdit.viconics.commAddress=Comm
direcci\u00f3n
+dsEdit.viconics.chipRevisionBr=Chip revisi\u00f3n
+dsEdit.viconics.commAddress=Comm direcci\u00f3n
dsEdit.viconics.convertCelsius=Conversi\u00f3n de temperatura a Celsius
dsEdit.viconics.crss=CRSS
dsEdit.viconics.dataSourceNotStarted=Fuente de datos no ha sido iniciada
@@ -1155,9 +1155,9 @@ dsEdit.viconics.deviceRemove=Eliminaci\u00f3n de dispositivo (s)
dsEdit.viconics.devices=Dispositivos
dsEdit.viconics.deviceWarning=Desconexi\u00f3n de Dispositivo por tiempo de espera (s)
dsEdit.viconics.dpconn=Puerto: {0}, ID PAN: {1}, Canal: {2}
-dsEdit.viconics.firmwareRevision=Firmware
revisi\u00f3n
+dsEdit.viconics.firmwareRevision=Firmware revisi\u00f3n
dsEdit.viconics.ieee=IEEE
-dsEdit.viconics.modelNumber=Modelo
n\u00famero
+dsEdit.viconics.modelNumber=Modelo n\u00famero
dsEdit.viconics.networkIdentifyFailure=Fall\u00f3 identificaci\u00f3n de Red: {0}
dsEdit.viconics.networkInfo=Informaci\u00f3n de la Red
dsEdit.viconics.networkTimeout=Desconexi\u00f3n de Red por tiempo de espera (s)
@@ -1171,9 +1171,9 @@ dsEdit.viconics.timeout=Tiempo de espera del mensaje
dsEdit.viconics.trss=TRSS
dsEdit.viconics.unreliable=El valor del Punto puede no ser confiable
dsEdit.viconics.zigbeeFirmwareRevision=Revisi\u00f3n de Firmware de Zigbee
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
dsEdit.viconics.zigbeeNetworkAddress=Direcci\u00f3n de red de Zigbee
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
dsEdit.virtual=Fuente de datos Virtual
dsEdit.virtual.attractionPoint=Punto de atracci\u00f3n
dsEdit.virtual.change=Cambio
@@ -1237,17 +1237,17 @@ dsList.type=Tipo
emport.added=agregado
emport.causedBy=causado por:
emport.compoundEvent.prefix=Detector de evento compuesto ''{0}'': {1}
-emport.compoundEvent.xid=Un detector de evento compuesto no tiene un valor 'xid'. Ignorado.
+emport.compoundEvent.xid=Un detector de evento compuesto no tiene un valor ’xid’. Ignorado.
emport.confirmImport=Atenci\u00f3n: todos los datos del proyecto actual ser\u00e1n eliminados! \u00bfEst\u00e1 seguro que desea importar un nuevo proyecto?
emport.data=Dato
emport.dataPoint.badReference=Dato del punto con XID ''{0}'' ya no existe y hace referencia a una fuente de datos que no existe. Ignorado
emport.dataPoint.prefix=Dato del punto''{0}'': {1}
-emport.dataPoint.xid=A Dato del punto con Nombre ''{0}'' no tiene un valor 'xid'. Ignorado.
+emport.dataPoint.xid=A Dato del punto con Nombre ''{0}'' no tiene un valor ’xid’. Ignorado.
emport.dataPoints=Datos de puntos
-emport.dataSource.invalidType= La fuente de datos con XID ''{0}'' ya no existe y tiene un valor de 'tipo' inv\u00e1lido de ''{1}''. Los tipos v\u00e1lidos son {2}
+emport.dataSource.invalidType= La fuente de datos con XID ''{0}'' ya no existe y tiene un valor de ’tipo’ inv\u00e1lido de ''{1}''. Los tipos v\u00e1lidos son {2}
emport.dataSource.missingType=La fuente de datos con XID ''{0}'' ya no existe y no tiene un valor de "tipo". Los tipos v\u00e1lidos son {1}
emport.dataSource.prefix=Fuente de datos ''{0}'': {1}
-emport.dataSource.xid=LA fuente de datos de Nombre ''{0}'' no tienen un valor 'xid'. Ignorado.
+emport.dataSource.xid=LA fuente de datos de Nombre ''{0}'' no tienen un valor ’xid’. Ignorado.
emport.error.alarmLevel=Nivel de alarma inv\u00e1lido ''{0}'' para el evento ''{1}''. Los valores v\u00e1lidos son {2}
emport.error.attractor.missingPoint=Dato del punto con ''{0}'' XID ''{1}'' no encontrado
emport.error.chart.invalid=El generador gr\u00e1fico tiene un valor inv\u00e1lido de ''{0}'' de ''{1}''. Los valores v\u00e1lidos son {2}
@@ -1255,7 +1255,7 @@ emport.error.chart.missing=El generador gr\u00e1fico deber\u00eda tener un ''{0}
emport.error.component.imageChart.invalid=El componente del Gr\u00e1fico tiene un valor inv\u00e1lido ''{0}'' de ''{1}''. Los valores v\u00e1lidos son {2}
emport.error.component.imageChart.missing=El componente del Gr\u00e1fico deber\u00eda tener un ''{0}''. Los valores v\u00e1lidos son {1}
emport.error.component.imageIndex=El \u00edndice de la imagen {0} es muy grande para su conjunto ''{1}''. Los valores v\u00e1lidos son 0 to {2}
-emport.error.component.incompatibleDataType=Dato del punto con 'XID' ''{0}'' tiene un tipo de dato que no es compatible con el componente de la Vista de tipo ''{1}''
+emport.error.component.incompatibleDataType=Dato del punto con ’XID’ ''{0}'' tiene un tipo de dato que no es compatible con el componente de la Vista de tipo ''{1}''
emport.error.component.invalid=El componente de la Vista tiene un valor inv\u00e1lido ''{0}'' de ''{1}''. Los valores v\u00e1lidos son {2}
emport.error.component.missing=El componente de la Vista deber\u00eda tener un ''{0}''. Los valores v\u00e1lidos son {1}
emport.error.component.unknownDynamicImage=ID de Imagen din\u00e1mica ''{0}'' no encontrada. Las im\u00e1genes din\u00e1micas conocidas son {1}
@@ -1289,12 +1289,12 @@ emport.error.recipient.invalid.reference=Recipient tiene un valor inv\u00e1lido
emport.error.recipient.missing=Recipient deber\u00eda tener un ''{0}''. Los valores v\u00e1lidos son {1}
emport.error.recipient.missing.reference=Recipient deber\u00eda tener un ''{0}''
emport.error.scheduledEvent.invalid=El planificador de eventos tiene un valor inv\u00e1lido ''{0}'' de ''{1}''. Los valores v\u00e1lidos son {2}
-emport.error.text.invalid=El generador de texto tiene un valor inv\u00e1lido de ''{0}''de ''{1}''. Los valores v\u00e1lidos son {2}
+emport.error.text.invalid=El generador de texto tiene un valor inv\u00e1lido de ''{0}'' de ''{1}''. Los valores v\u00e1lidos son {2}
emport.error.text.missing=El generador de texto deber\u00eda tener un ''{0}''. Los valores v\u00e1lidos son {1}
emport.error.viewShare.missing=Perdido ''{0}'' en la vista compartida
emport.errorMessage=Hay errores en el archivo enviado:
emport.eventHandler.prefix=Enlace a punto ''{0}'': {1}
-emport.eventHandler.xid=Un enlace a punto no tiene un valor 'xid'. Ignorado.
+emport.eventHandler.xid=Un enlace a punto no tiene un valor ’xid’. Ignorado.
emport.export=Exportar
emport.exportDate=Fecha de exportaci\u00f3n
emport.exportJson=Generar JSON
@@ -1317,29 +1317,29 @@ emport.importProjectTitle=Importar Proyecto (Upload)
emport.includePointValues=Incluir hist\u00f3rico de puntos
emport.indent=Nivel de identaci\u00f3n
emport.invalidFile=Error en la lectura del archivo ({0})
-emport.invalidImportData=Dato de importaci\u00f3n inv\u00e1lido: no es un objeto JSON
+emport.invalidImportData=Dato de importaci\u00f3n inv\u00e1lido: no es un objeto JSON. (www.json.org)
emport.invalidProjectName=Nombre inv\u00e1lido para el Proyecto
emport.mailingList.prefix=Prefijo de la lista de correo
-emport.mailingList.xid=Una lista de correo no tiene un valor 'xid'. Ignorado.
+emport.mailingList.xid=Una lista de correo no tiene un valor ’xid’. Ignorado.
emport.maintenanceEvent.prefix=Evento de mantenimiento ''{0}'': {1}
-emport.maintenanceEvent.xid=Un evento de mantenimiento no tienen valor 'xid'. Se ignor\u00f3.
+emport.maintenanceEvent.xid=Un evento de mantenimiento no tienen valor ’xid’. Se ignor\u00f3.
emport.noMessages=Sin mensaje de resultado. \u00bfNada que importar?
emport.parseError=Error de an\u00e1lisis JSON: {0}
emport.pointHierarchy.prefix=Jerarqu\u00eda de Punto: {0}
emport.pointLink.prefix=Punto de enlace ''{0}'': {1}
-emport.pointLink.xid=Un punto de enlace no tiene un valor 'xid'. Ignorado.
+emport.pointLink.xid=Un punto de enlace no tiene un valor ’xid’. Ignorado.
emport.pointValue.missingPoint=Hist\u00f3rico de punto ''{0}'': Informaci\u00f3n del punto no se encuentra
emport.pointValues=Hist\u00f3rico (valores)
emport.pointValuesMax=M\u00e1ximo (puntos a guardar)
emport.projectDescription=Descripci\u00f3n
emport.projectName=Nombre del Proyecto
-emport.publisher.invalidType=Publisher with XID ''{0}'' ya no existe y tiene un inv\u00e1lido 'type' valor de ''{1}''. Los tipos v\u00e1lidos son {2}
-emport.publisher.missingType=Publicador con XID ''{0}'' ya no existe y no tiene un valor de 'type'. Los tipos v\u00e1lidos son {1}
+emport.publisher.invalidType=Publisher with XID ''{0}'' ya no existe y tiene un inv\u00e1lido ’type’ valor de ''{1}''. Los tipos v\u00e1lidos son {2}
+emport.publisher.missingType=Publicador con XID ''{0}'' ya no existe y no tiene un valor de ’type’. Los tipos v\u00e1lidos son {1}
emport.publisher.prefix=Publicador ''{0}'': {1}
-emport.publisher.xid=La fuente de datos con el nombre ''{0}'' no tiene un valor 'xid'. Ignorado.
+emport.publisher.xid=La fuente de datos con el nombre ''{0}'' no tiene un valor ’xid’. Ignorado.
emport.saved=guardado
emport.scheduledEvent.prefix=El planificador de eventos ''{0}'': {1}
-emport.scheduledEvent.xid=A El planificador de eventos no tiene un valor 'xid'. Ignorado.
+emport.scheduledEvent.xid=A El planificador de eventos no tiene un valor ’xid’. Ignorado.
emport.script.prefix=Script ''{0}'': {1}
emport.select=Seleccione que le gustar\u00eda exportar
emport.selectAll=Seleccione todo
@@ -1350,14 +1350,14 @@ emport.unselectAll=Desmarcar todo
emport.uploadError=Fall\u00f3 carga (upload) de archivo ({0})
emport.uploadsFolder=Incluir carpeta de Uploads
emport.user.prefix=Usuario ''{0}'': {1}
-emport.user.username=Un usuario no tiene un valor de 'nombre de usuario'. Ignorado
+emport.user.username=Un usuario no tiene un valor de ’nombre de usuario’. Ignorado
emport.userPermission.prefix=Permisos para el usuario ''{0}'': {1}
emport.versionError=La versi\u00f3n del proyecto ({0}) es incompatible con la versi\u00f3n actual del sistema ({1})
emport.view.missingType=Vista con XID ''{0}'' ya no existe y no tiene un valor de "tipo". Los tipos v\u00e1lidos son {1}
emport.view.prefix=Vista ''{0}'': {1}
-emport.view.xid=Una vista gr\u00e1fica no tiene un valor 'xid'. Ignorado.
+emport.view.xid=Una vista gr\u00e1fica no tiene un valor ’xid’. Ignorado.
emport.watchList.prefix=Lista de Supervisi\u00f3n ''{0}'': {1}
-emport.watchList.xid=Una Lista de Supervisi\u00f3n no tiene un valor de 'xid'. Se ignora.
+emport.watchList.xid=Una Lista de Supervisi\u00f3n no tiene un valor de ’xid’. Se ignora.
engUnit.0=metros cuadrados
engUnit.1=pies cuadrados
engUnit.10=megavoltio amperios
@@ -1550,8 +1550,8 @@ engUnit.98=porcentaje
engUnit.99=porcentaje por segundo
engUnit.190=kilómetros
engUnit.abbr.190=km
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.10=megavoltio amperios
engUnit.abbr.100=por minuto
engUnit.abbr.101=por segundo
@@ -1777,7 +1777,7 @@ event.alarmMaxDecreased=Nivel m\u00e1ximo de la alarma ha sido disminuido de {0}
event.alarmMaxIncreased=Nivel m\u00e1ximo de la alarma ha sido incrementado de {0} a {1}
event.audit.added=Usuario "{0}" creado {1} con id {2}: {3}
event.audit.changed=Usuario "{0}" modificado {1} con id {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" a "{2}"
+event.audit.changedProperty={0}: "{1}" a "{2}"
event.audit.compoundEventDetector=Detector de evento compuesto
event.audit.dataPoint=Datos de punto
event.audit.dataSource=Fuente de Datos
@@ -1786,7 +1786,7 @@ event.audit.eventHandler=Manejador de evento
event.audit.maintenanceEvent=Evento de Mantenimiento
event.audit.pointEventDetector=Detector de evento de punto
event.audit.pointLink=Enlace de Punto
-event.audit.property=
{0}
+event.audit.property={0}
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2278,7 +2278,7 @@ login.nag=NOTA: Puede tener problemas con ScadaLTS porque su navegador no est\u0
login.password=Contrase\u00f1a
login.supportedBrowser=Este navegador est\u00e1 soportado.
login.unknownBrowser=Revisando compatibilidad del navegador...
-login.unsupportedBrowser=Su navegador puede trabajar con este producto, pero no est\u00e1 oficialmente soportado por Serotonin Software. Le recomendamos que tilice Firefox, Chrome, o Internet Explorer 7.
+login.unsupportedBrowser=Su navegador puede trabajar con este producto, pero no est\u00e1 oficialmente soportado por Serotonin Software. Le recomendamos que tilice Mozilla Firefox, Google Chrome.
login.userId=ID de Usuario
login.validation.accountDisabled=Su cuenta ha sido deshabilitada. Por favor contacte al administrador
login.validation.invalidLogin=Inicio de sesi\u00f3n Inv\u00e1lido, por favor intente de nuevo.
@@ -2351,7 +2351,7 @@ notes.timeByUsername=Hora del usuario
notes.userNotes=Notas de Usuario
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pagination.ascending=Incrementando
pagination.descending=Disminuyendo
pagination.next=Pr\u00f3ximo
@@ -2396,7 +2396,7 @@ pointDetails.username=Nombre de Usuario
pointDetails.views=Vistas
pointEdit.buttons.disable=Deshabilitar
pointEdit.buttons.enable=Habilitar
-pointEdit.buttons.note=nueva.
+views.noViews=No se ha creado ninguna vista gr\u00e1fica. Cree una
views.title=Vistas gr\u00e1ficas
watchlist.addNewList=Agregar nueva Lista de Supervisi\u00f3n
watchlist.addToWatchlist=Agregar a Lista de Supervisi\u00f3n
@@ -3295,7 +3295,7 @@ graphic.enhancedImageChart.seriesConfig.seriesOptions=Options for {0}\:
dsEdit.modbus.dpconn3=Connection monitoring
viewEdit.compound.point.lineType.spline=Spline
userProfiles.validate.nameUnique=Profile name must be unique and not empty
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
graphic.enhancedImageChart.pointConfig.renderMode.line=Line
watchlist.imageChartLiveButton=Start/Stop Live Chart
dsEdit.radiuino.radiuinoDataType.4bFloat=Float (4 bytes)
@@ -3378,4 +3378,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Nota:
+sql.warning.prefix=Advertencia:
+views.noViews.prefix=nueva.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_fi.properties b/test/messages_fi.properties
index 812f1fe756..68419a159b 100644
--- a/test/messages_fi.properties
+++ b/test/messages_fi.properties
@@ -667,7 +667,7 @@ dsEdit.meta.event.week=Viikon alku
dsEdit.meta.event.month=Kuukauden alku
dsEdit.meta.event.year=Vuoden alku
dsEdit.meta.event.cron=Cron-ajastus
-dsEdit.meta.delay=Suoritusviive
+dsEdit.meta.delay=Suoritusviive
dsEdit.meta.test.success=Onnistui. tulos={0}
dsEdit.meta.test.successTs=Onnistui. tulos={0}, aikaleima={1}
dsEdit.meta.test.context=Yksi tai useampi piste puuttuu tai ei ole k\u00e4yt\u00f6ss\u00e4
@@ -966,16 +966,16 @@ dsEdit.viconics.networkInfo=Network information
dsEdit.viconics.refreshing=Refreshing...
dsEdit.viconics.rfModule=RF Module
dsEdit.viconics.devices=Devices
-dsEdit.viconics.commAddress=Comm
address
-dsEdit.viconics.modelNumber=Model
number
-dsEdit.viconics.firmwareRevision=Firmware
revision
+dsEdit.viconics.commAddress=Comm address
+dsEdit.viconics.modelNumber=Model number
+dsEdit.viconics.firmwareRevision=Firmware revision
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee firmware revision
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
dsEdit.viconics.zigbeeNetworkAddress=Zigbee network address
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
dsEdit.viconics.ieee=IEEE
dsEdit.viconics.chipRevision=Chip revision
-dsEdit.viconics.chipRevisionBr=Chip
revision
+dsEdit.viconics.chipRevisionBr=Chip revision
dsEdit.viconics.trss=TRSS
dsEdit.viconics.crss=CRSS
dsEdit.viconics.unreliable=Point value may not be reliable
@@ -1096,42 +1096,42 @@ emport.importProgress=Tuonti k\u00e4ynniss\u00e4...
emport.importCancelled=Tuonti peruttu
emport.importComplete=Tuonti valmis
emport.noMessages=Ei tulosviesti\u00e4. Ei mit\u00e4\u00e4n tuotavaa?
-emport.invalidImportData=Tuotava tieto on virheellinen: Ei JSON-objekti
+emport.invalidImportData=Tuotava tieto on virheellinen: Ei JSON-objekti. (www.json.org)
emport.parseError=JSON j\u00e4sennysvirhe: {0}
-emport.user.username=K\u00e4ytt\u00e4j\u00e4ll\u00e4 ei ole 'username'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.user.username=K\u00e4ytt\u00e4j\u00e4ll\u00e4 ei ole ’username’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.user.prefix=K\u00e4ytt\u00e4j\u00e4 ''{0}'': {1}
-emport.view.missingType=N\u00e4ytt\u00f6 XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa eik\u00e4 sill\u00e4 ole 'type'-arvoa. Sallitut arvot ovat {1}
-emport.dataSource.xid=Datal\u00e4hde nimell\u00e4 ''{0}'', ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
-emport.dataSource.missingType=Datal\u00e4hde XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa eik\u00e4 sill\u00e4 ole 'type'-arvoa. Sallitut arvot ovat {1}
-emport.dataSource.invalidType=Datal\u00e4hde XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa ja sill\u00e4 on virheellinen 'type'-arvo: ''{1}''. Sallitut arvot ovat {2}
+emport.view.missingType=N\u00e4ytt\u00f6 XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa eik\u00e4 sill\u00e4 ole ’type’-arvoa. Sallitut arvot ovat {1}
+emport.dataSource.xid=Datal\u00e4hde nimell\u00e4 ''{0}'', ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.dataSource.missingType=Datal\u00e4hde XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa eik\u00e4 sill\u00e4 ole ’type’-arvoa. Sallitut arvot ovat {1}
+emport.dataSource.invalidType=Datal\u00e4hde XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa ja sill\u00e4 on virheellinen ’type’-arvo: ''{1}''. Sallitut arvot ovat {2}
emport.dataSource.prefix=Datal\u00e4hde ''{0}'': {1}
-emport.dataPoint.xid=Piste nimell\u00e4 ''{0}'' ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.dataPoint.xid=Piste nimell\u00e4 ''{0}'' ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.dataPoint.badReference=Piste XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa ja viittaa datal\u00e4hteeseen jota ei ole olemassa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.dataPoint.prefix=Piste ''{0}'': {1}
emport.userPermission.prefix=Oikeudet k\u00e4ytt\u00e4j\u00e4lle ''{0}'': {1}
emport.added=lis\u00e4tty
emport.saved=tallennettu
emport.causedBy=aiheuttaja:
-emport.view.xid=N\u00e4yt\u00f6ll\u00e4 ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.view.xid=N\u00e4yt\u00f6ll\u00e4 ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.view.prefix=N\u00e4ytt\u00f6 ''{0}'': {1}
emport.pointHierarchy.prefix=Pistehierarkia: {0}
-emport.pointLink.xid=Pistelinkill\u00e4 ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.pointLink.xid=Pistelinkill\u00e4 ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.pointLink.prefix=Pistelinkki ''{0}'': {1}
-emport.scheduledEvent.xid=Ajastetulla tapahtumalla ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.scheduledEvent.xid=Ajastetulla tapahtumalla ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.scheduledEvent.prefix=Ajastettu tapahtuma ''{0}'': {1}
-emport.compoundEvent.xid=Yhdistelm\u00e4tapahtumalla ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.compoundEvent.xid=Yhdistelm\u00e4tapahtumalla ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.compoundEvent.prefix=Yhdistelm\u00e4tapahtuma ''{0}'': {1}
-emport.mailingList.xid=Postituslistalla ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.mailingList.xid=Postituslistalla ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.mailingList.prefix=Postituslista ''{0}'': {1}
-emport.eventHandler.xid=Pistelinkill\u00e4 ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.eventHandler.xid=Pistelinkill\u00e4 ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.eventHandler.prefix=Pistelinkki ''{0}'': {1}
-emport.publisher.xid=Datal\u00e4hde nimell\u00e4 ''{0}'' ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
-emport.publisher.missingType=Julkaisija XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa eik\u00e4 sill\u00e4 ole 'type'-arvoa. Sallitut arvot ovat {1}
-emport.publisher.invalidType=Julkaisija XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa ja sill\u00e4 on virheellinen 'type'-arvo:''{1}''. Sallitut arvot ovat {2}
+emport.publisher.xid=Datal\u00e4hde nimell\u00e4 ''{0}'' ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.publisher.missingType=Julkaisija XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa eik\u00e4 sill\u00e4 ole ’type’-arvoa. Sallitut arvot ovat {1}
+emport.publisher.invalidType=Julkaisija XID:ll\u00e4 ''{0}'' ei ole viel\u00e4 olemassa ja sill\u00e4 on virheellinen ’type’-arvo:''{1}''. Sallitut arvot ovat {2}
emport.publisher.prefix=Julkaisija ''{0}'': {1}
-emport.watchList.xid=Seurannalla ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.watchList.xid=Seurannalla ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.watchList.prefix=Seuranta ''{0}'': {1}
-emport.maintenanceEvent.xid=Yll\u00e4pitotapahtumalla ei ole 'xid'-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
+emport.maintenanceEvent.xid=Yll\u00e4pitotapahtumalla ei ole ’xid’-arvoa. J\u00e4tet\u00e4\u00e4n huomioimatta.
emport.maintenanceEvent.prefix=Yll\u00e4pitotapahtuma ''{0}'': {1}
eventHandlers.recipTestEmailMessage=T\u00e4m\u00e4 viesti on l\u00e4hetettu testin\u00e4 tapahtumak\u00e4sittelij\u00e4n postituslistalta
@@ -1270,8 +1270,7 @@ login.loginButton=Kirjaudu
login.unknownBrowser=Tarkistetaan selaimen yhteensopivuus...
login.supportedBrowser=T\u00e4m\u00e4 selain on tuettu.
login.unsupportedBrowser=Selaimesi voi toimia, mutta ei ole viralliesti Serotonin Softwaren tukema. \
- Suosittelemme k\u00e4ytt\u00e4m\u00e4\u00e4n Firefox, Chrome, tai \
-Internet Explorer 7.
+ Suosittelemme k\u00e4ytt\u00e4m\u00e4\u00e4n Mozilla Firefox, Google Chrome.
login.nag=Huom: Koska selaimesi ei ole virallisesti tuettu, on mahdollista, ett\u00e4 aiheutuu ongelmia ScadaLTS kanssa. Kehotamme p\u00e4ivitt\u00e4m\u00e4\u00e4n selaimen.
mailingLists.added=Postituslista lis\u00e4tty
@@ -1339,7 +1338,7 @@ notes.cancel=Peruuta
notes.timeByUsername=time by username
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pointDetails.recordCountError=Tallenteiden m\u00e4\u00e4r\u00e4 pit\u00e4\u00e4 olla numero
pointDetails.timePeriodError=Aikajakso pit\u00e4\u00e4 olla numero
pointDetails.imageCountError=Kuvam\u00e4\u00e4r\u00e4 pit\u00e4\u00e4 olla numero
@@ -1375,7 +1374,7 @@ pointDetails.accessType=P\u00e4\u00e4sy
pointEdit.buttons.enable=P\u00e4\u00e4lle
pointEdit.buttons.disable=Pois k\u00e4yt\u00f6st\u00e4
pointEdit.buttons.restart=Uudelleenk\u00e4ynnistys
-pointEdit.buttons.note=Huom: Pisteen tallentaminen, sammuttaminen tai uudelleenk\u00e4ynnistys asettaa kaikki tapahtumat takaisin normaaliin.
+pointEdit.buttons.note=pisteen tallentaminen, sammuttaminen tai uudelleenk\u00e4ynnistys asettaa kaikki tapahtumat takaisin normaaliin.
pointEdit.chart.props=Kaavion asetukset
pointEdit.chart.type=Tyyppi
@@ -1528,7 +1527,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -1725,7 +1724,7 @@ scheduledEvents.validate.inactiveTrigger=Virhe luotaessa palautumisliipaisin: {0
scheduledEvents.validate.aliasTooLong=Alias ei voi olla pidempi kuin 50 merkki\u00e4
scheduledEvents.validate.invalidRtn=Palautumisaika pit\u00e4\u00e4 olla ennen aktivointiaikaa
-sql.warning=Varoitus: k\u00e4yt\u00e4 t\u00e4t\u00e4 ominaisuutta omalla vastuulla. Virheellinen k\u00e4ytt\u00f6 voi aiheuttaa tietojen h\u00e4vi\u00e4mist\u00e4 ja/tai j\u00e4rjestelm\u00e4vian.
+sql.warning= k\u00e4yt\u00e4 t\u00e4t\u00e4 ominaisuutta omalla vastuulla. Virheellinen k\u00e4ytt\u00f6 voi aiheuttaa tietojen h\u00e4vi\u00e4mist\u00e4 ja/tai j\u00e4rjestelm\u00e4vian.
sql.sql=SQL
sql.query=L\u00e4het\u00e4 kysely
sql.update=L\u00e4het\u00e4 p\u00e4ivitys
@@ -1743,8 +1742,8 @@ systemSettings.upToDate=Mango on ajantasainen
systemSettings.emailSettings=S\u00e4hk\u00f6postiasetukset
systemSettings.smtpHost=SMTP palvelin
systemSettings.smtpPort=SMTP portti
-systemSettings.fromAddress='Kenelt\u00e4'-osoite
-systemSettings.fromName='Kenelt\u00e4'-nimi
+systemSettings.fromAddress=’Kenelt\u00e4’-osoite
+systemSettings.fromName=’Kenelt\u00e4’-nimi
systemSettings.auth=K\u00e4yt\u00e4 tunnuksia
systemSettings.smtpUsername=K\u00e4ytt\u00e4j\u00e4
systemSettings.smtpPassword=Salasana
@@ -1907,7 +1906,7 @@ viewEdit.compound.duration=Jakso
views.title=Graafiset n\u00e4yt\u00f6t
views.newView=Uusi n\u00e4ytt\u00f6
-views.noViews=Et ole luonut viel\u00e4 yht\u00e4\u00e4n n\u00e4ytt\u00f6\u00e4. Tee nyt.
+views.noViews=Et ole luonut viel\u00e4 yht\u00e4\u00e4n n\u00e4ytt\u00f6\u00e4. Tee
watchlist.addToWatchlist=Lis\u00e4\u00e4 seurantaan
watchlist.points=Pisteet
@@ -2018,7 +2017,7 @@ event.system.process=Prosessi-tapahtuman virhe
event.audit.added=K\u00e4ytt\u00e4j\u00e4 "{0}" loi kohteen "{1} Id:{2}", asetuksilla: {3}
event.audit.changed=K\u00e4ytt\u00e4j\u00e4 "{0}" muutti kohteen "{1} Id:{2}", asetuksia: {3}
-event.audit.changedProperty=
{0}: "{1}" --> "{2}"
+event.audit.changedProperty={0}: "{1}" --> "{2}"
event.audit.compoundEventDetector=Yhdistem\u00e4tapahtuma
event.audit.dataPoint=Piste
event.audit.dataSource=Datal\u00e4hde
@@ -2027,7 +2026,7 @@ event.audit.eventHandler=Tapahtumak\u00e4sittelij\u00e4
event.audit.maintenanceEvent=Yll\u00e4pitotapahtuma
event.audit.pointEventDetector=Pistetapahtuma
event.audit.pointLink=Pistelinkki
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2587,8 +2586,8 @@ engUnit.188=newtons per meter
engUnit.189=watts per meter per degree kelvin
engUnit.190=kilometers
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.2=mA
engUnit.abbr.3=A
engUnit.abbr.4=ohms
@@ -3109,7 +3108,7 @@ viewEdit.graphic.whenOffLabel=Label when OFF (0, false)
viewEdit.graphic.text=Text
script.dpCommands=Datapoints commands
dsEdit.nodaves7.writeBaseCmd=Write command line
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
+emport.versionError=The project version ({0}) isn’t compatible with current system version ({1})
events.export.ackedByDeletedUser=(user deleted)
dsEdit.jmx.attributeName=Attribute name
dsEdit.opc.tagName=Tag Name
@@ -3464,4 +3463,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Huom:
+sql.warning.prefix=Varoitus:
+views.noViews.prefix=nyt.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_fr.properties b/test/messages_fr.properties
index 4a1d179507..0d78c21ea5 100644
--- a/test/messages_fr.properties
+++ b/test/messages_fr.properties
@@ -106,7 +106,7 @@ common.gettingData=Obtenir les données
common.help=Aide
common.imageChart=Image de chart
common.inactive=Inactive
-common.inactiveTime=Période d'inactivité
+common.inactiveTime=Période d’inactivité
common.inception=Origine;Création
common.latest=Fin
common.maximize=Etendre
@@ -151,14 +151,14 @@ common.stats.end=Fin
common.stats.logEntries=Entrées de journal
common.stats.max=Maximum
common.stats.min=Minimum
-common.stats.runtime=Durée d'exécution
+common.stats.runtime=Durée d’exécution
common.stats.start=Début
common.stats.starts=Débute
common.stats.sum=Somme
common.stats.value=Valeur
common.status=Status
common.testEmailSent=E-mail de test a été envoyé''{0}''
-common.thumb.invalidValue=Valeur de consigne n'est pas une image
+common.thumb.invalidValue=Valeur de consigne n’est pas une image
common.time=Date
common.tp.day=jour
common.tp.days=jour(s)
@@ -732,7 +732,7 @@ dsEdit.mbus.vifeTypes=Types Vif
dsEdit.mbus.vifLabel=Etiquette vif
dsEdit.mbus.vifType=Type Vif
dsEdit.mbus=MBus
-dsEdit.meta.delay=Délai d’éxécution
+dsEdit.meta.delay=Délai d’éxécution
dsEdit.meta.desc=Propriétés de source de données Meta
dsEdit.meta.event.context=Mise à jour de contexte
dsEdit.meta.event.cron=Modèle Cron
@@ -743,7 +743,7 @@ dsEdit.meta.event=Mise à jour évènement
dsEdit.meta.event.week=Début de la semaine
dsEdit.meta.event.year=Début de l’année
dsEdit.meta.event.month=Début du mois
-dsEdit.meta.noPoints=Aucun point n'a été ajouté au contexte de script
+dsEdit.meta.noPoints=Aucun point n’a été ajouté au contexte de script
dsEdit.meta.pointName=Nom du point
dsEdit.meta.script=Script
dsEdit.meta.scriptContext=Contexte du script
@@ -854,7 +854,7 @@ dsEdit.modbusSerial.parity.space=Espace
dsEdit.modbusSerial.parity=Parité
dsEdit.modbusSerial.port=Port
dsEdit.modbus.settableOverride=Settable
-dsEdit.modbusSerial.stopBits=Bits d'arrêt
+dsEdit.modbusSerial.stopBits=Bits d’arrêt
dsEdit.name=Nom
dsEdit.nmea.baud=Vitesse de transmission
dsEdit.nmea.binary0Value=Valeur 0 binaire
@@ -1077,8 +1077,8 @@ dsEdit.updatePeriod=Mise à jour période
dsEdit.validate.required=Valeur requise
dsEdit.viconics.channel=Canal viconics
dsEdit.viconics.chipRevision=Révision Chip viconics
-dsEdit.viconics.chipRevisionBr=Chip
révision viconics
-dsEdit.viconics.commAddress=Comm
adresse viconics
+dsEdit.viconics.chipRevisionBr=Chip révision viconics
+dsEdit.viconics.commAddress=Comm adresse viconics
dsEdit.viconics.convertCelsius=Convertir températures en Celsius
dsEdit.viconics.crss=CRSS Viconics
dsEdit.viconics.dataSourceNotStarted=Source des données n’est pas démarré
@@ -1087,9 +1087,9 @@ dsEdit.viconics.deviceRemove=supprimer le périphérique (s)
dsEdit.viconics.devices=Périphériques viconics
dsEdit.viconics.deviceWarning=Délai de périphérique déconnecté(s)
dsEdit.viconics.dpconn=Port: {0}, PAN ID: {1}, Canal: {2}
-dsEdit.viconics.firmwareRevision=Firmware
révision
+dsEdit.viconics.firmwareRevision=Firmware révision
dsEdit.viconics.ieee=IEEE viconics
-dsEdit.viconics.modelNumber=Model
numéro
+dsEdit.viconics.modelNumber=Model numéro
dsEdit.viconics.networkIdentifyFailure=Identification réseau échoué: {0}
dsEdit.viconics.networkInfo=Information réseau
dsEdit.viconics.networkTimeout=Délai de réseau déconnecté(s)
@@ -1103,9 +1103,9 @@ dsEdit.viconics.timeout=Délai message viconics
dsEdit.viconics.trss=TRSS viconics
dsEdit.viconics.unreliable=Valeur du point peut ne pas être fiable
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee révision firmware
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
révision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware révision
dsEdit.viconics.zigbeeNetworkAddress=Zigbee adresse réseau
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
adresse
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network adresse
dsEdit.viconics=Viconics thermostats sans fil
dsEdit.virtual.attractionPoint=Point d’attraction
dsEdit.virtual.change=Changement virtuelle
@@ -1250,7 +1250,7 @@ emport.importProjectTitle=Importer projet (Upload)
emport.includePointValues=Inclure valeurs de points
emport.indent=Niveau de retrait
emport.invalidFile=Lecture de fichier échoué ({0})
-emport.invalidImportData=Importer des données n’est pas valide: n’est pas un objet JSON
+emport.invalidImportData=Importer des données n’est pas valide: n’est pas un objet JSON. (www.json.org)
emport.invalidProjectName=Nom invalide
emport.mailingList.prefix=Liste de diffusion ''{0}'': {1}
emport.mailingList.xid=Une liste de diffusion n’a pas de valeur ‘xid’. Ignoré.
@@ -1266,7 +1266,7 @@ emport.pointValuesMax=Valeurs max de points
emport.projectDescription=Description
emport.projectName=Nom de projet
emport.publisher.invalidType=Éditeur avec XID ''{0}'' n’existe pas et a une valeur non valide ""type"" de ''{1}''. Les types valides sont {2}
-emport.publisher.missingType=Éditeur avec XID'' {0}''n’existe pas encore et n’a pas de valeur ‘type’. Les types valides sont {1}
+emport.publisher.missingType=Éditeur avec XID'' {0}'' n’existe pas encore et n’a pas de valeur ‘type’. Les types valides sont {1}
emport.publisher.prefix=Éditeur ''{0}'': {1}
emport.publisher.xid=Une source de données avec nom ''{0}'' ne pas avoir de valeur ‘xid’. Ignoré.
emport.saved=sauvegardé
@@ -1483,8 +1483,8 @@ engUnit.99=pourcent par seconde
engUnit.190=kilomètres
engUnit.abbr.190=km
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.10=mégavolt ampères
engUnit.abbr.100=par minute
engUnit.abbr.101=par seconde
@@ -1705,7 +1705,7 @@ event.alarmMaxDecreased=Niveau d’alarme maximal a diminué de {0} vers {1}
event.alarmMaxIncreased=Niveau d’alarme maximal a augmenté de {0} vers {1}
event.audit.added=Utilisateur ""{0}"" créé {1} avec id {2}: {3}
event.audit.changed=Utilisateur ""{0}"" changé {1} avec id {2}: {3}
-event.audit.changedProperty=
""{0}"" ""{1}"" à ""{2}""
+event.audit.changedProperty= ""{0}"" ""{1}"" à ""{2}""
event.audit.compoundEventDetector=Détecteur d’évènement du composé
event.audit.dataPoint=Point de données
event.audit.dataSource=Source de données
@@ -1714,7 +1714,7 @@ event.audit.eventHandler=Gestionnaire d’évènements
event.audit.maintenanceEvent=Évènement de maintenance
event.audit.pointEventDetector=Point de détecteur d’évènements
event.audit.pointLink=Point de lien
-event.audit.property=
""{0}""=""{1}""
+event.audit.property= ""{0}""=""{1}""
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2081,7 +2081,7 @@ ftl.eventActive=Scada-LTS notification d’évènements actif
ftl.eventInactive=Cet évènement est inactif à ce moment
ftl.footer=Si vous avez reçu ce message par erreur, s’il vous plaît ne pas tenir compte.
ftl.htmlFooter.automated=Cet e-mail a été envoyé par un système automatique. Il a été envoyé vers vous parce que vous avez été inscrit sur la liste d’envoi d’une notification d’e-mail Scada-LTS. S’il vous plaît ne répondez pas à cet e-mail.
-ftl.htmlFooter.mango=Scada-LTS (by Abil'I.T.)
+ftl.htmlFooter.mango=Scada-LTS (by Abil’I.T.)
ftl.manual=Cet évènement nécessite une confirmation manuelle pour qu’il devienne inactif
ftl.note=Note
ftl.originalInformation=Origine d’informations d’évènement
@@ -2162,7 +2162,7 @@ header.scripts=Scripte
header.setHomeUrl=Faire de ceci ma page de défaut
header.sql=SQL
header.systemSettings=Paramètres du système
-header.title=Scada-LTS (by Abil'I.T.)
+header.title=Scada-LTS (by Abil’I.T.)
header.toggleMute=Mute
header.unmute=Réactiver
header.user=Utilisateur
@@ -2191,7 +2191,7 @@ login.nag=NOTE: vous pouvez avoir des problèmes avec ScadaLTS parce que votre n
login.password=Mot de passe
login.supportedBrowser=Ce navigateur est supporté.
login.unknownBrowser=Vérification de votre navigateur pour la compatibilité...
-login.unsupportedBrowser=Ce navigateur devrait fonctionner, mais n'est pas officiellement supporté. Nous vous recommandons d'utiliser Firefox ou Chrome.
+login.unsupportedBrowser=Ce navigateur devrait fonctionner, mais n'est pas officiellement supporté. Nous vous recommandons d'utiliser Mozilla Firefox, Google Chrome.
login.userId=Id de l’utilisateur
login.validation.accountDisabled=Votre compte a été désactivé. S’il vous plaît contactez votre administrateur
login.validation.invalidLogin=Connexion incorrecte, s’il vous plaît essayer à nouveau
@@ -2247,7 +2247,7 @@ maintenanceEvents.type.year=Annuel
maintenanceEvents.type=Type planifié
maintenanceEvents.validate.activeCron=Erreur dans l’expression cron active: {0}
maintenanceEvents.validate.activeTrigger=Erreur de création de déclencheur actif: {0}
-maintenanceEvents.validate.aliasTooLong=Alias trop long
+maintenanceEvents.validate.aliasTooLong=Alias trop long (ne peut pas contenir plus de 50 caractères)
maintenanceEvents.validate.inactiveCron=Erreur dans l’expression cron inactive: {0}
maintenanceEvents.validate.inactiveTrigger=Erreur de création de déclencheur inactif: {0}
maintenanceEvents.validate.invalidRtn=Temps d’inactivité doit être après le temps d’activité
@@ -2261,7 +2261,7 @@ notes.timeByUsername=Temps par utilisateur
notes.userNotes=Notes d’utilisateur
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pagination.ascending=Ascendant
pagination.descending=Descendant
pagination.next=Prochain
@@ -2303,7 +2303,7 @@ pointDetails.username=Nom d’utilisateur
pointDetails.views=Vues
pointEdit.buttons.disable=Déscativer
pointEdit.buttons.enable=Activer
-pointEdit.buttons.note=Note: la sauvegarde, la désactivation, ou le redémarrage d’un point entraîne tous les évènements actifs à retourner à la normale
+pointEdit.buttons.note=la sauvegarde, la désactivation, ou le redémarrage d’un point entraîne tous les évènements actifs à retourner à la normale
pointEdit.buttons.restart=Redémarrer
pointEdit.chart.includeSum=Inclure somme
pointEdit.chart.invalidLimit=Tableau rendu: limite doit être entre 2 et 50
@@ -2553,7 +2553,7 @@ reports.commentList.type.event=Évèvenement
reports.commentList.type.point=Point
reports.commentList.type=Type
reports.commentList.typeKey=Taper clé
-reports.comments=Commentaires d'utilisateur
+reports.comments=Commentaires d’utilisateur
reports.consolidated=Tableau consolidé
reports.consolidatedChart=Diagramme consolidé
reports.criteria=Critères de rapport
@@ -2665,7 +2665,7 @@ sql.query=Envoyer requête
sql.rowsUpdated=Enregistrement(s) à jour.
sql.sql=SQL
sql.update=Envoyer mise à jour
-sql.warning=Attention: utiliser cette fonction à vos risques. Une utilisation incorrecte peut entraîner des données corrompues et/ou des failles de système.
+sql.warning=utiliser cette fonction à vos risques. Une utilisation incorrecte peut entraîner des données corrompues et/ou des failles de système.
systemSettings.auditAlarmLevels=Niveaux d’alarmes d’évènements d’audit
systemSettings.auditAlarmLevelsSaved=Niveaux d’alarmes d’évènements d’audit ont été sauvegardés
systemSettings.auth=Autorisation d’utilisation
@@ -2684,11 +2684,11 @@ systemSettings.fromAddress="De" adresse
systemSettings.fromName="De" nom
systemSettings.futureDateLimit=Jeter valeurs de points futures datées de plus de
systemSettings.groveLogging=Envoyer erreurs à Sérotonine
-systemSettings.historyCount=Compte de l'histoire
+systemSettings.historyCount=Compte de l’histoire
systemSettings.httpSaved=Paramètres Http ont été sauvegardés
systemSettings.httpSettings=Paramètres HTTP
-systemSettings.instanceDescription=Description de l'instance
-systemSettings.instanceId=Identifiant de l'instance
+systemSettings.instanceDescription=Description de l’instance
+systemSettings.instanceId=Identifiant de l’instance
systemSettings.langSaved=Langue a été sauvegardée
systemSettings.languageSettings=Paramètres de langue
systemSettings.miscSaved=les Paramètres ont été sauvegardés
@@ -2700,11 +2700,11 @@ systemSettings.otherSettings=Autres paramètres
systemSettings.proxyHost=Hôte proxy
systemSettings.proxyPassword=Mot de passe proxy
systemSettings.proxyPort=Port proxy
-systemSettings.proxyUsername=Nom d'utilisateur proxy
+systemSettings.proxyUsername=Nom d’utilisateur proxy
systemSettings.purgeData=Purger toutes les données
systemSettings.purgeDataComplete=Purge totale. {0} échantillons de points supprimés.
systemSettings.purgeDataConfirm=Cela purgera tous les échantillons de points de la base de données. Etes-vous sûr?
-systemSettings.purgeDataInProgress=Purge toutes les données, s'il vous plaît attendre...
+systemSettings.purgeDataInProgress=Purge toutes les données, s’il vous plaît attendre...
systemSettings.purgeEvents=Purger évènements plus vieux que
systemSettings.purgeNow=Purger maintenant en utilisant des paramètres de point
systemSettings.purgeReports=Purger les instances de rapport plus vieilles que
@@ -2712,9 +2712,9 @@ systemSettings.retrieving=(récupération)
systemSettings.smtpHost=Hôte SMTP
systemSettings.smtpPassword=Mot de passe
systemSettings.smtpPort=Port SMTP
-systemSettings.smtpUsername=Nom d'utilisateur
-systemSettings.systemAlarmLevels=Niveaux d'alarmes d'évènements du système
-systemSettings.systemAlarmLevelsSaved=Niveaux d'alarmes d'évènements du système ont été sauvegardés
+systemSettings.smtpUsername=Nom d’utilisateur
+systemSettings.systemAlarmLevels=Niveaux d’alarmes d'évènements du système
+systemSettings.systemAlarmLevelsSaved=Niveaux d’alarmes d'évènements du système ont été sauvegardés
systemSettings.systemInformation=Informations du système
systemSettings.systemLanguage=Langage du système
systemSettings.testEmail=Un e-mail de test avec vos paramètres du système a été envoyé avec succès.
@@ -2724,16 +2724,16 @@ systemSettings.totalSize=Taille totale
systemSettings.uiPerformance.high=Haute
systemSettings.uiPerformance.low=Basse
systemSettings.uiPerformance.med=Moyenne
-systemSettings.uiPerformance=Performance de l'UI
+systemSettings.uiPerformance=Performance de l’UI
systemSettings.upToDate=Cette instance de Scada-LTS est à jour
systemSettings.useProxy=Utiliser proxy
systemSettings.validation.invalidColour=Couleur invalide
-systemSettings.versionCheck1=Temps de pause du socket lors d'un contrôle. S'il vous plaît essayer à nouveau
-systemSettings.versionCheck2=Une erreur s'est produite: {0}: {1}
+systemSettings.versionCheck1=Temps de pause du socket lors d’un contrôle. S’il vous plaît essayer à nouveau
+systemSettings.versionCheck2=Une erreur s’est produite: {0}: {1}
systemSettings.versionSaved=Paramètres de version ont été sauvés
textRenderer.analog=Analogue
textRenderer.binary=Binaire
-textRenderer.engineeringUnits=Unités d'ingénierie
+textRenderer.engineeringUnits=Unités d’ingénierie
textRenderer.multistate=Multi-état
textRenderer.none=Aucun
textRenderer.plain=Ordinaire
@@ -2743,12 +2743,12 @@ users.add=Ajouter utilisateur
users.added=Utilisateur ajouté
users.dataSources=Source de données
users.deleteConfirm=Etes-vous sûr de vouloir supprimer cet utilisateur?
-users.details=Détails d'utilisateur
+users.details=Détails d’utilisateur
users.email=E-mail
users.newPassword=Nouveau mot de passe
users.phone=Téléphone
-users.receiveAlarmEmails=Envoyer des e-mails d'alarme
-users.receiveOwnAuditEvents=Recevez propres évènements d'audit
+users.receiveAlarmEmails=Envoyer des e-mails d’alarme
+users.receiveOwnAuditEvents=Recevez propres évènements d’audit
users.hideMenu=Masquer le menu
users.theme=Thème
users.theme.default=Défaut
@@ -2757,19 +2757,19 @@ users.homeUrl=Home URL
users.saved=Utilisateur sauvegardé
users.title=Utilisateur
users.user=Utilisateur
-users.username=Nom d'utilisateur
+users.username=Nom d’utilisateur
users.firstName=Prénom
users.lastName=Nom de famille
users.validate.adminDisable=Vous ne pouvez pas désactiver votre compte
-users.validate.adminInvalid=Vous ne pouvez pas supprimer vos propres privilèges d'administrateur
+users.validate.adminInvalid=Vous ne pouvez pas supprimer vos propres privilèges d’administrateur
users.validate.badDelete=Vous ne pouvez pas effacer votre compte
users.validate.emailRequired=E-mail est requis
users.validate.emailTooLong=E-mail ne peut pas contenir plus de 255 caractères
users.validate.phoneTooLong=Téléphone ne peut pas être plus long que 40 caractères
-users.validate.usernameInUse=Nom d'utilisateur est déjà utilisé
-users.validate.usernameRequired=Nom d'utilisateur est requis
-users.validate.usernameTooLong=Nom d'utilisateur ne peut pas contenir plus de 40 caractères
-users.validate.usernameUnique=Nom d'utilisateur doit être unique
+users.validate.usernameInUse=Nom d’utilisateur est déjà utilisé
+users.validate.usernameRequired=Nom d’utilisateur est requis
+users.validate.usernameTooLong=Nom d’utilisateur ne peut pas contenir plus de 40 caractères
+users.validate.usernameUnique=Nom d’utilisateur doit être unique
validate.0to15=Doit être entre 0 et 15 inclus
validate.0toArg=Doit être entre 0 et {0} inclus
validate.1to240=Doit être entre 1 et 240 inclus
@@ -2788,15 +2788,15 @@ validate.duplicateVarName=Duplicat de nom de variable: {0}
validate.fieldName=Un des noms de domaine de requête ou de déclaration de mise à jour doivent être fournis
validate.greaterThan1s=Ne peut pas être moins que 2 secondes
validate.greaterThanDiscardLow=Doit être supérieur à limite basse d'écart
-validate.greaterThanEngLow=Doit être supérieur à l'échelle d'ingénierie d'unité de valeur faible
+validate.greaterThanEngLow=Doit être supérieur à l'échelle d’ingénierie d’unité de valeur faible
validate.greaterThanRawLow=Doit être supérieur à l'échelle de valeur brute faible
validate.greaterThanZero=Doit être supérieur à zéro
validate.illegalValue=Valeur illégale
-validate.imageExtension=Format d'image invalide!
+validate.imageExtension=Format d’image invalide!
validate.invalidAddress=Adresse de capteur invalide: {0}
validate.invalidCharset=Ensemble de noms de caractères invalide
validate.invalidChoice=Choix invalide
-validate.invalidCron=Erreur dans l'expression de cron: {0}
+validate.invalidCron=Erreur dans l’expression de cron: {0}
validate.invalidValue=Valeur invalide
validate.invalidVarName=Nom de variable non valide: {0}
validate.lessThan100=Ne peut pas être > 100
@@ -2809,7 +2809,7 @@ validate.notLessThan30s=Ne peut pas être moins que 30 secondes
validate.notLongerThan=Ne peut pas contenir plus de {0} caractères
validate.pachube.dataStreadIdRequired=id de flux de données est requis
validate.parameterRequired=Nom de paramètre est requis
-validate.parseError=Erreur d'analyse: {0}
+validate.parseError=Erreur d’analyse: {0}
validate.ped.xidMissing=Tous les détecteurs d'évènements doivent définir un XID. Non sauvegardé
validate.ped.xidUsed=Le même XID ''{0}'' est en utilisation pour multiples détecteurs d'évènements. Non sauvegardés
validate.required=Valeur requise
@@ -2842,12 +2842,12 @@ viewEdit.graphic.height=Hauteur
viewEdit.graphic.hideAckColumn=Cacher colonne Ack
viewEdit.graphic.hideAlarmLevelColumn=Cacher colonne de niveau
viewEdit.graphic.hideIdColumn=Cacher ID de colonne
-viewEdit.graphic.hideInactivityColumn=Cacher colonne d'inactivité
+viewEdit.graphic.hideInactivityColumn=Cacher colonne d’inactivité
viewEdit.graphic.hideTimestampColumn=Cacher la colonne des horodatages
viewEdit.graphic.image=Image
viewEdit.graphic.images=Images
-viewEdit.graphic.imageSample=Échantillon d'image
-viewEdit.graphic.imageSet=Ensemble d'images
+viewEdit.graphic.imageSample=Échantillon d’image
+viewEdit.graphic.imageSet=Ensemble d’images
viewEdit.graphic.invalidMinMax=Min doit être inférieur au Max
viewEdit.graphic.invalidScale=Pourcentage d'échelle ne peut pas être inférieur à 1
viewEdit.graphic.invalidState=Valeur d'état non analysable en
@@ -2857,7 +2857,7 @@ viewEdit.graphic.maxListSize=Taille max de liste
viewEdit.graphic.min=Min
viewEdit.graphic.missingDefault=Une image de défault doit être sélectionnée
viewEdit.graphic.missingDynamicImage=Vous devez selectionner une image dynamique
-viewEdit.graphic.missingImageSet=Vous devez selectionner un ensemble d'images
+viewEdit.graphic.missingImageSet=Vous devez selectionner un ensemble d’images
viewEdit.graphic.missingMax=Max doit être saisi
viewEdit.graphic.missingMin=Min doit être saisi
viewEdit.graphic.missingOneImage=Une image une doit être sélectionnée
@@ -2873,7 +2873,7 @@ viewEdit.graphic.runtimeMode=Mode temps de lecture
viewEdit.graphic.saveToLoad=Sauvegardez vue pour charger composante!
viewEdit.graphic.scale=Le Pourcentage d'échelle
viewEdit.graphic.script=Le Script
-viewEdit.graphic.state=Missions d'image/état
+viewEdit.graphic.state=Missions d’image/état
viewEdit.graphic.stateList=Liste d'état
viewEdit.graphic.styleAttribute=Attribut de style
viewEdit.graphic.text=Texte
@@ -2898,7 +2898,7 @@ viewEdit.viewDelete=Supprimer la vue:
viewEdit.viewDeleteConfirm=Confirmer
viedEdit.viewSize=La Taille
views.newView=Nouvelle vue
-views.noViews=Vous n'avez pas créé de vues graphiques. En créer now.
+views.noViews=Vous n'avez pas créé de vues graphiques. En créer
views.title=Vues de graphique
watchlist.addNewList=Ajouter nouvelle liste de surveillance
watchlist.addToWatchlist=Ajouter à la liste de surveillance
@@ -2928,44 +2928,44 @@ dox.radiuinoDS=Source de données Radiuino
dox.radiuinoPP=Point de données Radiuino
dox.scripts=Scripts
dsEdit.asciiSerial.charStopMode.charASCII=Caractère ASCII
-dsEdit.asciiSerial.charX=Jusqu'au caractère C
+dsEdit.asciiSerial.charX=Jusqu’au caractère C
dsEdit.bacnetIp.gettingDeviceDetails=Récupération des informations sur les appareils...
dsEdit.bacnetIp.remoteDeviceNetworkAddress=Adresse du réseau
dsEdit.bacnetIp.remoteDeviceNetworkNumber=Numéro de réseau
dsEdit.iec101.persistent=Persistant
-dsEdit.mbus.id=Identification de l'appareil
+dsEdit.mbus.id=Identification de l’appareil
dsEdit.mbus.man=Man
dsEdit.mbus.phoneNumber=Numéro de téléphone
dsEdit.mbus.responseTimeOutOffset=Décalage de temps
-dsEdit.mbus.secAddrMedium=Support d'adresse sécondaire
+dsEdit.mbus.secAddrMedium=Support d’adresse sécondaire
dsEdit.mbus.tcpAddr=Adresse TCP
dsEdit.mbus.tcpIpBitPerSecond=Bit par séconde du TCP IP
dsEdit.mbus.tcpPort=Port du TCP
dsEdit.mbus.useTcpIpConnection=Utiliser une connexion TCP/IP
dsEdit.mbus.version=Version
-dsEdit.meta.generate.error=Erreur de création de l'histoire: {0}. {1} Mises à jour créées.
-dsEdit.meta.generate=Générer l'histoire
+dsEdit.meta.generate.error=Erreur de création de l’histoire: {0}. {1} Mises à jour créées.
+dsEdit.meta.generate=Générer l’histoire
dsEdit.meta.generate.noData=Pas de données pour le point ''{0}''
-dsEdit.meta.generate.success=L'histoire a été créées avec succès. {0} Mises à jour créées.
+dsEdit.meta.generate.success=L’histoire a été créées avec succès. {0} Mises à jour créées.
dsEdit.meta=Méta source de données
dsEdit.modbus.dpconn3=Contrôle des connexions
dsEdit.modbusIp.createSocketMonitorPoint=Créer un point de surveillance des prises
dsEdit.modbusIp.socketPointName=Surveillances des prises TCP
dsEdit.modbusIp.transportType.tcpListener=Auditeur TCP
-dsEdit.modbus.scanner.startError=Un problème d'exploration s'est posé. Il est possible qu'il y ait une source de données active utilisant le port sélectionné. ({0})
+dsEdit.modbus.scanner.startError=Un problème d’exploration s’est posé. Il est possible qu’il y ait une source de données active utilisant le port sélectionné. ({0})
dsEdit.modbusSerial=Série de Modbus
dsEdit.nodaves7.desc=S7 Iso TCP Ethernet
dsEdit.nodaves7=Contrôleur Ethernet S7 Iso TCP
dsEdit.nodaves7.s7writeBitOffset=Bit de décalage
-dsEdit.nodaves7.s7writeBytesQty=Quantité d'octets
+dsEdit.nodaves7.s7writeBytesQty=Quantité d’octets
dsEdit.nodaves7.s7writeDBNUM=DBNUM
dsEdit.nodaves7.s7writeMemoryArea=Zone de mémoire
dsEdit.nodaves7.s7writeStarts=Décalage de la mémoire (Démarrage)
dsEdit.nodaves7.writeBaseCmd=Write command line
-dsedit.opc.rt.addFailed=L'ajout a échoué pour{0}
+dsedit.opc.rt.addFailed=L’ajout a échoué pour{0}
dsEdit.persistent.getStatus=Obtenir un statut
dsEdit.persistent.status.connection={0}: connexions {1}, {2} paquet reçu
-dsEdit.persistent.status=État d'exécution
+dsEdit.persistent.status=État d’exécution
dsEdit.persistent.status.noConnections=Pas de connexions
dsEdit.persistent.status.notEnabled=Les sources de données ne sont pas activées
dsEdit.radiuino.avancado=Avancé
@@ -2983,7 +2983,7 @@ dsEdit.radiuino.parity=Parité
dsEdit.radiuino.pollingMode.false=Faux
dsEdit.radiuino.pollingMode=Mode de sondage
dsEdit.radiuino.pollingMode.true=Vrai
-dsEdit.radiuino.quantidadeByte=Quantité d'octets
+dsEdit.radiuino.quantidadeByte=Quantité d’octets
dsEdit.radiuino=Radiuino
dsEdit.radiuino.radiuinoDataType.1bUnsigned=Entier (non signé 1 octet)
dsEdit.radiuino.radiuinoDataType.2bUnsigned=Entier (non signé 2 octets)
@@ -2998,10 +2998,10 @@ dsEdit.radiuino.sleepMode.false=Sans repos
dsEdit.radiuino.sleepMode=Mode veille
dsEdit.radiuino.sleepMode.true=Avec repos
dsEdit.radiuino.sleepTime=Temps de repos
-dsEdit.radiuino.stopBits=Bits d'arrêt
+dsEdit.radiuino.stopBits=Bits d’arrêt
dsEdit.radiuino.timeout=Temps mort (ms)
dsEdit.serial.flowControlIn=Contrôle des flux entrant
-dsEdit.serial.inputBufferSize=Taille de la mémoire tampon d'entrée
+dsEdit.serial.inputBufferSize=Taille de la mémoire tampon d’entrée
dsEdit.serial.outputBufferSize=Taille du tampon de sortie
Edit.chart.missingPeriods=La période de temps du graphique doit être fixée
emport.pointValue.missingPoint=Valeur du point''{0}'': Point de données non trouvé
@@ -3012,7 +3012,7 @@ event.persistent.xidTooLong=XID de ""{0}"" point est trop long.
events.export.ackedByDeletedUser=(Utilisateur supprimé)
events.export.ackedByMaintenance=Mode de maintenance
events.export.ackedByUser={0}
-events.export=Evènements sur l'exportation
+events.export=Evènements sur l’exportation
events.search.dateRange=Gamme de données
events.search.dateRange.none=Aucune
events.search.dateRange.relative=Relative
@@ -3037,7 +3037,7 @@ graphic.enhancedImageChart.config.y.max=Y-axis max:
graphic.enhancedImageChart.config.y.min=Y-axis min:
graphic.enhancedImageChart.config.zoomIn=Zoom avant
graphic.enhancedImageChart.config.zoomOut=Zoom arrière
-graphic.enhancedImageChart=Charte d'image améliorée
+graphic.enhancedImageChart=Charte d’image améliorée
graphic.enhancedImageChart.legend=Légende
graphic.enhancedImageChart.point10=Point 10
graphic.enhancedImageChart.point1=Point 1
@@ -3059,7 +3059,7 @@ graphic.enhancedImageChart.seriesConfig.seriesOptions=Options pour {0}:
graphic.enhancedImageChart.seriesConfig.seriesOptions.strokeWidth=Largeur de la course:
graphic.enhancedImageChart.seriesConfig.visibility=Visibilité des séries
graphic.enhancedPoint=Point amélioré
-login.validation.noSuchUser=Impossible de trouver l'identifiant de l'utilisateur
+login.validation.noSuchUser=Impossible de trouver l’identifiant de l’utilisateur
mport.graphicsFolder=Inclure les dossiers graphique
mport.mailingList.prefix=Liste de courrier ''{0}'': {1}
pointDetails.chartDataButton=Importer des données graphiques
@@ -3074,21 +3074,21 @@ publisherEdit.httpSender.point.status=Statut
publisherEdit.httpSender.point.type=Type
publisherEdit.pachube.noPoints=Pas de liste de points
publisherEdit.persistent.getStatus=Obtenir statut
-publisherEdit.persistent.startSync=Synchroniser l'histoire
+publisherEdit.persistent.startSync=Synchroniser l’histoire
publisherEdit.persistent.status.connected=Connecté
publisherEdit.persistent.status.connecting=Point Connecté{0} à {1}
publisherEdit.persistent.status.connectionState=Connexion: {0}
-publisherEdit.persistent.status=Etat d'exécution
+publisherEdit.persistent.status=Etat d’exécution
publisherEdit.persistent.status.notConnected=Pas connecté
publisherEdit.persistent.status.notEnabled=Editeur désactivé
-publisherEdit.persistent.status.packetQueueSize=Fil d'attente d'un paquet: {0}
+publisherEdit.persistent.status.packetQueueSize=Fil d’attente d’un paquet: {0}
publisherEdit.persistent.status.pointCount=Nombre de point: {0}
-publisherEdit.persistent.status.queueSize=Mise à jour de la taille de la file d'attente: {0}
-publisherEdit.persistent.status.syncNotRunning=La synchronisation de l'historique n'est pas active
-publisherEdit.persistent.status.syncStatus=Statut de synchronisation de l'historique: Terminé {0} de {1} points, {2} demandes envoyées
+publisherEdit.persistent.status.queueSize=Mise à jour de la taille de la file d’attente: {0}
+publisherEdit.persistent.status.syncNotRunning=La synchronisation de l’historique n’est pas active
+publisherEdit.persistent.status.syncStatus=Statut de synchronisation de l’historique: Terminé {0} de {1} points, {2} demandes envoyées
publisherEdit.persistent.xidPrefix=XID préfixe
reports.zipData=Données au format .zip
-scripts.execution.scriptError=Echec de l'exécution du script
+scripts.execution.scriptError=Echec de l’exécution du script
scripts.execution.success=Script éxécuté avec succès
systemSettings.chartBackgroundColour=Couleur de fond du graphique
systemSettings.colourSettings=Configuration des couleurs
@@ -3101,23 +3101,23 @@ systemSettings.dbConfiguration.Mysql=MySQL
systemSettings.infoSaved=Les informations deconfiguration ont été sauvegardées
systemSettings.plotBackgroundColour=Couleur de fond du tracé
systemSettings.plotGridlinesColour=Couleur des lignes de quadrillage
-systemSettings.reServer=Redémarrer le serveur d'application
+systemSettings.reServer=Redémarrer le serveur d’application
systemSettings.version=Version de ScadaLTS
systemSettings.customCss.title=Feuille de style personnalisée
systemSettings.customCss.edit=Modifier le fichier
systemSettings.customCss.dialog.title=Modifier le fichier de feuille de style personnalisé
-userProfiles.add=Ajouter un profil d'utilisateur
-userProfiles.added=Profil d'utilisateur ajouté.
-users.dataSaved=Données d'utilisateur sauvegardées
+userProfiles.add=Ajouter un profil d’utilisateur
+userProfiles.added=Profil d’utilisateur ajouté.
+users.dataSaved=Données d’utilisateur sauvegardées
userProfiles.dataSources=Source de données
userProfiles.deleteConfirm=Êtes-vous sûr de vouloir supprimer ce profil ?
-userProfiles.details=Détail du profil d'utilisateur
+userProfiles.details=Détail du profil d’utilisateur
userProfiles.name=Nom du profil
userProfiles.none=Aucun
userProfiles.saved=Profil sauvegardé
-userProfiles.selectName=Profil d'utilisateur
-userProfiles.title=Gérer le profil de l'utilisateur
-userProfiles.validate.errorDeleting=Erreur de détection du profil de l'utilisateur!
+userProfiles.selectName=Profil d’utilisateur
+userProfiles.title=Gérer le profil de l’utilisateur
+userProfiles.validate.errorDeleting=Erreur de détection du profil de l’utilisateur!
userProfiles.validate.nameUnique=Le nom du profil doit être unique et non vide
userProfiles.validate.successDeleting=Profil supprimé avec succès.
viewEdit.compound.point.alias=Alias
@@ -3133,7 +3133,7 @@ viewEdit.fullScreen=Plein écran
watchlist.chartDataButton=Exporter les données des cartes
watchlist.consolidatedChart=Inclure dans le tableau consolidé
watchlist.createReport=Créer un rapport pour cette liste de surveillance
-watchlist.noExportables=Aucun point sélectionné pour l'exploitation
+watchlist.noExportables=Aucun point sélectionné pour l’exploitation
watchlist.imageChartLiveButton=Démarrer/Arrêter graphique en direct
script.execute.success=Exécuté avec succès
script.execute.error=Erreur
@@ -3148,7 +3148,7 @@ menu.compound_event_detectors.tooltip=Détecteurs d'évènement composés
menu.point_links.tooltip=Liens de points
menu.scripting.tooltip=Scénario
menu.users.tooltip=Utilisateurs
-menu.users_profiles.tooltip=Profils d'utilisateurs
+menu.users_profiles.tooltip=Profils d’utilisateurs
menu.point_hierarchy.tooltip=Hiérarchies des points
menu.mailing_lists.tooltip=Listes des diffusions
menu.publishers.tooltip=Editeurs
@@ -3166,12 +3166,12 @@ menu.point_hierarchy.delete.tooltip=Supprimer dossier / Déplacer le point à la
menu.point_hierarchy.refresh.tooltip=Rafraîchir
menu.point_hierarchy.info.tooltip=Information
ds.state.migrationOrErrorSerializeChangeEnableState=Pendant la lecture des données/migration/erreur sur le statut on/off des sources de données a été modifié
-ds.state.stopChangeEnableStateDs=En raison de la non-réponse du serveur externe et de l'arrêt des propriétés, les sources de données ont été arrêtées
-ds.state.userChangeEnableStateDs=L'utilisateur a modifié le statut on/off des sources de données
-ds.state.apiChangeEnableStateDs=Avec l'utilisation de l'API, le statut on/off des sources a été modifié
-ds.state.importChangeEnableStateDs=Lors de l'importation, le statut on/off des sources de données a été modifié
+ds.state.stopChangeEnableStateDs=En raison de la non-réponse du serveur externe et de l’arrêt des propriétés, les sources de données ont été arrêtées
+ds.state.userChangeEnableStateDs=L’utilisateur a modifié le statut on/off des sources de données
+ds.state.apiChangeEnableStateDs=Avec l’utilisation de l’API, le statut on/off des sources a été modifié
+ds.state.importChangeEnableStateDs=Lors de l’importation, le statut on/off des sources de données a été modifié
ds.state.scryptChangeEnable=Le script a changé le statut on/off des sources de données
-ds.state.userCpChangeEnableStateDs=L'utilisateur a copié les sources de données. Les sources de données sont désactivées par défaut
+ds.state.userCpChangeEnableStateDs=L’utilisateur a copié les sources de données. Les sources de données sont désactivées par défaut
dsList.statusDescribe=Description du statut
event.reactivation.sleep=Les sources de données ont été mises en sommeil
event.ds.describe={1}
@@ -3332,4 +3332,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Note:
+sql.warning.prefix=Attention:
+views.noViews.prefix=maintenant.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_lu.properties b/test/messages_lu.properties
index 56025f852b..d46be3fc4d 100644
--- a/test/messages_lu.properties
+++ b/test/messages_lu.properties
@@ -775,7 +775,7 @@ dsEdit.mbus.vifeLabel=Vifes
dsEdit.mbus.vifeLabels=Vife Label
dsEdit.mbus.vifeTypes=Vife Typen
dsEdit.meta=Meta Datenquell
-dsEdit.meta.delay=Berechnungsverz\u00f6gerung
+dsEdit.meta.delay=Berechnungsverz\u00f6gerung
dsEdit.meta.desc=Meta Datenquell Konfiguratioun
dsEdit.meta.event=Aktualis\u00e9ierungsereegnis
dsEdit.meta.event.context=\u00c4nnerung vun den Agangsvariablen
@@ -1179,8 +1179,8 @@ dsEdit.validate.required=Required value
dsEdit.viconics=Viconics Wireless Thermostats
dsEdit.viconics.channel=Channel
dsEdit.viconics.chipRevision=Chip revision
-dsEdit.viconics.chipRevisionBr=Chip
revision
-dsEdit.viconics.commAddress=Comm
address
+dsEdit.viconics.chipRevisionBr=Chip revision
+dsEdit.viconics.commAddress=Comm address
dsEdit.viconics.convertCelsius=Convert temperatures to celsius
dsEdit.viconics.crss=CRSS
dsEdit.viconics.dataSourceNotStarted=Data source is not started
@@ -1189,9 +1189,9 @@ dsEdit.viconics.deviceRemove=Device remove (s)
dsEdit.viconics.deviceWarning=Device offline timeone (s)
dsEdit.viconics.devices=Devices
dsEdit.viconics.dpconn=Port: {0}, PAN ID: {1}, Channel: {2}
-dsEdit.viconics.firmwareRevision=Firmware
revision
+dsEdit.viconics.firmwareRevision=Firmware revision
dsEdit.viconics.ieee=IEEE
-dsEdit.viconics.modelNumber=Model
number
+dsEdit.viconics.modelNumber=Model number
dsEdit.viconics.networkIdentifyFailure=Network identify failed: {0}
dsEdit.viconics.networkInfo=Network information
dsEdit.viconics.networkTimeout=Network offline timeout (s)
@@ -1205,9 +1205,9 @@ dsEdit.viconics.timeout=Message timeout
dsEdit.viconics.trss=TRSS
dsEdit.viconics.unreliable=Point value may not be reliable
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee firmware revision
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
dsEdit.viconics.zigbeeNetworkAddress=Zigbee network address
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
dsEdit.virtual=Virtuell Datenquell
dsEdit.virtual.attractionPoint=Datenpunkt Attraktor
dsEdit.virtual.change=\u00c4nnerung
@@ -1273,17 +1273,17 @@ dsedit.opc.tagName=Tag Tag
emport.added=added
emport.causedBy=caused by:
emport.compoundEvent.prefix=Compound event detector ''{0}'': {1}
-emport.compoundEvent.xid=A compound event detector does not have an 'xid' value. Ignored.
+emport.compoundEvent.xid=A compound event detector does not have an ’xid’ value. Ignored.
emport.confirmImport=Warn: the current database will be erased! Are you sure you want to import a new project?
emport.data=Daten
emport.dataPoint.badReference=Data point with XID ''{0}'' does not already exist and references a data source that does not exist. Ignored.
emport.dataPoint.prefix=Data point ''{0}'': {1}
-emport.dataPoint.xid=A data point with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataPoint.xid=A data point with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.dataPoints=Datenpunkten
-emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
-emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
+emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.dataSource.prefix=Datenquell ''{0}'' : {1}
-emport.dataSource.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataSource.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.error.alarmLevel=Invalid alarm level ''{0}'' for event ''{1}''. Valid values are {2}
emport.error.attractor.missingPoint=Data point with ''{0}'' XID ''{1}'' not found
emport.error.chart.invalid=Chart renderer has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
@@ -1291,7 +1291,7 @@ emport.error.chart.missing=Chart renderer must have a ''{0}''. Valid values are
emport.error.component.imageChart.invalid=Image chart component has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
emport.error.component.imageChart.missing=Image chart component must have a ''{0}''. Valid values are {1}
emport.error.component.imageIndex=Image index {0} is too high for image set ''{1}''. Valid values are 0 to {2}
-emport.error.component.incompatibleDataType=Data point with 'XID' ''{0}'' has a data type that is not compatible with view component type ''{1}''
+emport.error.component.incompatibleDataType=Data point with ’XID’ ''{0}'' has a data type that is not compatible with view component type ''{1}''
emport.error.component.invalid=View component has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
emport.error.component.missing=View component must have a ''{0}''. Valid values are {1}
emport.error.component.unknownDynamicImage=Dynamic image id ''{0}'' not found. Known dynamic image ids are {1}
@@ -1330,7 +1330,7 @@ emport.error.text.missing=Text renderer must have a ''{0}''. Valid values are {1
emport.error.viewShare.missing=Missing ''{0}'' in view share
emport.errorMessage=Errors:
emport.eventHandler.prefix=Point link ''{0}'': {1}
-emport.eventHandler.xid=A point link does not have an 'xid' value. Ignored.
+emport.eventHandler.xid=A point link does not have an ’xid’ value. Ignored.
emport.export=Export
emport.exportDate=Export date
emport.exportJson=Generate JSON
@@ -1353,29 +1353,29 @@ emport.importProjectTitle=Import Project (Upload)
emport.includePointValues=Include point values
emport.indent=Ar\u00e9ckung
emport.invalidFile=File reading failed ({0})
-emport.invalidImportData=Fir ze import\u00e9ierend Daten sinn ong\u00fclteg: keen JSON objet.
+emport.invalidImportData=Fir ze import\u00e9ierend Daten sinn ong\u00fclteg: keen JSON objet. (www.json.org)
emport.invalidProjectName=Invalid name
emport.mailingList.prefix=Mailing list ''{0}'': {1}
-emport.mailingList.xid=A mailing list does not have an 'xid' value. Ignored.
+emport.mailingList.xid=A mailing list does not have an ’xid’ value. Ignored.
emport.maintenanceEvent.prefix=Maintenance event ''{0}'': {1}
-emport.maintenanceEvent.xid=A maintenance event does not have an 'xid' value. Ignored.
+emport.maintenanceEvent.xid=A maintenance event does not have an ’xid’ value. Ignored.
emport.noMessages=No result message. Nothing to import?
emport.parseError=JSON-Parser Fehler: {0}
emport.pointHierarchy.prefix=Datenpunkthierarchie: {0}
emport.pointLink.prefix=Point link ''{0}'': {1}
-emport.pointLink.xid=A point link does not have an 'xid' value. Ignored.
+emport.pointLink.xid=A point link does not have an ’xid’ value. Ignored.
emport.pointValue.missingPoint=Point value ''{0}'': Data point not found
emport.pointValues=Point values
emport.pointValuesMax= Max point values
emport.projectDescription=Description
emport.projectName=Project name
-emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
-emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
+emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.publisher.prefix=Publisher ''{0}'': {1}
-emport.publisher.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.publisher.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.saved=gesp\u00e4ichert
emport.scheduledEvent.prefix=Scheduled event ''{0}'': {1}
-emport.scheduledEvent.xid=A scheduled event does not have an 'xid' value. Ignored.
+emport.scheduledEvent.xid=A scheduled event does not have an ’xid’ value. Ignored.
emport.script.prefix=Script ''{0}'': {1}
emport.select=Mark\u00e9iert, wat Dir export\u00e9ieren w\u00ebllt
emport.selectAll=alles mark\u00e9ieren
@@ -1386,14 +1386,14 @@ emport.unselectAll=all Mark\u00e9ierungen l\u00f6schen
emport.uploadError=Upload failed ({0})
emport.uploadsFolder=Include Uploads folder
emport.user.prefix=Benotzer ''{0} : {1}
-emport.user.username=A user does not have a 'username' value. Ignored.
+emport.user.username=A user does not have a ’username’ value. Ignored.
emport.userPermission.prefix=Recte fir Benotzer ''{0}'' : {1}
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
-emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.versionError=The project version ({0}) isn’t compatible with current system version ({1})
+emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
emport.view.prefix=Prozessbild ''{0}'' : {1}
-emport.view.xid=A graphical view does not have an 'xid' value. Ignored.
+emport.view.xid=A graphical view does not have an ’xid’ value. Ignored.
emport.watchList.prefix=Watch list ''{0}'': {1}
-emport.watchList.xid=A watch list does not have an 'xid' value. Ignored.
+emport.watchList.xid=A watch list does not have an ’xid’ value. Ignored.
engUnit.0=square meters
engUnit.1=square feet
engUnit.10=megavolt amperes
@@ -1586,8 +1586,8 @@ engUnit.98=percent
engUnit.99=percent per second
engUnit.190=kilometers
engUnit.abbr.190=km
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.10=megavolt amperes
engUnit.abbr.100=per minute
engUnit.abbr.101=per second
@@ -1808,7 +1808,7 @@ event.alarmMaxDecreased=H\u00e9chsten Alarmpriorit\u00e9it huet sech vun {0} op
event.alarmMaxIncreased=H\u00e9chsten Alarmpriorit\u00e9it huet sech vun {0} op {1} erh\u00e9icht
event.audit.added=Benotzer "{0}" huet {1} mat id {2}: {3} erzeugt
event.audit.changed=Benotzer "{0}" huet {1} mat id {2}: {3} ge\u00e4nnert
-event.audit.changedProperty=
{0}: "{1}" zu "{2}"
+event.audit.changedProperty={0}: "{1}" zu "{2}"
event.audit.compoundEventDetector=Compound event detector
event.audit.dataPoint=Datenpunkt
event.audit.dataSource=Datenquell
@@ -1817,7 +1817,7 @@ event.audit.eventHandler=Event handler
event.audit.maintenanceEvent=Maintenance event
event.audit.pointEventDetector=Point event detector
event.audit.pointLink=Point link
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2072,8 +2072,8 @@ event.valueParse.generalParsePoint={0}, result={1}, point={2}
event.valueParse.noData=No data to match against for point {0}
event.valueParse.noTime=No time match made {0}
event.valueParse.noValue=No value match made for point {0}
-event.valueParse.numericParse=Couldn't parse to numeric, result={0}
-event.valueParse.numericParsePoint=Couldn't parse to numeric, result={0}, point={1}
+event.valueParse.numericParse=Couldn’t parse to numeric, result={0}
+event.valueParse.numericParsePoint=Couldn’t parse to numeric, result={0}, point={1}
event.valueParse.textParse=Value did not match any multistate text and was not parsable, result={0}
event.valueParse.textParsePoint=Value did not match any multistate text and was not parsable, result={0}, point={1}
event.valueParse.timeParse=Failed to parse time "{0}"
@@ -2112,7 +2112,7 @@ eventHandlers.inactiveNotif=Benoriichtegung gaang
eventHandlers.inactiveOverride=Override inactive recipients
eventHandlers.inactiveRecipients=Inactive recipients
eventHandlers.inactiveScript=When inactive script
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
eventHandlers.invalidActiveSource=Invalid active source point
eventHandlers.invalidActiveSourceType=Invalid active source point data type
eventHandlers.invalidActiveValue=Invalid active value to set
@@ -2122,14 +2122,14 @@ eventHandlers.invalidInactiveSourceType=Invalid inactive source point data type
eventHandlers.invalidInactiveValue=Invalid inactive value to set
eventHandlers.invalidScripts=Selecione ao menos um script
eventHandlers.maintenanceEvents=Maintenance events
-eventHandlers.noEmailRecips=Keen Email Empf\u00e4nger!
Dir musst mindestens een Email Empf\u00e4nger b\u00e4if\u00fcgen
-eventHandlers.noEscalRecips=Keng Eskalatiouns Email Empf\u00e4nger!
Dir musst mindestens een Eskalatiouns Email Empf\u00e4nger b\u00e4if\u00fcgen
+eventHandlers.noEmailRecips=Keen Email Empf\u00e4nger! Dir musst mindestens een Email Empf\u00e4nger b\u00e4if\u00fcgen
+eventHandlers.noEscalRecips=Keng Eskalatiouns Email Empf\u00e4nger! Dir musst mindestens een Eskalatiouns Email Empf\u00e4nger b\u00e4if\u00fcgen
eventHandlers.noInactiveRecips=You must add inactive recipients
eventHandlers.noSetPointAction=No set point action has been defined
eventHandlers.noTargetPoint=No target point selected. You may not have any settable points defined.
eventHandlers.pointEventDetector=Datenpunktereegnisser
eventHandlers.publisherEvents=Ereegnisser Ver\u00f6ffentlechung
-eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler's email recipient list
+eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler’s email recipient list
eventHandlers.recipientType.active=Active
eventHandlers.recipientType.escalation=Escalation
eventHandlers.recipientType.inactive=Inactive
@@ -2348,7 +2348,7 @@ login.nag=Hiweis: et ass m\u00e9iglech dat Dir Problemer mat ScadaLTS hutt, well
login.password=Passwuert
login.supportedBrowser=D\u00ebse Browser g\u00ebtt \u00ebnnerst\u00ebtzt
login.unknownBrowser=Onbekannte Browser
-login.unsupportedBrowser=D\u00ebse Browser g\u00ebtt offiziell net vun Serotonin Software \u00ebnnerst\u00ebtzt. Mir empfielen Firefox, Chrome, oder Internet Explorer 7.
+login.unsupportedBrowser=D\u00ebse Browser g\u00ebtt offiziell net vun Serotonin Software \u00ebnnerst\u00ebtzt. Mir empfielen Mozilla Firefox, Google Chrome.
login.userId=Benotzernumm
login.validation.accountDisabled=\u00c4ren Account gouf gespaart, wennt Iech w.e.g un \u00c4ren Administrator
login.validation.invalidLogin=Login gescheitert, bitte prob\u00e9iert et nach eng K\u00e9ier
@@ -2421,7 +2421,7 @@ notes.timeByUsername=Z\u00e4itstempel an Benotzer
notes.userNotes=Bemierkungen
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pagination.ascending=Opsteigend
pagination.descending=Ofsteigend
pagination.next=N\u00e4chst(en)
@@ -2466,7 +2466,7 @@ pointDetails.username=Benotzernumm
pointDetails.views=Usichten
pointEdit.buttons.disable=Ausschalten
pointEdit.buttons.enable=Aschalten
-pointEdit.buttons.note=Hinweis: sp\u00e4icheren, deaktiv\u00e9ieren oder nei starten setzen all aktiven Ereegnisse zer\u00e9ck.
+pointEdit.buttons.note=sp\u00e4icheren, deaktiv\u00e9ieren oder nei starten setzen all aktiven Ereegnisse zer\u00e9ck.
pointEdit.buttons.restart=Neistart
pointEdit.chart.includeSum=Zomm berechnen
pointEdit.chart.invalidLimit=Tabell: Unzuel muss zw\u00ebschen 2 an 50 leien
@@ -2615,7 +2615,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -2777,7 +2777,7 @@ reports.pointComments=Point comments
reports.pointComments.empty=No point comments to list
reports.pointName=Numm
reports.previous=Vorherige(r)
-reports.recipTestEmailMessage=This message was sent as a test of a report's email recipient list
+reports.recipTestEmailMessage=This message was sent as a test of a report’s email recipient list
reports.relative=Relativ zur Erstellungsz\u00e4it
reports.rendered=Erstellt
reports.report=Report
@@ -2856,7 +2856,7 @@ sql.query=SQL-Offro starten
sql.rowsUpdated=Datens\u00e4tz aktualis\u00e9iert
sql.sql=SQL
sql.update=SQL-Update ausf\u00e9ieren
-sql.warning=Achtung: Benotzt d’SQL Offro mat Virsiicht. Benotzerfehler kennen zu Datenverloscht an/oder Fehlfunktiounen vum System f\u00e9ieren..
+sql.warning=Benotzt d'SQL Offro mat Virsiicht. Benotzerfehler kennen zu Datenverloscht an/oder Fehlfunktiounen vum System f\u00e9ieren.
systemSettings.auditAlarmLevels=Audit event alarm levels
systemSettings.auditAlarmLevelsSaved=Audit event alarm levels have been saved
systemSettings.auth=Server erfuerdert Legitimatioun
@@ -3058,7 +3058,7 @@ viewEdit.compound.type.static=Static
viewEdit.compound.width=Breet
viewEdit.deletePointView=Delete point component
viewEdit.deleteStaticView=Delete static content
-viewEdit.deleteView=Remove yourself from the view's share list
+viewEdit.deleteView=Remove yourself from the view’s share list
viewEdit.editGraphicalRenderer=Beaarbecht Duerstellung
viewEdit.editPointView=Beaarbecht Datenpunkt vum Bausteen
viewEdit.editStaticView=Edit static content
@@ -3129,7 +3129,7 @@ viewEdit.viewDelete=Delete view:
viewEdit.viewDeleteConfirm=Confirm
viedEdit.viewSize=Size
views.newView=Nei Prozessusicht
-views.noViews=Dir hutt nach kee Prozessbild. Erstellt een jetzt .
+views.noViews=Dir hutt nach kee Prozessbild. Erstellt een
views.title=Prozessbild
watchlist.addNewList=Nei Beobachtungslescht
watchlist.addToWatchlist=Zur Beobachtungslescht b\u00e4if\u00fcgen
@@ -3351,4 +3351,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+annotation.api=REST API
+pointEdit.buttons.note.prefix=Hinweis:
+sql.warning.prefix=Warnung:
+views.noViews.prefix=elo.
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_nl.properties b/test/messages_nl.properties
index cc838b5d15..b88d94b018 100644
--- a/test/messages_nl.properties
+++ b/test/messages_nl.properties
@@ -665,7 +665,7 @@ dsEdit.meta.event.week=Start van week
dsEdit.meta.event.month=Start van maand
dsEdit.meta.event.year=Start van jaar
dsEdit.meta.event.cron=Cron patroon
-dsEdit.meta.delay=Uitvoering vertraging
+dsEdit.meta.delay=Uitvoering vertraging
dsEdit.meta.test.success=Succes. resultaat={0}
dsEdit.meta.test.successTs=Success. resultaat={0}, tijdstempel={1}
dsEdit.meta.test.context=Een of meer punten zijn uitgeschakeld of missen
@@ -947,16 +947,16 @@ dsEdit.viconics.networkInfo=Netwerk informatie
dsEdit.viconics.refreshing=Verversen...
dsEdit.viconics.rfModule=RF Module
dsEdit.viconics.devices=Devices
-dsEdit.viconics.commAddress=Comm
adres
-dsEdit.viconics.modelNumber=Model
nummer
-dsEdit.viconics.firmwareRevision=Firmware
revisie
+dsEdit.viconics.commAddress=Comm adres
+dsEdit.viconics.modelNumber=Model nummer
+dsEdit.viconics.firmwareRevision=Firmware revisie
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee firmware revisie
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revisie
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revisie
dsEdit.viconics.zigbeeNetworkAddress=Zigbee netwerk adres
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
netwerk
adres
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee netwerk adres
dsEdit.viconics.ieee=IEEE
dsEdit.viconics.chipRevision=Chip revisie
-dsEdit.viconics.chipRevisionBr=Chip
revisie
+dsEdit.viconics.chipRevisionBr=Chip revisie
dsEdit.viconics.trss=TRSS
dsEdit.viconics.crss=CRSS
@@ -1075,38 +1075,38 @@ emport.importProgress=Bezig met importeren...
emport.importCancelled=Import afgebroken
emport.importComplete=Import gereed
emport.noMessages=Geen resultaat bericht. Niets te importeren ?
-emport.invalidImportData=Import data is ongeldig: geen JSON object
+emport.invalidImportData=Import data is ongeldig: geen JSON object. (www.json.org)
emport.parseError=JSON parse fout: {0}
-emport.user.username=Een gebruiker heeft geen 'gebruiker' waarde. Genegeerd.
+emport.user.username=Een gebruiker heeft geen ’gebruiker’ waarde. Genegeerd.
emport.user.prefix=Gebruiker ''{0}'': {1}
-emport.view.missingType=View met XID ''{0}'' bestaat nog niet en heeft geen 'type' waarde. Geldige typen zijn {1}
-emport.dataSource.xid=Een gegevensbron met naam ''{0}'' heeft geen 'xid' waarde. Genegeerd.
-emport.dataSource.missingType=gegevensbron met XID ''{0}'' bestaat nog niet en heeft geen 'type' waarde. Geldige typen zijn {1}
-emport.dataSource.invalidType="gegevensbron met XID ''{0}'' bestaat nog niet en heeft een ongeldige 'type' waarde van ''{1}''. Geldige typen zijn {2}
+emport.view.missingType=View met XID ''{0}'' bestaat nog niet en heeft geen ’type’ waarde. Geldige typen zijn {1}
+emport.dataSource.xid=Een gegevensbron met naam ''{0}'' heeft geen ’xid’ waarde. Genegeerd.
+emport.dataSource.missingType=gegevensbron met XID ''{0}'' bestaat nog niet en heeft geen ’type’ waarde. Geldige typen zijn {1}
+emport.dataSource.invalidType="gegevensbron met XID ''{0}'' bestaat nog niet en heeft een ongeldige ’type’ waarde van ''{1}''. Geldige typen zijn {2}
emport.dataSource.prefix=gegevensbron ''{0}'': {1}
-emport.dataPoint.xid=A data punt met naam ''{0}'' heeft geen 'xid' waarde. Genegeerd.
+emport.dataPoint.xid=A data punt met naam ''{0}'' heeft geen ’xid’ waarde. Genegeerd.
emport.dataPoint.badReference=Data punt met XID ''{0}'' bestaat nog niet en refereert naar een gegevensbron die nog niet bestaat. Genegeerd.
emport.dataPoint.prefix=Data punt ''{0}'': {1}
emport.userPermission.prefix=Rechten voor gebruiker ''{0}'': {1}
emport.added=toegevoegd
emport.saved=opgeslagen
emport.causedBy=veroorzaakt door:
-emport.view.xid=Een grafische view heeft geen 'xid' waarde. Genegeerd.
+emport.view.xid=Een grafische view heeft geen ’xid’ waarde. Genegeerd.
emport.view.prefix=View ''{0}'': {1}
emport.pointHierarchy.prefix=Punt hiërarchie: {0}
-emport.pointLink.xid=Een punt link heeft geen 'xid' waarde. Genegeerd.
+emport.pointLink.xid=Een punt link heeft geen ’xid’ waarde. Genegeerd.
emport.pointLink.prefix=Punt link ''{0}'': {1}
-emport.scheduledEvent.xid=Een geplande gebeurtenis heeft geen 'xid' waarde. Genegeerd.
+emport.scheduledEvent.xid=Een geplande gebeurtenis heeft geen ’xid’ waarde. Genegeerd.
emport.scheduledEvent.prefix=Geplande gebeurtenis ''{0}'': {1}
-emport.compoundEvent.xid=Een samengestelde gebeurtenis detector heeft geen 'xid' waarde. Genegeerd.
+emport.compoundEvent.xid=Een samengestelde gebeurtenis detector heeft geen ’xid’ waarde. Genegeerd.
emport.compoundEvent.prefix=Samengestelde gebeurtenis detector ''{0}'': {1}
-emport.mailingList.xid=Een mailing lijst heeft geen 'xid' waarde. Genegeerd.
+emport.mailingList.xid=Een mailing lijst heeft geen ’xid’ waarde. Genegeerd.
emport.mailingList.prefix=Mailing lijst ''{0}'': {1}
-emport.eventHandler.xid=Een punt link heeft geen 'xid' waarde. Genegeerd.
+emport.eventHandler.xid=Een punt link heeft geen ’xid’ waarde. Genegeerd.
emport.eventHandler.prefix=Punt link ''{0}'': {1}
-emport.publisher.xid=Een data bron met naam ''{0}'' heeft geen 'xid' waarde. 'xid' value. Genegeerd.
-emport.publisher.missingType=Publisher met XID ''{0}'' bestaat nog niet en heeft geen 'type' waarde. Geldige types zijn {1}
-emport.publisher.invalidType=Publisher met XID ''{0}'' bestaat nog niet en heeft geen geldige 'type' waarde. 'type' waarde van ''{1}''. Geldige types zijn {2}
+emport.publisher.xid=Een data bron met naam ''{0}'' heeft geen ’xid’ waarde. ’xid’ value. Genegeerd.
+emport.publisher.missingType=Publisher met XID ''{0}'' bestaat nog niet en heeft geen ’type’ waarde. Geldige types zijn {1}
+emport.publisher.invalidType=Publisher met XID ''{0}'' bestaat nog niet en heeft geen geldige ’type’ waarde. ’type’ waarde van ''{1}''. Geldige types zijn {2}
emport.publisher.prefix=Publisher ''{0}'': {1}
eventHandlers.recipTestEmailMessage=Dit bericht was verzonden om een email ontangstlijst van een gebeurtenis afhandelaar te testen
@@ -1228,8 +1228,7 @@ login.loginButton=Inloggen
login.unknownBrowser=Bezig met controleren browser voor compatibiliteit...
login.supportedBrowser=Deze browser is ondersteund.
login.unsupportedBrowser=Het kan zijn dat uw browser wel werkt met dit product, maar het is niet officieel ondersteund door Serotonin \
-Software. Wij adviseren het gebruik van Firefox, Chrome, of \
-Internet Explorer 7.
+Software. Wij adviseren het gebruik van Mozilla Firefox, Google Chrome.
login.nag=NB: Het kan zijn dat u problemen ondervindt met ScadaLTS omdat uw browser niet officieel is ondersteund. Upgrade uw browser s.v.p.
mailingLists.added=Mailing lijst toegevoegd
@@ -1261,7 +1260,7 @@ notes.cancel=Afbreken
notes.timeByUsername=tijd door gebruikersnaam
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pointDetails.recordCountError=Record teller moet een getal zijn
pointDetails.timePeriodError=Tijd periode moet een getal zijn
pointDetails.imageCountError=Afbeelding teller moet een getal zijn
@@ -1297,7 +1296,7 @@ pointDetails.accessType=Toegangstype
pointEdit.buttons.enable=Inschakelen
pointEdit.buttons.disable=Uitschakelen
pointEdit.buttons.restart=Herstart
-pointEdit.buttons.note=Noot: opslaan, uitschakelen, of herstarten van een punt heeft tot gevolg dat alle actieve gebeurtenissen terugkeren naar normaal.
+pointEdit.buttons.note=opslaan, uitschakelen, of herstarten van een punt heeft tot gevolg dat alle actieve gebeurtenissen terugkeren naar normaal.
pointEdit.chart.props=Grafiek generator eigenschappen
pointEdit.chart.type=Type
@@ -1450,7 +1449,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -1647,7 +1646,7 @@ scheduledEvents.validate.inactiveTrigger=Fout bij aanmaken inactieve trigger: {0
scheduledEvents.validate.aliasTooLong=Alias kan niet langer zijn dan 50 karakters
scheduledEvents.validate.invalidRtn=Inactief tijd moet na actief tijd komen
-sql.warning=Waarschuwing: gebruik deze faciliteit op eigen risico. Incorrect gebruik kan leiden tot beschadigde data en/of systeem storing.
+sql.warning=gebruik deze faciliteit op eigen risico. Incorrect gebruik kan leiden tot beschadigde data en/of systeem storing.
sql.sql=SQL
sql.query=Invoeren query
sql.update=Invoeren update
@@ -1665,8 +1664,8 @@ systemSettings.upToDate=Deze instantie van Mango is up to date
systemSettings.emailSettings=Email instellingen
systemSettings.smtpHost=SMTP host
systemSettings.smtpPort=SMTP poort
-systemSettings.fromAddress='Van' adres
-systemSettings.fromName='Van' naam
+systemSettings.fromAddress=’Van’ adres
+systemSettings.fromName=’Van’ naam
systemSettings.auth=Gebruik autorisatie
systemSettings.smtpUsername=Gebruikersnaam
systemSettings.smtpPassword=Wachtwoord
@@ -1816,7 +1815,7 @@ viewEdit.compound.duration=Duur
views.title=Grafische views
views.newView=Nieuwe view
-views.noViews=Er zijn nog geen grafische views aangemaakt. Maak er nu een aan.
+views.noViews=Er zijn nog geen grafische views aangemaakt. Maak er
viewEdit.viewDelete=Delete view:
viewEdit.viewDeleteConfirm=Confirm
@@ -1918,7 +1917,7 @@ event.system.process=Proces gebeurtenis handler gefaald
event.audit.added=User "{0}" aangemaakt {1} met id {2}: {3}
event.audit.changed=User "{0}" veranderd {1} met id {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" to "{2}"
+event.audit.changedProperty={0}: "{1}" to "{2}"
event.audit.compoundEventDetector=Samengestelde gebeurtenis detector
event.audit.dataPoint=Data punt
event.audit.dataSource=Data bron
@@ -1927,7 +1926,7 @@ event.audit.eventHandler=Gebeurtenis handler
event.audit.maintenanceEvent=Maintenance event
event.audit.pointEventDetector=Punt gebeurtenis detector
event.audit.pointLink=Punt link
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2267,7 +2266,7 @@ emport.error.eventCode=Ongeldige gebeurtenis code ''{0}''. Geldig codes zijn {1}
emport.error.alarmLevel=Ongeldig alarm niveau ''{0}'' voor gebeurtenis ''{1}''. Geldige waarden zijn {2}
emport.error.missingUser=Gebruiker met gebruikersnaam ''{0}'' niet gevonden
emport.error.viewShare.missing=Ontbrekende ''{0}'' in gedeelde view
-emport.error.component.incompatibleDataType=Data punt met 'XID' ''{0}'' heeft een data type die niet compatibel is met view component type ''{1}''
+emport.error.component.incompatibleDataType=Data punt met ’XID’ ''{0}'' heeft een data type die niet compatibel is met view component type ''{1}''
emport.error.compound.invalidChildId=Ongeldig child id ''{0}'' voor samengestelde view component van type ''{1}''. Geldige ids zijn {2}
emport.error.component.unknownDynamicImage=Dynamische afbeelding id ''{0}'' niet gevonden. Bekende dynamische afbeelding ids zijn {1}
emport.error.component.unknownImageSet=Afbeelding set id ''{0}'' niet gevonden. Bekende afbeelding set ids zijn {1}
@@ -2482,8 +2481,8 @@ engUnit.188=newton per meter
engUnit.189=watt per meter per graden kelvin
engUnit.190=kilometers
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.2=mA
engUnit.abbr.3=A
engUnit.abbr.4=ohms
@@ -2889,7 +2888,7 @@ emport.exportProjectInstruction=Select your options and download the project fil
pointEdit.props.chartColour=Chart color
eventHandlers.activeScript=When active script
dox.drStorageHt5bDS=Data Source Dr.StorageHT-5B
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
dox.colours=Color
emport.projectName=Project name
dsEdit.fhz4j.deviceHousecode=Device Housecode
@@ -2961,7 +2960,7 @@ dsEdit.jmx.writeFailed=Write failed for ''{0}''
viewEdit.graphic.views=Views
dsEdit.asciiSerial.desc=ASCII Serial Properties
graphic.enhancedImageChart.seriesConfig.seriesOptions.strokeWidth=Stroke width\:
-emport.watchList.xid=A watch list does not have an 'xid' value. Ignored.
+emport.watchList.xid=A watch list does not have an ’xid’ value. Ignored.
reports.zipData=Data in .zip format
events.silenceAll=Silence all
viewEdit.graphic.whenOffLabel=Label when OFF (0, false)
@@ -2969,7 +2968,7 @@ viewEdit.graphic.text=Text
script.dpCommands=Datapoints commands
dsEdit.asciiSerial.stopMode=Stop mode
dsEdit.nodaves7.writeBaseCmd=Write command line
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
+emport.versionError=The project version ({0}) is’ compatible with current system version ({1})
events.export.ackedByDeletedUser=(user deleted)
dsEdit.jmx.attributeName=Attribute name
dsEdit.opc.tagName=Tag Name
@@ -3183,7 +3182,7 @@ publisherEdit.persistent.status.connecting=Connected point {0} of {1}
emport.systemSettingsFailed=System configuration export error
dsEdit.serial.inputBufferSize=Input Buffer Size
viewEdit.compound.type.static=Static
-emport.maintenanceEvent.xid=A maintenance event does not have an 'xid' value. Ignored.
+emport.maintenanceEvent.xid=A maintenance event does not have an ’xid’ value. Ignored.
dsEdit.modbusIp.socketPointName=TCP socket monitoring
scripts.seDetails=Script details
watchlist.consolidatedChart=Include in consolidated chart
@@ -3454,4 +3453,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Noot:
+sql.warning.prefix=Waarschuwing:
+views.noViews.prefix=nu een aan.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_pl.properties b/test/messages_pl.properties
index aef65b4b72..fe996d18cf 100644
--- a/test/messages_pl.properties
+++ b/test/messages_pl.properties
@@ -195,7 +195,7 @@ js.help.error=B\u0142\u0105d
js.help.related=Powi\u0105zane przedmioty
js.help.lastUpdated=Ostatnio zaktualizowany
js.email.noRecipients=Brak odbiorc\u00f3w
-js.email.addMailingList=Dodaj list\u0119 mail'ingow\u0105
+js.email.addMailingList=Dodaj list\u0119 mail’ingow\u0105
js.email.addUser=Dodaj u\u017cytkownika
js.email.addAddress=Dodaj adres
js.email.noRecipForEmail=Brak odbiorc\u00f3w do wys\u0142ania testowego e-maila
@@ -679,7 +679,7 @@ dsEdit.meta.event.week=Start of week
dsEdit.meta.event.month=Start of month
dsEdit.meta.event.year=Start of year
dsEdit.meta.event.cron=Cron pattern
-dsEdit.meta.delay=Execution delay
+dsEdit.meta.delay=Execution delay
dsEdit.meta.test.success=Success. result={0}
dsEdit.meta.test.successTs=Success. result={0}, timestamp={1}
dsEdit.meta.test.context=One or more points are disabled or missing
@@ -761,7 +761,7 @@ dsEdit.modbusIp.transportType.udp=UDP
dsEdit.modbusIp.host=Host
dsEdit.modbusIp.port=Port
dsEdit.modbusIp.encapsulated=Encapsulated
-dsEdit.modbusIp.createSocketMonitorPoint=Stw\u00f3rz punkt monitorowania socket'u
+dsEdit.modbusIp.createSocketMonitorPoint=Stw\u00f3rz punkt monitorowania socket’u
dsEdit.modbusSerial=Modbus Serial
dsEdit.modbusSerial.port=Port
@@ -983,16 +983,16 @@ dsEdit.viconics.networkInfo=Network information
dsEdit.viconics.refreshing=Refreshing...
dsEdit.viconics.rfModule=RF Module
dsEdit.viconics.devices=Devices
-dsEdit.viconics.commAddress=Comm
address
-dsEdit.viconics.modelNumber=Model
number
-dsEdit.viconics.firmwareRevision=Firmware
revision
+dsEdit.viconics.commAddress=Comm address
+dsEdit.viconics.modelNumber=Model number
+dsEdit.viconics.firmwareRevision=Firmware revision
dsEdit.viconics.zigbeeFirmwareRevision=Zigbee firmware revision
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
dsEdit.viconics.zigbeeNetworkAddress=Zigbee network address
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
dsEdit.viconics.ieee=IEEE
dsEdit.viconics.chipRevision=Chip revision
-dsEdit.viconics.chipRevisionBr=Chip
revision
+dsEdit.viconics.chipRevisionBr=Chip revision
dsEdit.viconics.trss=TRSS
dsEdit.viconics.crss=CRSS
dsEdit.viconics.unreliable=Point value may not be reliable
@@ -1135,49 +1135,49 @@ emport.importProgress=Import in progress...
emport.importCancelled=Import cancelled
emport.importComplete=Import complete
emport.noMessages=No result message. Nothing to import?
-emport.invalidImportData=Import data is invalid: not a JSON object
+emport.invalidImportData=Import data is invalid: not a JSON object. (www.json.org)
emport.parseError=JSON parse error: {0}
-emport.user.username=A user does not have a 'username' value. Ignored.
+emport.user.username=A user does not have a ’username’ value. Ignored.
emport.user.prefix=User ''{0}'': {1}
-emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
-emport.dataSource.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
-emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
-emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
+emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
+emport.dataSource.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
+emport.dataSource.missingType=Data source with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
+emport.dataSource.invalidType=Data source with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
emport.dataSource.prefix=Data source ''{0}'': {1}
-emport.dataPoint.xid=A data point with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataPoint.xid=A data point with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.dataPoint.badReference=Data point with XID ''{0}'' does not already exist and references a data source that does not exist. Ignored.
emport.dataPoint.prefix=Data point ''{0}'': {1}
emport.userPermission.prefix=Permissions for user ''{0}'': {1}
emport.added=dodano
emport.saved=zapisano
emport.causedBy=przez:
-emport.view.xid=A graphical view does not have an 'xid' value. Ignored.
+emport.view.xid=A graphical view does not have an ’xid’ value. Ignored.
emport.view.prefix=View ''{0}'': {1}
emport.pointHierarchy.prefix=Point hierarchy: {0}
-emport.pointLink.xid=A point link does not have an 'xid' value. Ignored.
+emport.pointLink.xid=A point link does not have an ’xid’ value. Ignored.
emport.pointLink.prefix=Point link ''{0}'': {1}
-emport.scheduledEvent.xid=A scheduled event does not have an 'xid' value. Ignored.
+emport.scheduledEvent.xid=A scheduled event does not have an ’xid’ value. Ignored.
emport.scheduledEvent.prefix=Scheduled event ''{0}'': {1}
-emport.compoundEvent.xid=A compound event detector does not have an 'xid' value. Ignored.
+emport.compoundEvent.xid=A compound event detector does not have an ’xid’ value. Ignored.
emport.compoundEvent.prefix=Compound event detector ''{0}'': {1}
-emport.mailingList.xid=A mailing list does not have an 'xid' value. Ignored.
+emport.mailingList.xid=A mailing list does not have an ’xid’ value. Ignored.
emport.mailingList.prefix=Mailing list ''{0}'': {1}
-emport.eventHandler.xid=A point link does not have an 'xid' value. Ignored.
+emport.eventHandler.xid=A point link does not have an ’xid’ value. Ignored.
emport.eventHandler.prefix=Point link ''{0}'': {1}
-emport.publisher.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
-emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
-emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
+emport.publisher.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
+emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
+emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
emport.publisher.prefix=Publisher ''{0}'': {1}
-emport.watchList.xid=A watch list does not have an 'xid' value. Ignored.
+emport.watchList.xid=A watch list does not have an ’xid’ value. Ignored.
emport.watchList.prefix=Watch list ''{0}'': {1}
-emport.maintenanceEvent.xid=A maintenance event does not have an 'xid' value. Ignored.
+emport.maintenanceEvent.xid=A maintenance event does not have an ’xid’ value. Ignored.
emport.maintenanceEvent.prefix=Maintenance event ''{0}'': {1}
-eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler's email recipient list
+eventHandlers.recipTestEmailMessage=This message was sent as a test of an event handler’s email recipient list
eventHandlers.emailRecipients=Email recipients
-eventHandlers.escalTestEmailMessage=This message was sent as a test of an event handler's escalation list
+eventHandlers.escalTestEmailMessage=This message was sent as a test of an event handler’s escalation list
eventHandlers.escalRecipients=Escalation recipients
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
eventHandlers.inactiveRecipients=Inactive recipients
eventHandlers.noEmailRecips=You must add email recipients
eventHandlers.escalDelayError=Escalation delay must be greater than zero
@@ -1267,7 +1267,7 @@ events.ackedByMaintenance=- maintanance mode
footer.rightsReserved=Wszystkie prawa zastrze\u017cone.
-header.title=ScadaJR
+header.title=Scada-LTS
header.mute=Wycisz
header.unmute=Wy\u0142\u0105cz wyciszenie
header.watchlist=Listy podgl\u0105du punkt\u00f3w
@@ -1309,12 +1309,11 @@ login.validation.accountDisabled=twoje konto zosta\u0142o zablokowane. Skontaktu
login.loginButton=Zaloguj
login.unknownBrowser=Kontrola zgodno\u015bci przegl\u0105darki...
login.supportedBrowser=Ta przegl\u0105darka jest obs\u0142ugiwana.
-login.unsupportedBrowser=Twoja przegl\u0105darka mo\u017ce dzia\u0142a\u0107 poprawnie, ale nie jest oficjalnie wspierana. Rekomendujemy u\u017cywanie Firefox, Chrome, lub \
-Internet Explorer 7.
+login.unsupportedBrowser=Twoja przegl\u0105darka mo\u017ce dzia\u0142a\u0107 poprawnie, ale nie jest oficjalnie wspierana. Rekomendujemy u\u017cywanie Mozilla Firefox, Google Chrome.
login.nag=NOTATKA: mo\u017cesz mie\u0107 problemy poniewa\u017c u\u017cywasz nie wspieranej przegl\u0105darki.
-mailingLists.added=Lista mail'ingowa dodana
-mailingLists.saved=Lista mail'ingowa zapisana
+mailingLists.added=Lista mail’ingowa dodana
+mailingLists.saved=Lista mail’ingowa zapisana
mailingLists.testEmailMessage=Test email has been sent
mailingLists.noUser=No user found to add
mailingLists.noAddress=Enter the email address before adding to the list
@@ -1414,7 +1413,7 @@ pointDetails.accessType=Typ dost\u0119pu
pointEdit.buttons.enable=Odblokuj
pointEdit.buttons.disable=Zablokuj
pointEdit.buttons.restart=Zrestartuj
-pointEdit.buttons.note=Notatka: saving, disabling, or restarting a point causes all active events to be returned to normal.
+pointEdit.buttons.note=saving, disabling, or restarting a point causes all active events to be returned to normal.
pointEdit.chart.props=Chart renderer properties
pointEdit.chart.type=Type
@@ -1633,7 +1632,7 @@ publisherList.config=Configuration
publisherList.status=status
publisherList.noRows=No rows
-reports.recipTestEmailMessage=This message was sent as a test of a report's email recipient list
+reports.recipTestEmailMessage=This message was sent as a test of a report’s email recipient list
reports.emailRecipients=Email recipients
reports.export=Export data
reports.eventExport=Export events
@@ -1732,7 +1731,7 @@ scheduledEvents.validate.inactiveTrigger=Error creating inactive trigger: {0}
scheduledEvents.validate.aliasTooLong=Alias cannot be longer than 50 characters
scheduledEvents.validate.invalidRtn=Inactive time must be after active time
-sql.warning=Warning: use this facility at your own risk. Incorrect usage may result in corrupted data and/or system failures.
+sql.warning=use this facility at your own risk. Incorrect usage may result in corrupted data and/or system failures.
sql.sql=SQL
sql.query=Submit query
sql.update=Submit update
@@ -1750,8 +1749,8 @@ systemSettings.upToDate=This instance of Scada-LTS is up to date
systemSettings.emailSettings=Ustawienia Email
systemSettings.smtpHost=SMTP host
systemSettings.smtpPort=SMTP port
-systemSettings.fromAddress='From' address
-systemSettings.fromName='From' name
+systemSettings.fromAddress=’From’ address
+systemSettings.fromName=’From’ name
systemSettings.auth=Use authorization
systemSettings.smtpUsername=Username
systemSettings.smtpPassword=Password
@@ -1764,7 +1763,7 @@ systemSettings.systemAlarmLevels=Poziomy alarmowe zdarze\u0144 systemowych
systemSettings.auditAlarmLevels=Poziomy alarmowe punkt\u00f3w danych
systemSettings.otherSettings=Inne ustawienia
systemSettings.purgeEvents=Usu\u0144 zdarzenia starsze ni\u017c
-systemSettings.purgeReports=PUsu\u0144 raporty starsze ni\u017c
+systemSettings.purgeReports=Usu\u0144 raporty starsze ni\u017c
systemSettings.uiPerformance=Wydajno\u015b\u0107 interfejsu u\u017cytkownika
systemSettings.uiPerformance.high=Wysoka
systemSettings.uiPerformance.med=\u015arednia
@@ -1790,7 +1789,7 @@ systemSettings.purgeNow=Oczy\u015b\u0107 baz\u0119 u\u017cywaj\u0105c ustawie\u0
systemSettings.filedataSize=Wielko\u015b\u0107 plik\u00f3w
systemSettings.totalSize=Rozmiar ca\u0142kowity
systemSettings.historyCount=Ilo\u015b\u0107 historii
-systemSettings.topPoints=Punkty top'owe
+systemSettings.topPoints=Punkty top’owe
systemSettings.eventCount=Ilo\u015b\u0107 zdarze\u0144
systemSettings.testEmail=Your system settings test email was successfully sent.
systemSettings.versionCheck1=Socket timeout during check. Please try again
@@ -1915,7 +1914,7 @@ viewEdit.fullScreen=Pe\u0142ny ekran
views.title=Schematy
views.newView=Nowy schemat
-views.noViews=Nie masz \u017cadnych schamt\u00f3w.Utw\u00f3rz teraz.
+views.noViews=Nie masz \u017cadnych schemat\u00f3w. Utw\u00f3rz
watchlist.addToWatchlist=Dodaj do listy
watchlist.points=Punkty
@@ -2001,7 +2000,7 @@ event.system.process=B\u0142\u0105d obs\u0142ugi zdarzenia
event.audit.added=User "{0}" created {1} with id {2}: {3}
event.audit.changed=User "{0}" changed {1} with id {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" to "{2}"
+event.audit.changedProperty={0}: "{1}" to "{2}"
event.audit.compoundEventDetector=Compound event detector
event.audit.dataPoint=Data point
event.audit.dataSource=Data source
@@ -2010,7 +2009,7 @@ event.audit.eventHandler=Event handler
event.audit.maintenanceEvent=Maintenance event
event.audit.pointEventDetector=Point event detector
event.audit.pointLink=Point link
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2133,8 +2132,8 @@ event.valueParse.timeParse=Failed to parse time "{0}"
event.valueParse.timeParsePoint=Failed to parse time "{0}" for {1}
event.valueParse.textParse=Value did not match any multistate text and was not parsable, result={0}
event.valueParse.textParsePoint=Value did not match any multistate text and was not parsable, result={0}, point={1}
-event.valueParse.numericParse=Couldn't parse to numeric, result={0}
-event.valueParse.numericParsePoint=Couldn't parse to numeric, result={0}, point={1}
+event.valueParse.numericParse=Couldn’t parse to numeric, result={0}
+event.valueParse.numericParsePoint=Couldn’t parse to numeric, result={0}, point={1}
event.valueParse.generalParse={0}, result={1}
event.valueParse.generalParsePoint={0}, result={1}, point={2}
event.1wire.deviceRead=Error reading device at address {0}: {1}
@@ -2353,7 +2352,7 @@ emport.error.eventCode=Invalid event code ''{0}''. Valid codes are {1}
emport.error.alarmLevel=Invalid alarm level ''{0}'' for event ''{1}''. Valid values are {2}
emport.error.missingUser=User with username ''{0}'' not found
emport.error.viewShare.missing=Missing ''{0}'' in view share
-emport.error.component.incompatibleDataType=Data point with 'XID' ''{0}'' has a data type that is not compatible with view component type ''{1}''
+emport.error.component.incompatibleDataType=Data point with ’XID’ ''{0}'' has a data type that is not compatible with view component type ''{1}''
emport.error.compound.invalidChildId=Invalid child id ''{0}'' for compound view component of type ''{1}''. Valid ids are {2}
emport.error.component.unknownDynamicImage=Dynamic image id ''{0}'' not found. Known dynamic image ids are {1}
emport.error.component.unknownImageSet=Image set id ''{0}'' not found. Known image set ids are {1}
@@ -2569,8 +2568,8 @@ engUnit.188=newtons per meter
engUnit.189=watts per meter per degree kelvin
engUnit.190=kilometers
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.2=mA
engUnit.abbr.3=A
engUnit.abbr.4=ohms
@@ -3026,7 +3025,7 @@ emport.errorMessage=B\u0142\u0119dy:
emport.uploadError=Upload failed ({0})
emport.invalidFile=File reading failed ({0})
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
+emport.versionError=The project version ({0}) isn’t compatible with current system version ({1})
dox.exportProject=Exporting projects
dox.importProject=Importing projects
@@ -3092,7 +3091,7 @@ users.theme.dark=Ciemny
viewEdit.moveDownComponent=Send to back
viewEdit.moveUpComponent=Bring to front
emport.profilePermission.prefix=Uprawnienia dla profilu ''{0}'': {1}
-dox.anonymousView=Dost0119p anonimowy
+dox.anonymousView=Dost\u0119p anonimowy
viewEdit.position.x=Położenie X
viewEdit.position.y=Położenie Y
@@ -3273,7 +3272,7 @@ mport.graphicsFolder=Include Graphics folder
graphic.enhancedImageChart.seriesConfig=Series configuration
dsEdit.radiuino.pollingMode=Polling mode
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
publisherEdit.httpSender.point.status=Status
dsEdit.radiuino.stopBits=Stop Bits
userProfiles.none=None
@@ -3476,4 +3475,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Notatka:
+sql.warning.prefix=Ostrzeżenie:
+views.noViews.prefix=teraz.
annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_pt.properties b/test/messages_pt.properties
index 94316ea501..22b4325781 100644
--- a/test/messages_pt.properties
+++ b/test/messages_pt.properties
@@ -685,7 +685,7 @@ dsEdit.meta.event.week=In\u00edcio da semana
dsEdit.meta.event.month=In\u00edcio do m\u00eas
dsEdit.meta.event.year=In\u00edcio do ano
dsEdit.meta.event.cron=Padr\u00e3o cron
-dsEdit.meta.delay=Atraso de execu\u00e7\u00e3o
+dsEdit.meta.delay=Atraso de execu\u00e7\u00e3o
dsEdit.meta.test.success=Successo. resultado={0}
dsEdit.meta.test.successTs=Successo. resultado={0}, timestamp={1}
dsEdit.meta.test.context=Um ou mais pontos est\u00e3o desabilitados ou faltando
@@ -993,16 +993,16 @@ dsEdit.viconics.networkInfo=Informa\u00e7\u00e3o da rede
dsEdit.viconics.refreshing=Atualizando...
dsEdit.viconics.rfModule=M\u00f3dulo RF
dsEdit.viconics.devices=Dispositivos
-dsEdit.viconics.commAddress=Endere\u00e7os
Comm
-dsEdit.viconics.modelNumber=N\u00famero de
modelo
-dsEdit.viconics.firmwareRevision=Revis\u00e3o de
Firmware
+dsEdit.viconics.commAddress=Endere\u00e7os Comm
+dsEdit.viconics.modelNumber=N\u00famero de modelo
+dsEdit.viconics.firmwareRevision=Revis\u00e3o de Firmware
dsEdit.viconics.zigbeeFirmwareRevision=Revis\u00e3o de firmware Zigbee
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Revis\u00e3o de
firmware
Zigbee
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Revis\u00e3o de firmware Zigbee
dsEdit.viconics.zigbeeNetworkAddress=Endere\u00e7o de rede Zigbee
-dsEdit.viconics.zigbeeNetworkAddressBr=Endere\u00e7o de
rede
Zigbee
+dsEdit.viconics.zigbeeNetworkAddressBr=Endere\u00e7o de rede Zigbee
dsEdit.viconics.ieee=IEEE
dsEdit.viconics.chipRevision=Revis\u00e3o do Chip
-dsEdit.viconics.chipRevisionBr=Revis\u00e3o do
chip
+dsEdit.viconics.chipRevisionBr=Revis\u00e3o do chip
dsEdit.viconics.trss=TRSS
dsEdit.viconics.crss=CRSS
dsEdit.viconics.unreliable=Valor do ponto pode n\u00e3o ser confi\u00e1vel
@@ -1204,42 +1204,42 @@ emport.importProgress=Importa\u00e7\u00e3o em progresso...
emport.importCancelled=Importa\u00e7\u00e3o cancelada
emport.importComplete=Importa\u00e7\u00e3o completa
emport.noMessages=Mensagem sem resultados. Nada a importar?
-emport.invalidImportData=Dado para importa\u00e7\u00e3o inv\u00e1lido: n\u00e3o \u00e9 um objeto JSON
+emport.invalidImportData=Dado para importa\u00e7\u00e3o inv\u00e1lido: n\u00e3o \u00e9 um objeto JSON. (www.json.org)
emport.parseError=Erro de an\u00e1lise JSON: {0}
-emport.user.username=Um usu\u00e1rio n\u00e3o tem um valor 'nome de usu\u00e1rio'. Ignorado.
+emport.user.username=Um usu\u00e1rio n\u00e3o tem um valor ’nome de usu\u00e1rio’. Ignorado.
emport.user.prefix=Usu\u00e1rio ''{0}'': {1}
-emport.view.missingType=Visualiza\u00e7\u00e3o com XID ''{0}'' n\u00e3o existe atualmente e n\u00e3o tem um valor 'tipo'. Tipos v\u00e1lidos s\u00e3o {1}
-emport.dataSource.xid=Um data source com nome ''{0}'' n\u00e3o tem um valor 'xid' v\u00e1lido. Ignorado.
-emport.dataSource.missingType=Data source com XID ''{0}'' n\u00e3o existe atualmente e n\u00e3o tem um valor 'tipo'. Tipos v\u00e1lidos s\u00e3o {1}
-emport.dataSource.invalidType=Data source com XID ''{0}''n\u00e3o existe atualmente e tem um valor 'tipo' inv\u00e1lido: ''{1}''. Tipos v\u00e1lidos s\u00e3o {2}
+emport.view.missingType=Visualiza\u00e7\u00e3o com XID ''{0}'' n\u00e3o existe atualmente e n\u00e3o tem um valor ’tipo’. Tipos v\u00e1lidos s\u00e3o {1}
+emport.dataSource.xid=Um data source com nome ''{0}'' n\u00e3o tem um valor ’xid’ v\u00e1lido. Ignorado.
+emport.dataSource.missingType=Data source com XID ''{0}'' n\u00e3o existe atualmente e n\u00e3o tem um valor ’tipo’. Tipos v\u00e1lidos s\u00e3o {1}
+emport.dataSource.invalidType=Data source com XID ''{0}'' n\u00e3o existe atualmente e tem um valor ’tipo’ inv\u00e1lido: ''{1}''. Tipos v\u00e1lidos s\u00e3o {2}
emport.dataSource.prefix=Data source ''{0}'': {1}
-emport.dataPoint.xid=Um data point com name ''{0}'' n\u00e3o tem um valor 'xid'. Ignorado.
+emport.dataPoint.xid=Um data point com name ''{0}'' n\u00e3o tem um valor ’xid’. Ignorado.
emport.dataPoint.badReference=Data point com XID ''{0}'' n\u00e3o existe atualmente e referencia um data source que n\u00e3o existe. Ignorado.
emport.dataPoint.prefix=Data point ''{0}'': {1}
emport.userPermission.prefix=Permiss\u00f5es para usu\u00e1rio ''{0}'': {1}
emport.added=adicionado
emport.saved=salvo
emport.causedBy=causado por:
-emport.view.xid=Uma visualiza\u00e7\u00e3o gr\u00e1fica n\u00e3o possui um valor 'xid'. Ignorado.
+emport.view.xid=Uma visualiza\u00e7\u00e3o gr\u00e1fica n\u00e3o possui um valor ’xid’. Ignorado.
emport.view.prefix=Visualiza\u00e7\u00e3o ''{0}'': {1}
emport.pointHierarchy.prefix=Hierarquia de ponto: {0}
-emport.pointLink.xid=Um v\u00ednculo de ponto n\u00e3o possui um valor 'xid'. Ignorado.
+emport.pointLink.xid=Um v\u00ednculo de ponto n\u00e3o possui um valor ’xid’. Ignorado.
emport.pointLink.prefix=V\u00ednculo de ponto ''{0}'': {1}
-emport.scheduledEvent.xid=Um evento agendado n\u00e3o possui um valor 'xid'. Ignorado.
+emport.scheduledEvent.xid=Um evento agendado n\u00e3o possui um valor ’xid’. Ignorado.
emport.scheduledEvent.prefix=Evento agendado ''{0}'': {1}
-emport.compoundEvent.xid=Um detector de eventos compostos n\u00e3o possui um valor 'xid'. Ignorado.
+emport.compoundEvent.xid=Um detector de eventos compostos n\u00e3o possui um valor ’xid’. Ignorado.
emport.compoundEvent.prefix=Detector de eventos compostos ''{0}'': {1}
-emport.mailingList.xid=Uma lista de envio de mensagens n\u00e3o possui um valor 'xid'. Ignorado.
+emport.mailingList.xid=Uma lista de envio de mensagens n\u00e3o possui um valor ’xid’. Ignorado.
emport.mailingList.prefix=Lista de envio de mensagens ''{0}'': {1}
-emport.eventHandler.xid=Um v\u00ednculo de ponto n\u00e3o posssui um valor 'xid'. Ignorado.
+emport.eventHandler.xid=Um v\u00ednculo de ponto n\u00e3o posssui um valor ’xid’. Ignorado.
emport.eventHandler.prefix=V\u00ednculo de ponto ''{0}'': {1}
-emport.publisher.xid=Um data source com nome ''{0}'' n\u00e3o tem um valor 'xid'. Ignorado.
-emport.publisher.missingType=Publisher com XID ''{0}'' n\u00e3o existe atualmente e n\u00e3o possui um valor 'tipo'. Tipos v\u00e1lidos s\u00e3o {1}
-emport.publisher.invalidType=Publisher com XID ''{0}'' n\u00e3o existe atualmente e tem um valor 'tipo' inv\u00e1lido: ''{1}''. Tipos v\u00e1lidos s\u00e3o {2}
+emport.publisher.xid=Um data source com nome ''{0}'' n\u00e3o tem um valor ’xid’. Ignorado.
+emport.publisher.missingType=Publisher com XID ''{0}'' n\u00e3o existe atualmente e n\u00e3o possui um valor ’tipo’. Tipos v\u00e1lidos s\u00e3o {1}
+emport.publisher.invalidType=Publisher com XID ''{0}'' n\u00e3o existe atualmente e tem um valor ’tipo’ inv\u00e1lido: ''{1}''. Tipos v\u00e1lidos s\u00e3o {2}
emport.publisher.prefix=Publisher ''{0}'': {1}
-emport.watchList.xid=Uma lista de visualiza\u00e7\u00e3o n\u00e3o possui um valor para 'xid'. Ignorada.
+emport.watchList.xid=Uma lista de visualiza\u00e7\u00e3o n\u00e3o possui um valor para ’xid’. Ignorada.
emport.watchList.prefix=Lista de visualiza\u00e7\u00e3o ''{0}'': {1}
-emport.maintenanceEvent.xid=Um evento de manuten\u00e7\u00e3o n\u00e3o possui um valor para 'xid'. Ignorado.
+emport.maintenanceEvent.xid=Um evento de manuten\u00e7\u00e3o n\u00e3o possui um valor para ’xid’. Ignorado.
emport.maintenanceEvent.prefix=Evento de manuten\u00e7\u00e3o ''{0}'': {1}
eventHandlers.recipTestEmailMessage= Essa mensagem foi enviada como um teste de um tratador de evento de email
@@ -1377,7 +1377,7 @@ login.validation.accountDisabled=Sua conta de usu\u00e1rio foi desativada. Por f
login.loginButton=Login
login.unknownBrowser=Checando a compatibilidade do browser...
login.supportedBrowser=Este browser \u00e9 suportado.
-login.unsupportedBrowser=Seu browser pode funcionar com este produto, mas n\u00e3o \u00e9 oficialmente suportado pela Equipe Scada-LTS. Recomendamos o uso do Firefox ou Chrome.
+login.unsupportedBrowser=Seu browser pode funcionar com este produto, mas n\u00e3o \u00e9 oficialmente suportado pela Equipe Scada-LTS. Recomendamos o uso do Mozilla Firefox, Google Chrome.
login.nag=NOTA: voc\u00ea poder\u00e1 ter problemas com o ScadaLTS porque seu browser n\u00e3o \u00e9 oficialmente suportado. Por favor, atualize seu browser.
mailingLists.added=Lista de envio adicionada
mailingLists.saved=Lista de envio salva
@@ -1443,7 +1443,7 @@ notes.cancel=Cancelar
notes.timeByUsername=time by username
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pointDetails.recordCountError=Contagem de grava\u00e7\u00e3o precisa ser um n\u00famero
pointDetails.timePeriodError=Tempo precisa ser um n\u00famero
pointDetails.imageCountError=Contagem de imagem precisa ser um n\u00famero
@@ -1479,7 +1479,7 @@ pointDetails.accessType=Tipo de acesso
pointEdit.buttons.enable=Habilitar
pointEdit.buttons.disable=Desabilitar
pointEdit.buttons.restart=Reiniciar
-pointEdit.buttons.note=Nota: salvar, desabilitar ou reiniciar um data point far\u00e1 com que todos os eventos ativos retornem ao normal.
+pointEdit.buttons.note=salvar, desabilitar ou reiniciar um data point far\u00e1 com que todos os eventos ativos retornem ao normal.
pointEdit.chart.props=Propriedades do renderizador de gr\u00e1ficos
pointEdit.chart.type=Tipo
@@ -1632,7 +1632,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -1836,7 +1836,7 @@ scheduledEvents.validate.inactiveTrigger=Erro ao criar gatilho inativo: {0}
scheduledEvents.validate.aliasTooLong=Alias n\u00e3o pode ser maior que 50 caracteres
scheduledEvents.validate.invalidRtn=Inactive time must be after active time
-sql.warning=Alerta: use esta funcionalidade por risco pr\u00f3prio. Uso incorreto pode resultar em dados corrompidos e/ou falhas no sistema.
+sql.warning=use esta funcionalidade por risco pr\u00f3prio. Uso incorreto pode resultar em dados corrompidos e/ou falhas no sistema.
sql.sql=SQL
sql.query=Enviar consulta
sql.update=Enviar atualiza\u00e7\u00e3o
@@ -2032,7 +2032,7 @@ viewEdit.compound.duration=Dura\u00e7\u00e3o
views.title=Representa\u00e7\u00f5es Gr\u00e1ficas
views.newView=Nova representa\u00e7\u00e3o
-views.noViews=Voc\u00ea n\u00e3o criou nenhuma representa\u00e7\u00e3o gr\u00e1fica. Crie uma agora.
+views.noViews=Voc\u00ea n\u00e3o criou nenhuma representa\u00e7\u00e3o gr\u00e1fica. Crie uma
watchlist.addToWatchlist=Adicionar na watch list
watchlist.points=Points
@@ -2130,7 +2130,7 @@ event.system.process=Falha do processo do tratador de eventos
event.audit.added=User "{0}" criado {1} com id {2}: {3}
event.audit.changed=User "{0}" alerado {1} com id {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" to "{2}"
+event.audit.changedProperty={0}: "{1}" to "{2}"
event.audit.compoundEventDetector=Detector de evento composto
event.audit.dataPoint=Data point
event.audit.dataSource=Data source
@@ -2139,7 +2139,7 @@ event.audit.eventHandler=Tratador de evento
event.audit.maintenanceEvent=Evento de manuten\u00e7\u00e3o
event.audit.pointEventDetector=Detector de evento de data point
event.audit.pointLink=Point link
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2380,7 +2380,7 @@ event.ds.initialization=Exce\u00e7\u00e3o de inicializa\u00e7\u00e3o
event.ds.message=Exce\u00e7\u00e3o de mensagem
event.ds.device=Exce\u00e7\u00e3o de dispositivo
event.ds.network=Exce\u00e7\u00e3o de rede
-event.ds.duplicateComm=Endere\u00e7o comm duplicado detectado
+event.ds.duplicateComm=Endere\u00e7o comm duplicado detectado
event.ds.dataSource=Exce\u00e7\u00e3o de data source
event.ds.pointRead=Exce\u00e7\u00e3o de leitura de data point
event.ds.pointWrite=Exce\u00e7\u00e3o de escrita em data point
@@ -2479,7 +2479,7 @@ emport.error.eventCode=C\u00f3digo de evento ''{0}'' inv\u00e1lido. C\u00f3digos
emport.error.alarmLevel=N\u00edvel de alarme ''{0}'' inv\u00e1lido para evento ''{1}''. Valores v\u00e1lidos s\u00e3o {2}
emport.error.missingUser=Usu\u00e1rio com nome de usu\u00e1rio ''{0}'' n\u00e3o encontrado
emport.error.viewShare.missing=''{0}'' faltando em compartilhamento da representa\u00e7\u00e3o
-emport.error.component.incompatibleDataType=Data point com 'XID' ''{0}'' possui tipo de dado n\u00e3o compat\u00edvel com com tipo de visualiza\u00e7\u00e3o de componente ''{1}''
+emport.error.component.incompatibleDataType=Data point com ’XID’ ''{0}'' possui tipo de dado n\u00e3o compat\u00edvel com com tipo de visualiza\u00e7\u00e3o de componente ''{1}''
emport.error.compound.invalidChildId=Id filho ''{0}'' inv\u00e1lido para componente de visualiza\u00e7\u00e3o composto do tipo ''{1}''. Ids v\u00e1lidos s\u00e3o {2}
emport.error.component.unknownDynamicImage=Id de imagem din\u00e2mica ''{0}'' n\u00e3o encontrado. Ids de imagens din\u00e2micas s\u00e3o {1}
emport.error.component.unknownImageSet=Id de defini\u00e7\u00e3o de imagem ''{0}'' n\u00e3o encontrado. Ids de defini\u00e7\u00e3o de imagem conhecidos s\u00e3o {1}
@@ -2695,8 +2695,8 @@ engUnit.188=Newtons por metro
engUnit.189=watts por metro por Kelvin
engUnit.190=kilometros
-engUnit.abbr.0=m2
-engUnit.abbr.1=f2
+engUnit.abbr.0=m\u00b2
+engUnit.abbr.1=ft\u00b2
engUnit.abbr.2=mA
engUnit.abbr.3=A
engUnit.abbr.4=ohms
@@ -2718,22 +2718,22 @@ engUnit.abbr.19=kWh
engUnit.abbr.20=btus
engUnit.abbr.21=therms
engUnit.abbr.22=ton hours
-engUnit.abbr.23=J/Kg ar seco
-engUnit.abbr.24=btus/lb ar seco
+engUnit.abbr.23=J/Kg ar seco
+engUnit.abbr.24=btus/lb ar seco
engUnit.abbr.25=ciclos por hora
engUnit.abbr.26=ciclos por minuto
engUnit.abbr.27=hertz
-engUnit.abbr.28=g H2O / kg ar seco
+engUnit.abbr.28=g H\u2082O / kg ar seco
engUnit.abbr.29=%UR
engUnit.abbr.30=mm
engUnit.abbr.31=m
engUnit.abbr.32=pol
engUnit.abbr.33=p\u00e9s
-engUnit.abbr.34=W/p\u00e92
-engUnit.abbr.35=W/m2
+engUnit.abbr.34=W/p\u00e9\u00b2
+engUnit.abbr.35=W/m\u00b2
engUnit.abbr.36=lm
engUnit.abbr.37=lx
-engUnit.abbr.38=lm/p\u00e92
+engUnit.abbr.38=lm/p\u00e9\u00b2
engUnit.abbr.39=kg
engUnit.abbr.40=lb
engUnit.abbr.41=t
@@ -2751,12 +2751,12 @@ engUnit.abbr.52=RT
engUnit.abbr.53=Pa
engUnit.abbr.54=kPa
engUnit.abbr.55=bar
-engUnit.abbr.56=lbf/pol2
-engUnit.abbr.57=cmH2O
-engUnit.abbr.58=polH2O
-engUnit.abbr.59=mmHg
-engUnit.abbr.60=cmHg
-engUnit.abbr.61=polHg
+engUnit.abbr.56=lbf/pol\u00b2
+engUnit.abbr.57=cmH\u2082O
+engUnit.abbr.58=polH\u2082O
+engUnit.abbr.59=mmHg
+engUnit.abbr.60=cmHg
+engUnit.abbr.61=polHg
engUnit.abbr.62=°C
engUnit.abbr.63=K
engUnit.abbr.64=°F
@@ -2774,17 +2774,17 @@ engUnit.abbr.75=km/h
engUnit.abbr.76=p\u00e9s/s
engUnit.abbr.77=p\u00e9s/min
engUnit.abbr.78=m/h
-engUnit.abbr.79=p\u00e9s3
-engUnit.abbr.80=m3
-engUnit.abbr.81=GaUK
+engUnit.abbr.79=p\u00e9s\u00b3
+engUnit.abbr.80=m\u00b3
+engUnit.abbr.81=GaUK
engUnit.abbr.82=l
-engUnit.abbr.83=GaUS
-engUnit.abbr.84=p\u00e9s3/min
-engUnit.abbr.85=m3/s
-engUnit.abbr.86=GaUK/min
+engUnit.abbr.83=GaUS
+engUnit.abbr.84=p\u00e9s\u00b3/min
+engUnit.abbr.85=m\u00b3/s
+engUnit.abbr.86=GaUK/min
engUnit.abbr.87=l/s
engUnit.abbr.88=l/m
-engUnit.abbr.89=GaUS/min
+engUnit.abbr.89=GaUS/min
engUnit.abbr.90=°
engUnit.abbr.91=°C/h
engUnit.abbr.92=°F/min
@@ -2810,8 +2810,8 @@ engUnit.abbr.111=currency 7
engUnit.abbr.112=currency 8
engUnit.abbr.113=currency 9
engUnit.abbr.114=currency 10
-engUnit.abbr.115=pol2
-engUnit.abbr.116=cm2
+engUnit.abbr.115=pol\u00b2
+engUnit.abbr.116=cm\u00b2
engUnit.abbr.117=BTU/lb
engUnit.abbr.118=cm
engUnit.abbr.119=lb/s
@@ -2830,22 +2830,22 @@ engUnit.abbr.131=/h
engUnit.abbr.132=mW
engUnit.abbr.133=hPa
engUnit.abbr.134=mbar
-engUnit.abbr.135=m3/h
+engUnit.abbr.135=m\u00b3/h
engUnit.abbr.136=l/h
-engUnit.abbr.137=kWh/m2
-engUnit.abbr.138=kWh/p\u00e92
-engUnit.abbr.139=MJ/m2
-engUnit.abbr.140=MJ/p\u00e92
-engUnit.abbr.141=W/m2K
-engUnit.abbr.142=p\u00e9s3/s
+engUnit.abbr.137=kWh/m\u00b2
+engUnit.abbr.138=kWh/p\u00e9\u00b2
+engUnit.abbr.139=MJ/m\u00b2
+engUnit.abbr.140=MJ/p\u00e9\u00b2
+engUnit.abbr.141=W/m\u00b2K
+engUnit.abbr.142=p\u00e9s\u00b3/s
engUnit.abbr.143=%obs/p\u00e9
engUnit.abbr.144=%pbs/m
engUnit.abbr.145=mΩ
engUnit.abbr.146=MWh
engUnit.abbr.147=kBTU
engUnit.abbr.148=MBTU
-engUnit.abbr.149=kJ/kgar seco
-engUnit.abbr.150=MJ/kgar seco
+engUnit.abbr.149=kJ/kg ar seco
+engUnit.abbr.150=MJ/kg ar seco
engUnit.abbr.151=kJ/K
engUnit.abbr.152=MJ/K
engUnit.abbr.153=N
@@ -2853,18 +2853,18 @@ engUnit.abbr.154=g/s
engUnit.abbr.155=g/min
engUnit.abbr.156=t/h
engUnit.abbr.157=kBTU/h
-engUnit.abbr.158=s x 102
+engUnit.abbr.158=s x 10\u00b2
engUnit.abbr.159=ms
engUnit.abbr.160=Nm
engUnit.abbr.161=mm/s
engUnit.abbr.162=mm/min
engUnit.abbr.163=m/min
engUnit.abbr.164=m/h
-engUnit.abbr.165=m3/min
-engUnit.abbr.166=m/s2
+engUnit.abbr.165=m\u00b3/min
+engUnit.abbr.166=m/s\u00b2
engUnit.abbr.167=A/m
-engUnit.abbr.168=A/m2
-engUnit.abbr.169=Am2
+engUnit.abbr.168=A/m\u00b2
+engUnit.abbr.169=Am\u00b2
engUnit.abbr.170=Fd
engUnit.abbr.171=H
engUnit.abbr.172=Ωm
@@ -2875,13 +2875,13 @@ engUnit.abbr.176=V/K
engUnit.abbr.177=V/m
engUnit.abbr.178=Wb
engUnit.abbr.179=cd
-engUnit.abbr.180=cd/m2
+engUnit.abbr.180=cd/m\u00b2
engUnit.abbr.181=K/h
engUnit.abbr.182=K/min
engUnit.abbr.183=Js
engUnit.abbr.184=rad/s
-engUnit.abbr.185=m2/N
-engUnit.abbr.186=kg/m3
+engUnit.abbr.185=m\u00b2/N
+engUnit.abbr.186=kg/m\u00b3
engUnit.abbr.187=Ns
engUnit.abbr.188=N/m
engUnit.abbr.189=W/mK
@@ -3349,7 +3349,7 @@ dsEdit.mbus.phoneNumber=Phone Number
graphic.enhancedImageChart.config.zoomOut=Zoom out
dsEdit.mbus.tcpAddr=TCP Address
pointHierarchySLTS.folder=Folder
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
graphic.enhancedImageChart.pointConfig.renderMode.line=Line
event.maintenance.active=Maintenance event activated\: {0}
dsEdit.snmp.sl.authnopriv=Only authentication
@@ -3490,4 +3490,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=Nota:
+sql.warning.prefix=Alerta:
+views.noViews.prefix=agora.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_ru.properties b/test/messages_ru.properties
index 4aba684182..aa0dc3aa32 100644
--- a/test/messages_ru.properties
+++ b/test/messages_ru.properties
@@ -666,7 +666,7 @@ dsEdit.meta.event.week=\u041d\u0430\u0447\u0430\u043b\u043e \u043d\u0435\u0434\u
dsEdit.meta.event.month=\u041d\u0430\u0447\u0430\u043b\u043e \u043c\u0435\u0441\u044f\u0446\u0430
dsEdit.meta.event.year=\u041d\u0430\u0447\u0430\u043b\u043e \u0433\u043e\u0434\u0430
dsEdit.meta.event.cron=\u0428\u0430\u0431\u043b\u043e\u043d \u043a\u0440\u043e\u043d\u0430
-dsEdit.meta.delay=\u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f
+dsEdit.meta.delay=\u0417\u0430\u0434\u0435\u0440\u0436\u043a\u0430 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f
dsEdit.meta.test.success=\u0423\u0441\u043f\u0435\u0448\u043d\u043e. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442={0}
dsEdit.meta.test.successTs=\u0423\u0441\u043f\u0435\u0448\u043d\u043e. \u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442={0}, \u0432\u0440\u0435\u043c\u044f={1}
dsEdit.meta.test.context=\u041e\u0434\u043d\u0430 \u0438\u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u0435\u043a \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0438\u043b\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044e\u0442
@@ -968,16 +968,16 @@ dsEdit.viconics.networkInfo=\u0418\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u04
dsEdit.viconics.refreshing=\u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435...
dsEdit.viconics.rfModule=\u0420\u0430\u0434\u0438\u043e\u043c\u043e\u0434\u0443\u043b\u044c
dsEdit.viconics.devices=\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430
-dsEdit.viconics.commAddress=\u0410\u0434\u0440\u0435\u0441
\u0441\u0432\u044f\u0437\u0438
-dsEdit.viconics.modelNumber=\u041d\u043e\u043c\u0435\u0440
\u043c\u043e\u0434\u0435\u043b\u0438
-dsEdit.viconics.firmwareRevision=\u0412\u0435\u0440\u0441\u0438\u044f
\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
+dsEdit.viconics.commAddress=\u0410\u0434\u0440\u0435\u0441 \u0441\u0432\u044f\u0437\u0438
+dsEdit.viconics.modelNumber=\u041d\u043e\u043c\u0435\u0440 \u043c\u043e\u0434\u0435\u043b\u0438
+dsEdit.viconics.firmwareRevision=\u0412\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
dsEdit.viconics.zigbeeFirmwareRevision=\u0412\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b Zigbee
-dsEdit.viconics.zigbeeFirmwareRevisionBr= \u0412\u0435\u0440\u0441\u0438\u044f
\u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b
Zigbee
+dsEdit.viconics.zigbeeFirmwareRevisionBr= \u0412\u0435\u0440\u0441\u0438\u044f \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b Zigbee
dsEdit.viconics.zigbeeNetworkAddress=\u0410\u0434\u0440\u0435\u0441 \u0441\u0435\u0442\u0438 Zigbee
-dsEdit.viconics.zigbeeNetworkAddressBr= \u0410\u0434\u0440\u0435\u0441
\u0441\u0435\u0442\u0438
Zigbee
+dsEdit.viconics.zigbeeNetworkAddressBr= \u0410\u0434\u0440\u0435\u0441 \u0441\u0435\u0442\u0438 Zigbee
dsEdit.viconics.ieee=IEEE
dsEdit.viconics.chipRevision=\u0412\u0435\u0440\u0441\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u0447\u0438\u043f\u0430
-dsEdit.viconics.chipRevisionBr=\u0412\u0435\u0440\u0441\u0438\u044f
\u043c\u0438\u043a\u0440\u043e\u0447\u0438\u043f\u0430
+dsEdit.viconics.chipRevisionBr=\u0412\u0435\u0440\u0441\u0438\u044f \u043c\u0438\u043a\u0440\u043e\u0447\u0438\u043f\u0430
dsEdit.viconics.trss=TRSS
dsEdit.viconics.crss=CRSS
dsEdit.viconics.unreliable=\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u043a\u0438 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0448\u0438\u0431\u043e\u0447\u043d\u044b\u043c
@@ -1120,42 +1120,42 @@ emport.importProgress=\u041f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u04
emport.importCancelled=\u0418\u043c\u043f\u043e\u0440\u0442 \u043e\u0442\u043c\u0435\u043d\u0435\u043d
emport.importComplete=\u0418\u043c\u043f\u043e\u0440\u0442 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d
emport.noMessages=\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438. \u041d\u0435\u0442 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430?
-emport.invalidImportData=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430: \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c JSON
+emport.invalidImportData=\u041d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u0430: \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c JSON. (www.json.org)
emport.parseError=\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 JSON : {0}
emport.user.username=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043d\u0435 \u043f\u0440\u0438\u0441\u0432\u043e\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '\u0438\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.user.prefix=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c ''{0}'': {1}
emport.view.missingType=\u0412\u0438\u0434 \u0441 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '\u0442\u0438\u043f' \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b: {1}
-emport.dataSource.xid=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
-emport.dataSource.missingType=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '\u0442\u0438\u043f' \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b: {1}
+emport.dataSource.xid=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.dataSource.missingType=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442, \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 ’\u0442\u0438\u043f’ \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b: {1}
emport.dataSource.invalidType=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '\u0442\u0438\u043f' \u0434\u043b\u044f ''{1}''. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b: {2}
emport.dataSource.prefix=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 ''{0}'': {1}
-emport.dataPoint.xid=\u0414\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.dataPoint.xid=\u0414\u043b\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.dataPoint.badReference=\u0422\u043e\u0447\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.dataPoint.prefix=\u041e\u0431\u044a\u0435\u043a\u0442 \u0434\u0430\u043d\u043d\u044b\u0445 ''{0}'': {1}
emport.userPermission.prefix=\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f ''{0}'': {1}
emport.added=\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e
emport.saved=\u0421\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043e
emport.causedBy=\u0412\u044b\u0437\u0432\u0430\u043d\u043e:
-emport.view.xid=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0438\u0434 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.view.xid=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0432\u0438\u0434 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.view.prefix=\u0412\u0438\u0434 ''{0}'': {1}
emport.pointHierarchy.prefix=\u0418\u0435\u0440\u0430\u0440\u0445\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432: {0}
-emport.pointLink.xid=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u0435\u043a \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.pointLink.xid=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u0435\u043a \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.pointLink.prefix=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u0435\u043a ''{0}'': {1}
-emport.scheduledEvent.xid=\u0417\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.scheduledEvent.xid=\u0417\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.scheduledEvent.prefix=\u0417\u0430\u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u0435 ''{0}'': {1}
-emport.compoundEvent.xid=\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0439 \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430
+emport.compoundEvent.xid=\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0439 \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430
emport.compoundEvent.prefix=\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0439 \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 ''{0}'': {1}
-emport.mailingList.xid=\u0421\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.mailingList.xid=\u0421\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.mailingList.prefix=\u0421\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 ''{0}'': {1}
-emport.eventHandler.xid=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.eventHandler.xid=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u043a\u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.eventHandler.prefix=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u043a\u0438 ''{0}'': {1}
-emport.publisher.xid=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.publisher.xid=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.publisher.missingType=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0440 \u0441 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f '\u0442\u0438\u043f'. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0442\u0438\u043f\u044b: {1}
emport.publisher.invalidType=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0440 \u0441 XID ''{0}'' \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0438\u043c\u0435\u0435\u0442 \u043d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 '\u0442\u0438\u043f' \u0434\u043b\u044f ''{1}''. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: {2}
emport.publisher.prefix=\u041f\u0443\u0431\u043b\u0438\u043a\u0430\u0442\u043e\u0440 ''{0}'': {1}
-emport.watchList.xid=\u041b\u0438\u0441\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.watchList.xid=\u041b\u0438\u0441\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.watchList.prefix=\u041b\u0438\u0441\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f ''{0}'': {1}
-emport.maintenanceEvent.xid=\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f 'XID'. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
+emport.maintenanceEvent.xid=\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f ’XID’. \u041e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.
emport.maintenanceEvent.prefix=\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f ''{0}'': {1}
eventHandlers.recipTestEmailMessage=\u0414\u0430\u043d\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0441\u043f\u0438\u0441\u043a\u0430 \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 (\u043f\u043e\u043b\u0443\u0447\u0430\u0442\u0435\u043b\u0435\u0439 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439)
@@ -1294,7 +1294,7 @@ login.validation.accountDisabled=\u0412\u0430\u0448 \u0430\u043a\u043a\u0430\u04
login.loginButton=\u041b\u043e\u0433\u0438\u043d
login.unknownBrowser=\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u0438 \u0412\u0430\u0448\u0435\u0433\u043e \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u0430...
login.supportedBrowser=\u0412\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f.
-login.unsupportedBrowser=\u0412\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c, \u043d\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435\u043c Scada-LTS. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e Firefox, Chrome, \u0438\u043b\u0438 Internet Explorer 7.
+login.unsupportedBrowser=\u0412\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u044d\u0442\u0438\u043c \u043f\u0440\u043e\u0434\u0443\u043a\u0442\u043e\u043c, \u043d\u043e \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u044b\u043c \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u0435\u043c Scada-LTS. \u0420\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e Mozilla Firefox, Google Chrome.
login.nag=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441\u043e ScadaLTS, \u0442\u0430\u043a \u043a\u0430\u043a \u0412\u0430\u0448 \u0431\u0440\u0430\u0443\u0437\u0435\u0440 \u043e\u0444\u0438\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0440\u0430\u0443\u0437\u0435\u0440.
mailingLists.added=\u0421\u043f\u0438\u0441\u043e\u043a \u0440\u0430\u0441\u0441\u044b\u043b\u043a\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d
@@ -1362,7 +1362,7 @@ notes.cancel=\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c
notes.timeByUsername=\u0412\u0440\u0435\u043c\u044f \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pointDetails.recordCountError=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0447\u0438\u0441\u043b\u043e\u043c
pointDetails.timePeriodError=\u041f\u0435\u0440\u0438\u043e\u0434 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u0447\u0438\u0441\u043b\u043e\u043c
pointDetails.imageCountError=\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0447\u0438\u0441\u043b\u043e\u043c
@@ -1398,7 +1398,7 @@ pointDetails.accessType=\u0422\u0438\u043f \u0434\u043e\u0441\u0442\u0443\u043f\
pointEdit.buttons.enable=\u0412\u043a\u043b\u044e\u0447\u0438\u0442\u044c
pointEdit.buttons.disable=\u041e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c
pointEdit.buttons.restart=\u041f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c
-pointEdit.buttons.note=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435: \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435, \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
+pointEdit.buttons.note=\u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435, \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u043e\u0431\u044a\u0435\u043a\u0442\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0432\u0441\u0435 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435
pointEdit.chart.props=\u0421\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u043f\u043e\u0441\u0442\u0440\u043e\u0438\u0442\u0435\u043b\u044f \u0433\u0440\u0430\u0444\u0438\u043a\u043e\u0432
pointEdit.chart.type=\u0422\u0438\u043f
@@ -1551,7 +1551,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -1752,7 +1752,7 @@ scheduledEvents.validate.inactiveTrigger=\u041e\u0448\u0438\u0431\u043a\u0430 \u
scheduledEvents.validate.aliasTooLong=\u0414\u043b\u0438\u043d\u0430 \u043f\u0441\u0435\u0432\u0434\u043e\u043d\u0438\u043c\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0431\u043e\u043b\u0435\u0435 50 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432
scheduledEvents.validate.invalidRtn=\u0412\u0440\u0435\u043c\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u043f\u043e\u0437\u0436\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f
-sql.warning=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435: \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u0432\u0430\u0448 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0440\u0438\u0441\u043a. \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u043e\u0442\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438/\u0438\u043b\u0438 \u0441\u0431\u043e\u044f\u043c \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.
+sql.warning= \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u044d\u0442\u0443 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430 \u0432\u0430\u0448 \u0441\u0442\u0440\u0430\u0445 \u0438 \u0440\u0438\u0441\u043a. \u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a \u043f\u043e\u0442\u0435\u0440\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0438/\u0438\u043b\u0438 \u0441\u0431\u043e\u044f\u043c \u0432 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u044b.
sql.sql=SQL
sql.query=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441
sql.update=\u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435
@@ -1770,8 +1770,8 @@ systemSettings.upToDate=\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u
systemSettings.emailSettings=\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439
systemSettings.smtpHost=\u0425\u043e\u0441\u0442 SMTP
systemSettings.smtpPort=\u041f\u043e\u0440\u0442 SMTP
-systemSettings.fromAddress=\u0410\u0434\u0440\u0435\u0441 \u0432 \u043f\u043e\u043b\u0435 'From:'
-systemSettings.fromName=\u0418\u043c\u044f \u0432 \u043f\u043e\u043b\u0435 'From:'
+systemSettings.fromAddress=\u0410\u0434\u0440\u0435\u0441 \u0432 \u043f\u043e\u043b\u0435 ’From:’
+systemSettings.fromName=\u0418\u043c\u044f \u0432 \u043f\u043e\u043b\u0435 ’From:’
systemSettings.auth=\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e
systemSettings.smtpUsername=\u0418\u043c\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f
systemSettings.smtpPassword=\u041f\u0430\u0440\u043e\u043b\u044c
@@ -1930,7 +1930,7 @@ viewEdit.compound.duration=\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u044
views.title=\u0413\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0432\u0438\u0434\u044b
views.newView=\u041d\u043e\u0432\u044b\u0439 \u0432\u0438\u0434
-views.noViews=\u0412\u044b \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439 \u0441\u0435\u0439\u0447\u0430\u0441.
+views.noViews=\u0412\u044b \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043b\u0438 \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430. \u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u044b\u0439
watchlist.addToWatchlist=\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u043b\u0438\u0441\u0442 \u043d\u0430\u0431\u043b\u044e\u0434\u0435\u043d\u0438\u044f
watchlist.points=\u0422\u043e\u0447\u043a\u0438
@@ -2030,7 +2030,7 @@ event.system.process=\u041e\u0448\u0438\u0431\u043a\u0430 \u043e\u0431\u0440\u04
event.audit.added=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c "{0}" \u0441\u043e\u0437\u0434\u0430\u043b {1} \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c {2}: {3}
event.audit.changed=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c "{0}" \u0438\u0437\u043c\u0435\u043d\u0438\u043b {1} \u0441 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u043e\u043c {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" \u0432 "{2}"
+event.audit.changedProperty={0}: "{1}" \u0432 "{2}"
event.audit.compoundEventDetector=\u0421\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0439 \u0434\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439
event.audit.dataPoint=\u0422\u043e\u0447\u043a\u0430 \u0434\u0430\u043d\u043d\u044b\u0445
event.audit.dataSource=\u0418\u0441\u0442\u043e\u0447\u043d\u0438\u043a \u0434\u0430\u043d\u043d\u044b\u0445
@@ -2039,7 +2039,7 @@ event.audit.eventHandler=\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\
event.audit.maintenanceEvent=\u0421\u043e\u0431\u044b\u0442\u0438\u0435 \u043e\u0431\u0441\u043b\u0443\u0436\u0438\u0432\u0430\u043d\u0438\u044f
event.audit.pointEventDetector=\u0414\u0435\u0442\u0435\u043a\u0442\u043e\u0440 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u043e\u0431\u044a\u0435\u043a\u0442\u0430
event.audit.pointLink=\u0421\u0432\u044f\u0437\u044c \u0442\u043e\u0447\u0435\u043a
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2384,7 +2384,7 @@ emport.error.eventCode=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u0
emport.error.alarmLevel=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0442\u0440\u0435\u0432\u043e\u0433\u0438 ''{0}'' \u0434\u043b\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f ''{1}''. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: {2}
emport.error.missingUser=\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441 \u0438\u043c\u0435\u043d\u0435\u043c ''{0}'' \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d
emport.error.viewShare.missing=\u041e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442 ''{0}'' \u0432 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u043d\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u0432\u0438\u0434\u0430
-emport.error.component.incompatibleDataType=\u0422\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0447\u043a\u0438 \u0441 'XID' ''{0}'' \u043d\u0435 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c \u0441 \u0442\u0438\u043f\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432\u0438\u0434\u0430 ''{1}''
+emport.error.component.incompatibleDataType=\u0422\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445 \u0442\u043e\u0447\u043a\u0438 \u0441 ’XID’ ''{0}'' \u043d\u0435 \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c \u0441 \u0442\u0438\u043f\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0432\u0438\u0434\u0430 ''{1}''
emport.error.compound.invalidChildId=\u041d\u0435\u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0439 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u043e\u0433\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u0430 ''{0}'' \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0441\u043e\u0441\u0442\u0430\u0432\u043d\u043e\u0433\u043e \u0432\u0438\u0434\u0430 \u0442\u0438\u043f\u0430 ''{1}''. \u041f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b: {2}
emport.error.component.unknownDynamicImage=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f ''{0}'' \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u0418\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u0438\u0437\u043c\u0435\u043d\u044f\u044e\u0449\u0438\u0445\u0441\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439: {1}
emport.error.component.unknownImageSet=\u0418\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u043d\u0430\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 ''{0}'' \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d. \u0418\u0437\u0432\u0435\u0441\u0442\u043d\u044b\u0435 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440\u044b \u043d\u0430\u0431\u043e\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439: {1}
@@ -2600,8 +2600,8 @@ engUnit.188=\u041d\u044c\u044e\u0442\u043e\u043d \u043d\u0430 \u043c\u0435\u0442
engUnit.189=\u0412\u0430\u0442\u0442\u044b \u043d\u0430 \u043c\u0435\u0442\u0440-\u043a\u0435\u043b\u044c\u0432\u0438\u043d
engUnit.190=kilometers
-engUnit.abbr.0=\u043c2
-engUnit.abbr.1=\u04442
+engUnit.abbr.0=\u043c\u00b2
+engUnit.abbr.1=\u0444\u00b2
engUnit.abbr.2=\u043c\u0410
engUnit.abbr.3=\u0410
engUnit.abbr.4=\u041e\u043c
@@ -3486,4 +3486,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:
+sql.warning.prefix=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435:
+views.noViews.prefix=\u0441\u0435\u0439\u0447\u0430\u0441.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/messages_zh.properties b/test/messages_zh.properties
index 7d451f2719..33ab4c2c56 100644
--- a/test/messages_zh.properties
+++ b/test/messages_zh.properties
@@ -581,7 +581,7 @@ dsEdit.meta.event.week=\u5f00\u59cb\u7684\u5468\u6570
dsEdit.meta.event.month=\u5f00\u59cb\u6708\u4efd
dsEdit.meta.event.year=\u5f00\u59cb\u5e74\u4efd
dsEdit.meta.event.cron=\u5b9a\u65f6\u5668\u8868\u8fbe\u5f0f
-dsEdit.meta.delay=\u6267\u884c\u5ef6\u65f6
+dsEdit.meta.delay=\u6267\u884c\u5ef6\u65f6
dsEdit.meta.test.success=\u6210\u529f\u3002\u7ed3\u679c={0}
dsEdit.meta.test.successTs=\u6210\u529f\u3002\u7ed3\u679c={0}\uff0c\u65f6\u95f4\u6233={1}
dsEdit.meta.test.context=\u4e00\u4e2a\u6216\u8005\u591a\u4e2a\u70b9\u5df2\u5931\u6548\u6216\u8005\u4e0d\u5b58\u5728
@@ -899,31 +899,31 @@ emport.importProgress=\u6b63\u5728\u5bfc\u5165...
emport.importCancelled=\u5bfc\u5165\u5df2\u53d6\u6d88
emport.importComplete=\u5bfc\u5165\u5b8c\u6210
emport.noMessages=\u65e0\u8fd4\u56de\u4fe1\u606f\u3002\u65e0\u9700\u5bfc\u5165?
-emport.invalidImportData=\u5bfc\u5165\u6570\u636e\u65e0\u6548: \u975eJSON\u5bf9\u8c61
+emport.invalidImportData=\u5bfc\u5165\u6570\u636e\u65e0\u6548: \u975eJSON\u5bf9\u8c61. (www.json.org)
emport.parseError=JSON\u5bf9\u8c61\u5206\u6790\u9519\u8bef: {0}
emport.user.username=\u7528\u6237\u7f3a\u5c11'\u7528\u6237\u540d'\u3002\u5df2\u5ffd\u7565\u3002
emport.user.prefix=\u7528\u6237 ''{0}'': {1}
-emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
-emport.dataSource.xid=A\u6570\u636e\u6e90 with name ''{0}'' does not have an 'xid' value. Ignored.
-emport.dataSource.missingType=\u6570\u636e\u6e90 with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
-emport.dataSource.invalidType="\u6570\u636e\u6e90 with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
+emport.view.missingType=View with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
+emport.dataSource.xid=A\u6570\u636e\u6e90 with name ''{0}'' does not have an ’xid’ value. Ignored.
+emport.dataSource.missingType=\u6570\u636e\u6e90 with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
+emport.dataSource.invalidType="\u6570\u636e\u6e90 with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
emport.dataSource.prefix=\u6570\u636e\u6e90 ''{0}'': {1}
-emport.dataPoint.xid=A \u6570\u636e\u70b9with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.dataPoint.xid=A \u6570\u636e\u70b9with name ''{0}'' does not have an ’xid’ value. Ignored.
emport.dataPoint.badReference=\u6570\u636e\u70b9with XID ''{0}'' does not already exist and references a\u6570\u636e\u6e90 that does not exist. Ignored.
emport.dataPoint.prefix=\u6570\u636e\u70b9''{0}'': {1}
emport.userPermission.prefix=Permissions for user ''{0}'': {1}
emport.added=added
emport.saved=saved
emport.causedBy=caused by:
-emport.view.xid=A graphical view does not have an 'xid' value. Ignored.
+emport.view.xid=A graphical view does not have an ’xid’ value. Ignored.
emport.view.prefix=View ''{0}'': {1}
emport.pointHierarchy.prefix=\u70b9\u5c42\u6b21: {0}
-emport.pointLink.xid=A \u70b9\u94fe\u63a5does not have an 'xid' value. Ignored.
+emport.pointLink.xid=A \u70b9\u94fe\u63a5does not have an ’xid’ value. Ignored.
emport.pointLink.prefix=\u70b9\u94fe\u63a5''{0}'': {1}
-eventHandlers.recipTestEmailMessage=\u8fd9\u662f\u6d4b\u8bd5\u90ae\u4ef6\u5173\u4e8e\u4e8b\u4ef6\u5904\u7406\u5668's email recipient list
+eventHandlers.recipTestEmailMessage=\u8fd9\u662f\u6d4b\u8bd5\u90ae\u4ef6\u5173\u4e8e\u4e8b\u4ef6\u5904\u7406\u5668’s email recipient list
eventHandlers.emailRecipients=Email recipients
-eventHandlers.escalTestEmailMessage=\u8fd9\u662f\u6d4b\u8bd5\u90ae\u4ef6\u5173\u4e8e\u4e8b\u4ef6\u5904\u7406\u5668's escalation list
+eventHandlers.escalTestEmailMessage=\u8fd9\u662f\u6d4b\u8bd5\u90ae\u4ef6\u5173\u4e8e\u4e8b\u4ef6\u5904\u7406\u5668’s escalation list
eventHandlers.escalRecipients=Escalation recipients
eventHandlers.noEmailRecips=You must add email recipients
eventHandlers.escalDelayError=Escalation delay\u5fc5\u987b\u5927\u4e8e0
@@ -1029,8 +1029,7 @@ login.loginButton=\u767b\u5f55
login.unknownBrowser=\u8bf7\u68c0\u67e5\u60a8\u6d4f\u89c8\u5668\u7684\u517c\u5bb9\u6027...
login.supportedBrowser=\u672c\u6d4f\u89c8\u5668\u662f\u5b98\u65b9\u652f\u6301\u7684\u3002
login.unsupportedBrowser=\u60a8\u7684\u6d4f\u89c8\u5668\u53ef\u80fd\u53ef\u4ee5\u6d4f\u89c8\u672c\u7ad9\uff0c\u4f46\u5b83\u4e0d\u662fserosoft\u8f6f\u4ef6\u516c\u53f8\u5b98\u65b9\u652f\u6301\u7684\u6d4f\u89c8\u5668 \u3002\
-\u6211\u4eec\u63a8\u8350\u60a8\u4f7f\u7528 \u706b\u72d0(Firefox), Chrome, \u6216\u8005 \
-\u5fae\u8f6f\u7684Internet Explorer 7.
+\u6211\u4eec\u63a8\u8350\u60a8\u4f7f\u7528 Mozilla Firefox, Google Chrome.
login.nag=\u6ce8\u610f: \u7531\u4e8e\u60a8\u4f7f\u7528\u7684\u6d4f\u89c8\u5668\u4e0d\u5728\u5b98\u65b9\u652f\u6301\u7684\u8303\u56f4\u5185\uff0c\u6240\u4ee5\u8bbf\u95ee\u672c\u7ad9\u53ef\u80fd\u9047\u5230\u4e00\u4e9b\u95ee\u9898\u3002\u8bf7\u5347\u7ea7\u6216\u8005\u66f4\u6362\u6d4f\u89c8\u5668\u3002
mailingLists.added=\u90ae\u4ef6\u5217\u8868\u5df2\u589e\u52a0
@@ -1062,7 +1061,7 @@ notes.cancel=\u653e\u5f03
notes.timeByUsername=time\u6839\u636e\u7528\u6237\u540d
notification.newui.title=New page is available!
notification.newui.move=Move!
-notification.newui.dontshow=Don't show again.
+notification.newui.dontshow=Don’t show again.
pointDetails.recordCountError=\u8bb0\u5f55\u6570\u5fc5\u987b\u662f\u4e00\u4e2a\u6570\u5b57
pointDetails.timePeriodError=\u65f6\u95f4\u95f4\u9694\u5fc5\u987b\u662f\u4e00\u4e2a\u6570\u5b57
pointDetails.imageCountError=\u6570\u904d\u6570\u5fc5\u987b\u662f\u4e00\u4e2a\u6570\u5b57
@@ -1098,7 +1097,7 @@ pointDetails.accessType=\u8bbf\u95ee\u7c7b\u578b
pointEdit.buttons.enable=\u6fc0\u6d3b
pointEdit.buttons.disable=\u7981\u7528
pointEdit.buttons.restart=\u91cd\u542f
-pointEdit.buttons.note=\u6ce8\u610f: \u4fdd\u5b58\u3001\u7981\u7528\u3001\u91cd\u542f\u70b9\u5c06\u4f7f\u5176\u544a\u8b66\u4e8b\u4ef6\u7ea7\u522b\u53d8\u4e3a\u666e\u901a
+pointEdit.buttons.note=\u4fdd\u5b58\u3001\u7981\u7528\u3001\u91cd\u542f\u70b9\u5c06\u4f7f\u5176\u544a\u8b66\u4e8b\u4ef6\u7ea7\u522b\u53d8\u4e3a\u666e\u901a
pointEdit.chart.props=\u56fe\u8868\u6e32\u67d3\u5668\u5c5e\u6027
pointEdit.chart.type=\u7c7b\u578b
@@ -1248,7 +1247,7 @@ pointHierarchySLTS.dataSource=Data source
pointHierarchySLTS.xid=XID
pointHierarchySLTS.type=Type
pointHierarchySLTS.changeOfLanguageFailed=Change of language failed
-pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don't remove data point in root hierarchy
+pointHierarchySLTS.warningDontRemoveDataPointInRoot=Don’t remove data point in root hierarchy
pointHierarchySLTS.moveDataPointToRoot=Move the element to root level tree
pointHierarchySLTS.areYouSureToMoveElement=Are you sure to move element?
pointHierarchySLTS.movedElement=Moved element
@@ -1412,7 +1411,7 @@ scheduledEvents.validate.activeTrigger=\u521b\u5efaactive\u89e6\u53d1\u5668\u65f
scheduledEvents.validate.inactiveTrigger=\u521b\u5efainactive\u89e6\u53d1\u5668\u65f6\u53d1\u751f\u9519\u8bef\uff1a{0}
scheduledEvents.validate.aliasTooLong=\u522b\u540d\u4e0d\u80fd\u8d85\u8fc750\u5b57\u7b26
-sql.warning=\u8b66\u544a\uff1a \u4f7f\u7528\u672c\u5de5\u5177\u98ce\u9669\u81ea\u62c5\u3002\u4f7f\u7528\u65b9\u6cd5\u4e0d\u5f97\u5f53\u5c06\u53ef\u80fd\u5bfc\u81f4\u635f\u574f\u7684\u6570\u636e\u6216\u8005\u7cfb\u7edf\u7ea7\u522b\u7684\u9519\u8bef\u3002(\u539f\u56e0\u662fSQL\u76f4\u63a5\u4f5c\u7528\u4e8e\u6570\u636e\u5e93)
+sql.warning= \u4f7f\u7528\u672c\u5de5\u5177\u98ce\u9669\u81ea\u62c5\u3002\u4f7f\u7528\u65b9\u6cd5\u4e0d\u5f97\u5f53\u5c06\u53ef\u80fd\u5bfc\u81f4\u635f\u574f\u7684\u6570\u636e\u6216\u8005\u7cfb\u7edf\u7ea7\u522b\u7684\u9519\u8bef\u3002(\u539f\u56e0\u662fSQL\u76f4\u63a5\u4f5c\u7528\u4e8e\u6570\u636e\u5e93)
sql.sql=SQL
sql.query=\u63d0\u4ea4\u67e5\u8be2
sql.update=\u63d0\u4ea4\u66f4\u65b0
@@ -1579,7 +1578,7 @@ viewEdit.compound.duration=\u671f\u95f4
views.title=\u56fe\u5f62\u5316\u89c6\u56fe
views.newView=\u65b0\u5efa\u89c6\u56fe
-views.noViews=\u672a\u521b\u5efa\u56fe\u5f62\u5316\u89c6\u56fe. \u9a6c\u4e0a\u521b\u5efa.
+views.noViews=\u672a\u521b\u5efa\u56fe\u5f62\u5316\u89c6\u56fe.
viewEdit.viewDelete=Delete view:
viewEdit.viewDeleteConfirm=Confirm
@@ -1678,7 +1677,7 @@ event.system.pointLink=\u70b9\u7684\u94fe\u63a5\u5931\u8d25
event.audit.added=\u7528\u6237 "{0}" \u5df2\u88ab\u521b\u5efa {1} \u83b7\u5f97\u6807\u8bc6\u4e3a {2}: {3}
event.audit.changed=\u7528\u6237 "{0}" \u5df2\u88ab\u66f4\u6539 {1} \u5176\u6807\u8bc6\u4e3a {2}: {3}
-event.audit.changedProperty=
{0}: "{1}" -> "{2}"
+event.audit.changedProperty={0}: "{1}" -> "{2}"
event.audit.compoundEventDetector=\u7ec4\u5408\u4e8b\u4ef6\u4fa6\u5bdf\u5668
event.audit.dataPoint=\u6570\u636e\u70b9
event.audit.dataSource=\u6570\u636e\u6e90
@@ -1687,7 +1686,7 @@ event.audit.eventHandler=\u4e8b\u4ef6\u5904\u7406\u5668
event.audit.maintenanceEvent=Maintenance event
event.audit.pointEventDetector=\u70b9\u4e8b\u4ef6\u4fa6\u5bdf\u5668
event.audit.pointLink=\u70b9\u7684\u94fe\u63a5
-event.audit.property=
{0}="{1}"
+event.audit.property={0}="{1}"
event.audit.propertyList.0=
event.audit.propertyList.1={0}
event.audit.propertyList.10={0}{1}{2}{3}{4}{5}{6}{7}{8}{9}
@@ -2003,7 +2002,7 @@ emport.error.eventCode=\u65e0\u6548\u7684\u4e8b\u4ef6\u4ee3\u7801''{0}''\u3002\u
emport.error.alarmLevel=\u4e8b\u4ef6''{1}''\u7684\u65e0\u6548\u544a\u8b66\u7ea7\u522b''{0}''\u3002\u65e0\u6548\u503c\u4e3a\uff1a{2}
emport.error.missingUser=\u53eb''{0}''\u540d\u5b57\u7684\u7528\u6237\u6ca1\u6709\u627e\u5230
emport.error.viewShare.missing=\u89c6\u56fe\u5171\u4eab\u4e2d\u6ca1\u6709''{0}''
-emport.error.component.incompatibleDataType='XID'\u4e3a''{0}''\u7684\u6570\u636e\u70b9\u7684\u5c5e\u6027\u7c7b\u578b\u4e0e\u6570\u636e\u7c7b\u578b''{1}''\u4e0d\u5339\u914d
+emport.error.component.incompatibleDataType=’XID’\u4e3a''{0}''\u7684\u6570\u636e\u70b9\u7684\u5c5e\u6027\u7c7b\u578b\u4e0e\u6570\u636e\u7c7b\u578b''{1}''\u4e0d\u5339\u914d
emport.error.compound.invalidChildId=\u7c7b\u578b\u4e3a''{1}''\u7684\u7ec4\u5408\u89c6\u56fe\u7ec4\u4ef6\u7684\u5b50id''{0}''\u65e0\u6548\u3002\u6709\u6548\u7684id\u4e3a\uff1a{2}
emport.error.component.unknownDynamicImage=id\u4e3a''{0}''\u7684\u52a8\u6001\u56fe\u6ca1\u6709\u53d1\u73b0\u3002\u5df2\u77e5\u7684\u52a8\u6001\u56feid\u5982\u4e0b\uff1a{1}
emport.error.component.unknownImageSet=id\u4e3a''{0}''\u7684\u56fe\u7247\u96c6\u5408\u6ca1\u6709\u53d1\u73b0\u3002\u5df2\u77e5\u7684\u56fe\u7247\u96c6\u5408id\u5982\u4e0b\uff1a{1}
@@ -2450,7 +2449,7 @@ publisherEdit.persistent.status.connectionState=Connection\: {0}
emport.maintenanceEvent.prefix=Maintenance event ''{0}''\: {1}
dox.internalDS=Internal Data Source
systemSettings.instanceId=Instance ID
-dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee
firmware
revision
+dsEdit.viconics.zigbeeFirmwareRevisionBr=Zigbee firmware revision
eventHandlers.activeScript=When active script
dsEdit.mbus.addressHex=Address
dsEdit.mbus.manufacturer=Manufacturer
@@ -2488,9 +2487,9 @@ engUnit.abbr.5=V
engUnit.abbr.4=ohms
engUnit.abbr.3=A
engUnit.abbr.2=mA
-engUnit.abbr.1=f2
+engUnit.abbr.1=ft\u00b2
graphic.enhancedImageChart.pointConfig.showPoints=Display points of measure\:
-engUnit.abbr.0=m2
+engUnit.abbr.0=m\u00b2
scripts.objectsContext=Context objects
dsEdit.radiuino.radiuinoDataType.2bUnsigned=Integer (unsigned 2 bytes)
dsEdit.iec101Ethernet=IEC101 Ethernet
@@ -2508,7 +2507,7 @@ event.pachube.dataStreamNotFound=Data stream "{0}" in feed {1} not found or has
dsEdit.asciiSerial.timeout=Timeout (ms)
dsEdit.openv4j.dataPointSettable=Setable
maintenanceEvents.addMe=Add maintenance event
-emport.publisher.xid=A data source with name ''{0}'' does not have an 'xid' value. Ignored.
+emport.publisher.xid=A data source with name ''{0}'' does not have an ’xid’ value. Ignored.
dsEdit.asciiSerial=ASCII Serial
dsEdit.mbus.firstHexAddress=From Address (Hex)
dsEdit.modbusIp.socketPointName=TCP socket monitoring
@@ -2604,7 +2603,7 @@ publisherEdit.persistent.startSync=Synchronize history
dsEdit.radiuino.desc=Radiuino Properties
graphic.button=ON/OFF Button
dsEdit.openv4j.device=Device
-dsEdit.viconics.chipRevisionBr=Chip
revision
+dsEdit.viconics.chipRevisionBr=Chip revision
dox.importProject=Importing projects
events.search.maxResults=Max results
dox.pachubeDS=Pachube data source
@@ -2664,7 +2663,7 @@ publisherEdit.pachube.retries=Retries
maintenanceEvents.schedule.manual={0} - Manual
dsEdit.persistent.dsconn=Port\: {0}
emport.error.eventType.missing.reference=Event type must have a ''{0}''
-dsEdit.viconics.firmwareRevision=Firmware
revision
+dsEdit.viconics.firmwareRevision=Firmware revision
pointEdit.props.deviceName=Device Name
dsEdit.alpha2.station=Station
dsEdit.dnp3.minIndex=Min index
@@ -2863,7 +2862,7 @@ engUnit.abbr.133=hectopascals
engUnit.abbr.132=milliwatts
engUnit.abbr.131=per hour
engUnit.abbr.130=megahertz
-emport.compoundEvent.xid=A compound event detector does not have an 'xid' value. Ignored.
+emport.compoundEvent.xid=A compound event detector does not have an ’xid’ value. Ignored.
engUnit.139=megajoules per square meter
engUnit.138=kilowatt hours per square foot
engUnit.137=kilowatt hours per square meter
@@ -3072,11 +3071,11 @@ engUnit.41=tons
dsEdit.dnp3.validate.indexUsed=Index already in use
engUnit.40=pounds mass
publisherEdit.pachube.point.feedId=Feed ID
-emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid 'type' value of ''{1}''. Valid types are {2}
+emport.publisher.invalidType=Publisher with XID ''{0}'' does not already exist and has an invalid ’type’ value of ''{1}''. Valid types are {2}
dsEdit.pachube.timeout=Timeout (seconds)
common.confirmDelete=Are you sure you want delete?
dsEdit.modbus.maxReadBitCount=Max read bit count
-dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee
network
address
+dsEdit.viconics.zigbeeNetworkAddressBr=Zigbee network address
scripts.seDetails=Script details
dsedit.opc.tagName=Tag Tag
dsEdit.modbus.modbusDataType.varchar=Variable length string
@@ -3169,7 +3168,7 @@ dsEdit.opc=OPC DA
dsEdit.drStorageHt5b.pointType=Point Type
events.listed={0} event(s) listed
events.ackedByDeletedUser=- (deleted user)
-eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler's inactive list
+eventHandlers.inactiveTestEmailMessage=This message was sent as a test of an event handler’s inactive list
dsEdit.jmx.addPoint=Add point
dsEdit.asciiSerial.charStopMode.charASCII=ASCII character
dsEdit.radiuino.offset=Offset
@@ -3178,7 +3177,7 @@ dsEdit.openv4j.desc=OpenV4J properties
userProfiles.validate.successDeleting=Profile successfully deleted.
dsEdit.alpha2.deviceCode.commWordDevice=Comm Word Device
dox.asciiFileReaderPP=ASCII File Reader PP
-emport.mailingList.xid=A mailing list does not have an 'xid' value. Ignored.
+emport.mailingList.xid=A mailing list does not have an ’xid’ value. Ignored.
aphic.simpleCompound.leadPoint=Lead Point
graphic.enhancedPoint=Enhanced point
maintenanceEvents.meDisabled=Disabled maintenance event
@@ -3212,7 +3211,7 @@ dsEdit.internal.attr.BATCH_ENTRIES=Point values to be written
event.pb.persistent.syncCompleted=Synchronization completed
publisherEdit.httpSender.dateFormat=Date format
scripts.se=Script
-emport.watchList.xid=A watch list does not have an 'xid' value. Ignored.
+emport.watchList.xid=A watch list does not have an ’xid’ value. Ignored.
systemSettings.contentType.html=HTML only
dsEdit.mbus.search=Search
dsEdit.opc.validate.dataSourceNotSaved=You must first save the data source
@@ -3232,14 +3231,14 @@ dox.scriptDPObject=Data Point Context Object
dox.opcDS=Data Source OPC
dsEdit.modbus.locatorTestIp.startError=There was a problem testing the locator. ({0})
publisherEdit.persistent=Serotonin Persistent TCP
-dsEdit.viconics.commAddress=Comm
address
+dsEdit.viconics.commAddress=Comm address
dsEdit.openv4j.dataPoint=Datapoint
dsEdit.mbus.addPoint=add
validate.between=Must be between {0} and {1}
dsEdit.iec101.dpconn=TypeId {0}, IOA {1}
dsEdit.jmx.attributeNotComposite=Attribute ''{0}'' in ''{1}'' is not composite
maintenanceEvents.validate.inactiveCron=Error in inactive cron expression\: {0}
-emport.scheduledEvent.xid=A scheduled event does not have an 'xid' value. Ignored.
+emport.scheduledEvent.xid=A scheduled event does not have an ’xid’ value. Ignored.
emport.error.eventHandler.invalid=Event handler has an invalid ''{0}'' value of ''{1}''. Valid values are {2}
dsEdit.viconics.channel=Channel
dsEdit.mbus.useDirectConnection=Direct connection
@@ -3302,7 +3301,7 @@ dsEdit.mbus.vifeLabels=Vife labels
pointDetails.pointNotFound=Point not found
dsEdit.asciiSerial.baud=Baud rate
dox.radiuinoPP=Radiuino data point
-emport.eventHandler.xid=A point link does not have an 'xid' value. Ignored.
+emport.eventHandler.xid=A point link does not have an ’xid’ value. Ignored.
dsEdit.bacnetIp.objectList=Device object list
dsEdit.mbus.responseFrame=Frame
engUnitGroup.length=Length
@@ -3330,7 +3329,7 @@ dsEdit.modbus.dpconn3=Connection monitoring
dsEdit.modbus.dpconn2=Slave id {0} monitor
graphic.enhancedImageChart.pointConfig.renderMode=Render mode\:
dsEdit.serial.parity.space=Space
-emport.maintenanceEvent.xid=A maintenance event does not have an 'xid' value. Ignored.
+emport.maintenanceEvent.xid=A maintenance event does not have an ’xid’ value. Ignored.
dsEdit.openv4j.refreshStopped=Update finished
dsEdit.internal.attr.MONITOR_STACK_HEIGHT=Maximum thread stack height
dsEdit.viconics.port=Port
@@ -3368,7 +3367,7 @@ dsEdit.opc.tagName=Tag Name
graphic.link=Link
eventHandlers.inactiveOverride=Override inactive recipients
dsEdit.bacnetIp.remoteDeviceNetworkNumber=Network Number
-emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a 'type' value. Valid types are {1}
+emport.publisher.missingType=Publisher with XID ''{0}'' does not already exist and does not have a ’type’ value. Valid types are {1}
dsEdit.alpha2.deviceCode.commBitDevice=Comm Bit Device
dsEdit.mbus.tcpIpBitPerSecond=Baudrate
dox.jmxDS=JMX Data Source
@@ -3380,7 +3379,7 @@ maintenanceEvents.toggle.disabled=Cannot toggle. Event is currently disabled.
maintenanceEvents.validate.activeCron=Error in active cron expression\: {0}
dsEdit.bacnetIp.remoteDeviceInstanceNumber=Remote device instance number
dsEdit.nodaves7.s7writeBytesQty=Bytes quantity
-emport.versionError=The project version ({0}) isn't compatible with current system version ({1})
+emport.versionError=The project version ({0}) isn’t compatible with current system version ({1})
publisherEdit.persistent.sync.none=None
dsEdit.dnp3Serial.baud=Baud rate
eventHandlers.noInactiveRecips=You must add inactive recipients
@@ -3409,7 +3408,7 @@ dsEdit.asciiFile.checkFile=Check
event.persistent.xidTooLong=XID of "{0}" point is too long.
event.viconics.duplicateCommException=Duplicate comm address detected\: {0}
dsEdit.drStorageHt5b.type.Temperature=Temperature
-dsEdit.viconics.modelNumber=Model
number
+dsEdit.viconics.modelNumber=Model number
dsEdit.dnp3.binaryInput=Binary Input
dsEdit.jmx.getObjectNames=Get object names
dox.colours=Color
@@ -3439,4 +3438,17 @@ systemsettings.webresource.uploads.path=Uploads images path
systemsettings.webresource.graphics.path=Graphics images path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
-annotation.api=REST API
\ No newline at end of file
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
+pointEdit.buttons.note.prefix=\u6ce8\u610f:
+sql.warning.prefix=\u8b66\u544a\uff1a:
+views.noViews.prefix=\u9a6c\u4e0a\u521b\u5efa.
+annotation.api=REST API
+dsEdit.sql.statementLimit=Statement limit
+dsEdit.sql.statementLimit.warning=Setting the value 0 in the Statement limit field means there is no limit for the select query, which may lead to a serious application failure due to filling up the memory needed for the application to run. Do you confirm setting Statement limit equals 0?
+event.sms.failure=Failed to send sms titled "{0}" to "{1}". Message: "{2}"
+event.script.failure=Failed execute script: "{0}", Message: "{1}"
+event.system.sms=Sms send failure
+event.system.script=Script event handler failure
+validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
\ No newline at end of file
diff --git a/test/utils/ScriptTestUtils.java b/test/utils/ScriptTestUtils.java
index b0a050abcf..e9a51fd4ac 100644
--- a/test/utils/ScriptTestUtils.java
+++ b/test/utils/ScriptTestUtils.java
@@ -7,12 +7,14 @@
import com.serotonin.mango.rt.dataImage.DataPointRT;
import com.serotonin.mango.rt.dataImage.PointValueTime;
import com.serotonin.mango.rt.dataImage.types.MangoValue;
+import com.serotonin.mango.rt.dataSource.DataSourceRT;
import com.serotonin.mango.vo.DataPointVO;
import com.serotonin.mango.vo.DataPointVO.LoggingTypes;
import com.serotonin.mango.vo.User;
import com.serotonin.mango.vo.dataSource.PointLocatorVO;
import com.serotonin.mango.vo.dataSource.virtual.VirtualPointLocatorVO;
import com.serotonin.mango.vo.permission.Permissions;
+import org.mockito.Mockito;
import org.scada_lts.web.beans.ApplicationBeans;
import org.scada_lts.web.ws.services.DataPointServiceWebSocket;
import utils.mock.MockUtils;
@@ -72,4 +74,10 @@ public static void configMock(RuntimeManager runtimeManager, ScriptContextObject
when(ApplicationBeans.getDataPointServiceWebSocketBean()).thenReturn(dataPointServiceWebSocket);
}
+ public static void configScriptMock(RuntimeManager runtimeManager, ScriptContextObject scriptContextObject) throws Exception {
+ DataSourceRT dataSourceRT = mock(DataSourceRT.class);
+ Mockito.when(dataSourceRT.isInitialized()).thenReturn(true);
+ Mockito.when(runtimeManager.getRunningDataSource(anyInt())).thenReturn(dataSourceRT);
+ ScriptTestUtils.configMock(runtimeManager, scriptContextObject);
+ }
}
diff --git a/test/utils/mock/RuntimeMockUtils.java b/test/utils/mock/RuntimeMockUtils.java
new file mode 100644
index 0000000000..6fd56c22d4
--- /dev/null
+++ b/test/utils/mock/RuntimeMockUtils.java
@@ -0,0 +1,66 @@
+package utils.mock;
+
+import com.serotonin.mango.Common;
+import com.serotonin.mango.rt.EventManager;
+import com.serotonin.mango.rt.RuntimeManager;
+import com.serotonin.mango.rt.maint.BackgroundProcessing;
+import com.serotonin.mango.util.timeout.TimeoutTask;
+import com.serotonin.mango.web.ContextWrapper;
+import org.powermock.api.mockito.PowerMockito;
+import org.scada_lts.dao.SystemSettingsDAO;
+import org.scada_lts.mango.service.DataPointService;
+import org.scada_lts.mango.service.DataSourceService;
+import org.scada_lts.mango.service.PointValueService;
+import org.scada_lts.mango.service.SystemSettingsService;
+import org.scada_lts.web.beans.ApplicationBeans;
+import org.scada_lts.web.ws.services.DataPointServiceWebSocket;
+
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.powermock.api.mockito.PowerMockito.*;
+import static org.powermock.api.mockito.PowerMockito.when;
+
+public final class RuntimeMockUtils {
+
+ private RuntimeMockUtils() {}
+
+ public static void runtimeManagerMock(RuntimeManager runtimeManager, EventManager eventManager) throws Exception {
+
+ DataSourceService dataSourceService = PowerMockito.mock(DataSourceService.class);
+ whenNew(DataSourceService.class).withNoArguments().thenReturn(dataSourceService);
+
+ DataPointService dataPointService = PowerMockito.mock(DataPointService.class);
+ whenNew(DataPointService.class).withNoArguments().thenReturn(dataPointService);
+
+ SystemSettingsService systemSettingsService = PowerMockito.mock(SystemSettingsService.class);
+ whenNew(SystemSettingsService.class).withNoArguments().thenReturn(systemSettingsService);
+
+ SystemSettingsDAO systemSettingsDAO = PowerMockito.mock(SystemSettingsDAO.class);
+ whenNew(SystemSettingsDAO.class).withNoArguments().thenReturn(systemSettingsDAO);
+
+ mockStatic(SystemSettingsDAO.class);
+ when(SystemSettingsDAO.getValue(anyString())).thenReturn("");
+ when(SystemSettingsDAO.getFutureDateLimit()).thenReturn(1L);
+
+ PointValueService mangoPointValues = PowerMockito.mock(PointValueService.class);
+ whenNew(PointValueService.class).withNoArguments().thenReturn(mangoPointValues);
+
+ mockStatic(ApplicationBeans.class);
+ DataPointServiceWebSocket dataPointServiceWebSocket = PowerMockito.mock(DataPointServiceWebSocket.class);
+ when(ApplicationBeans.getDataPointServiceWebSocketBean()).thenReturn(dataPointServiceWebSocket);
+
+ ContextWrapper contextWrapper = PowerMockito.mock(ContextWrapper.class);
+ BackgroundProcessing backgroundProcessing = PowerMockito.mock(BackgroundProcessing.class);
+
+ when(contextWrapper.getRuntimeManager()).thenReturn(runtimeManager);
+ when(contextWrapper.getEventManager()).thenReturn(eventManager);
+ when(contextWrapper.getBackgroundProcessing()).thenReturn(backgroundProcessing);
+
+ TimeoutTask timeoutTaskMock = mock(TimeoutTask.class);
+ whenNew(TimeoutTask.class).withAnyArguments()
+ .thenReturn(timeoutTaskMock);
+
+ Common.ctx = contextWrapper;
+ Common.timer.init();
+
+ }
+}
diff --git a/webapp-resources/log4j2.xml b/webapp-resources/log4j2.xml
index 498cbf1bfe..8f07ef9f6d 100644
--- a/webapp-resources/log4j2.xml
+++ b/webapp-resources/log4j2.xml
@@ -36,7 +36,7 @@
ERROR
ERROR
INFO
- INFO
+ ERROR
INFO
@@ -256,6 +256,13 @@
+
+
+
+
+
+
+
@@ -288,6 +295,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/webapp-resources/messages_de.properties b/webapp-resources/messages_de.properties
index 8a6fa0a49b..1cf7edbb71 100644
--- a/webapp-resources/messages_de.properties
+++ b/webapp-resources/messages_de.properties
@@ -3335,6 +3335,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Hinweis:
sql.warning.prefix=Achtung:
@@ -3346,6 +3348,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
diff --git a/webapp-resources/messages_en.properties b/webapp-resources/messages_en.properties
index 5d4bdf9842..6680867f26 100644
--- a/webapp-resources/messages_en.properties
+++ b/webapp-resources/messages_en.properties
@@ -3338,6 +3338,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Note:
sql.warning.prefix=Warning:
@@ -3349,6 +3351,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3362,4 +3365,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_es.properties b/webapp-resources/messages_es.properties
index cc979ad4c8..4e12fedfae 100644
--- a/webapp-resources/messages_es.properties
+++ b/webapp-resources/messages_es.properties
@@ -3378,6 +3378,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Nota:
sql.warning.prefix=Advertencia:
@@ -3389,6 +3391,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3402,4 +3405,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_fi.properties b/webapp-resources/messages_fi.properties
index aaa55078b1..5a28a5bf6f 100644
--- a/webapp-resources/messages_fi.properties
+++ b/webapp-resources/messages_fi.properties
@@ -3463,6 +3463,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Huom:
sql.warning.prefix=Varoitus:
@@ -3474,6 +3476,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3487,4 +3490,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_fr.properties b/webapp-resources/messages_fr.properties
index 6bec4083d1..1518b29416 100644
--- a/webapp-resources/messages_fr.properties
+++ b/webapp-resources/messages_fr.properties
@@ -3332,6 +3332,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Note:
sql.warning.prefix=Attention:
@@ -3343,6 +3345,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3356,4 +3359,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_lu.properties b/webapp-resources/messages_lu.properties
index 49fc70f8a9..e71eb551e6 100644
--- a/webapp-resources/messages_lu.properties
+++ b/webapp-resources/messages_lu.properties
@@ -3351,6 +3351,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Hinweis:
sql.warning.prefix=Warnung:
@@ -3362,6 +3364,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3375,4 +3378,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_nl.properties b/webapp-resources/messages_nl.properties
index 847e164111..7dfbb6141f 100644
--- a/webapp-resources/messages_nl.properties
+++ b/webapp-resources/messages_nl.properties
@@ -3453,6 +3453,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Noot:
sql.warning.prefix=Waarschuwing:
@@ -3464,6 +3466,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3477,4 +3480,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_pl.properties b/webapp-resources/messages_pl.properties
index c84a16787f..849312d4d7 100644
--- a/webapp-resources/messages_pl.properties
+++ b/webapp-resources/messages_pl.properties
@@ -3475,6 +3475,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Notatka:
sql.warning.prefix=Ostrzeżenie:
@@ -3486,6 +3488,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3499,4 +3502,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_pt.properties b/webapp-resources/messages_pt.properties
index 67caffd5a4..5cfe62b4fb 100644
--- a/webapp-resources/messages_pt.properties
+++ b/webapp-resources/messages_pt.properties
@@ -3490,6 +3490,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=Nota:
sql.warning.prefix=Alerta:
@@ -3501,6 +3503,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3514,4 +3517,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_ru.properties b/webapp-resources/messages_ru.properties
index b3687fdf0e..063015fd4d 100644
--- a/webapp-resources/messages_ru.properties
+++ b/webapp-resources/messages_ru.properties
@@ -3486,6 +3486,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:
sql.warning.prefix=\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435:
@@ -3497,6 +3499,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3510,4 +3513,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images
diff --git a/webapp-resources/messages_zh.properties b/webapp-resources/messages_zh.properties
index 25314c370f..82becb4dd4 100644
--- a/webapp-resources/messages_zh.properties
+++ b/webapp-resources/messages_zh.properties
@@ -3438,6 +3438,8 @@ systemsettings.webresource.uploads.path=Uploads Images Path
systemsettings.webresource.graphics.path=Graphics Images Path
systemsettings.webresource.uploads.path.wrong=Uploaded images save path must end with "uploads" or "uploads{0}"
systemsettings.webresource.graphics.path.wrong=Graphics images path must end with "graphics" or "graphics{0}"
+event.ds.monitorWrite=Monitor write exception
+dsEdit.mbus.correctionFactor=Correction factor
annotation.api=REST API
pointEdit.buttons.note.prefix=\u6ce8\u610f:
sql.warning.prefix=\u8b66\u544a\uff1a:
@@ -3449,6 +3451,7 @@ event.script.failure=Failed execute script: "{0}", Message: "{1}"
event.system.sms=Sms send failure
event.system.script=Script event handler failure
validate.valueRestored=Previous value restored
+validate.invalidVariable=Invalid variable: {0}
events.assigneeByUser=- {0}
events.assign=Assign
events.unassign=Unassign
@@ -3462,4 +3465,4 @@ viewEdit.graphic.hideAssigneeColumn=Hide Assignee column
systemsettings.top.description.prefix = Top description prefix
systemsettings.top.description = Top description
header.imageSets=Image sets
-header.dynamicImages=Dynamic images
\ No newline at end of file
+header.dynamicImages=Dynamic images