diff --git a/WebContent/WEB-INF/jsp/scripting.jsp b/WebContent/WEB-INF/jsp/scripting.jsp index d1832db303..3380fd34cc 100644 --- a/WebContent/WEB-INF/jsp/scripting.jsp +++ b/WebContent/WEB-INF/jsp/scripting.jsp @@ -43,7 +43,7 @@ var xid = jQuery("#xid"); // saveScript() nie zdarzy zapisac !!! jQuery.ajax({ - url: myLocation+"/script/execute/"+xid[0].value, + url: myLocation+"script/execute/"+xid[0].value, type:"POST", success: function(){ setUserMessage(" ") diff --git a/WebContent/WEB-INF/jsp/systemSettings.jsp b/WebContent/WEB-INF/jsp/systemSettings.jsp index 27f89f13aa..35899f2afa 100644 --- a/WebContent/WEB-INF/jsp/systemSettings.jsp +++ b/WebContent/WEB-INF/jsp/systemSettings.jsp @@ -482,7 +482,7 @@ jQuery.ajax({ type: 'GET', dataType: 'text', - url:myLocation+"/api/resources/imagesRefresh", + url:myLocation+"api/resources/imagesRefresh", success: function(msg){ alert("Success: the resource images has been refreshed"); }, diff --git a/WebContent/WEB-INF/snippet/warningContent.jsp b/WebContent/WEB-INF/snippet/warningContent.jsp index aa8192481d..29f42d421e 100644 --- a/WebContent/WEB-INF/snippet/warningContent.jsp +++ b/WebContent/WEB-INF/snippet/warningContent.jsp @@ -37,7 +37,7 @@ - + diff --git a/WebContent/WEB-INF/snippet/warningIcon.jsp b/WebContent/WEB-INF/snippet/warningIcon.jsp new file mode 100644 index 0000000000..b9c16068b0 --- /dev/null +++ b/WebContent/WEB-INF/snippet/warningIcon.jsp @@ -0,0 +1,9 @@ +<%@ include file="/WEB-INF/snippet/common.jsp" %> + + + + + + + + \ No newline at end of file diff --git a/WebContent/WEB-INF/snippet/watchListMessages.jsp b/WebContent/WEB-INF/snippet/watchListMessages.jsp index 9f6a6ee9c4..7539d6e682 100644 --- a/WebContent/WEB-INF/snippet/watchListMessages.jsp +++ b/WebContent/WEB-INF/snippet/watchListMessages.jsp @@ -25,7 +25,7 @@ -
+
diff --git a/WebContent/WEB-INF/tags/alarmAck.tag b/WebContent/WEB-INF/tags/alarmAck.tag index c036ee8e80..988b4b9769 100644 --- a/WebContent/WEB-INF/tags/alarmAck.tag +++ b/WebContent/WEB-INF/tags/alarmAck.tag @@ -43,6 +43,10 @@ + + + + diff --git a/WebContent/WEB-INF/tags/pointComponent.tag b/WebContent/WEB-INF/tags/pointComponent.tag index fbba850231..940959daea 100644 --- a/WebContent/WEB-INF/tags/pointComponent.tag +++ b/WebContent/WEB-INF/tags/pointComponent.tag @@ -58,7 +58,7 @@
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