Search in sources :

Example 6 with PointValueTime

use of com.serotonin.m2m2.rt.dataImage.PointValueTime in project ma-modules-public by infiniteautomation.

the class SerialDataSourceRT method serialEvent.

@Override
public void serialEvent(SerialPortProxyEvent evt) {
    // Keep a lock on the buffer while we do this
    synchronized (this.buffer) {
        // If our port is dead, say so
        if (this.port == null) {
            raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.readFailedPortNotSetup"));
            return;
        }
        // String msg = null;
        try {
            // Don't read during timeout events as there could be no data and this would block till there is
            if (!(evt instanceof TimeoutSerialEvent)) {
                InputStream in = this.port.getInputStream();
                int data;
                // this may not be the full message, or may read multiple messages
                while ((data = in.read()) > -1) {
                    if (buffer.size() >= this.vo.getMaxMessageSize()) {
                        buffer.popAll();
                        raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.readFailed", "Max message size reached!"));
                        // Give up
                        return;
                    }
                    buffer.push(data);
                }
                // Log our buffer contents
                byte[] logMsg = buffer.peekAll();
                if (this.vo.isLogIO()) {
                    if (this.vo.isHex())
                        this.ioLog.log(true, logMsg);
                    else
                        this.ioLog.log("I: " + new String(logMsg, Common.UTF8_CS));
                }
                // Serial Event so setup a Timeout Task to fire after the message timeout
                if (this.buffer.size() > 0)
                    this.timeoutTask = new TimeoutTask(this.vo.getReadTimeout(), new SerialTimeoutClient(this));
            }
            // We either use a terminator and timeout OR just a Timeout
            if (vo.getUseTerminator()) {
                // If timeout then process the buffer
                // If serial event then read input and process buffer
                // "!([A-Z0-9]{3,3})([a-zA-Z])(.*);";
                String messageRegex = vo.getMessageRegex();
                // DS Information
                int pointIdentifierIndex = vo.getPointIdentifierIndex();
                // Create a String so we can use Regex and matching
                String msg = null;
                if (this.vo.isHex()) {
                    msg = convertFromHex(buffer.peekAll());
                } else {
                    msg = new String(buffer.peekAll(), Common.UTF8_CS);
                }
                // Now we have a string that contains the entire contents of the buffer,
                // split on terminator, keep it on the end of the message and process any full messages
                // and pop them from the buffer
                String[] messages = splitMessages(msg, this.vo.getMessageTerminator());
                for (String message : messages) {
                    // potentially be one incomplete message.
                    if (canProcessTerminatedMessage(message, this.vo.getMessageTerminator())) {
                        // Pop off this message
                        this.buffer.pop(message.length());
                        if (LOG.isDebugEnabled())
                            LOG.debug("Matching will use String: " + message);
                        final AtomicBoolean matcherFailed = new AtomicBoolean(false);
                        pointListChangeLock.readLock().lock();
                        try {
                            for (final DataPointRT dp : this.dataPoints) {
                                SerialPointLocatorVO plVo = dp.getVO().getPointLocator();
                                MatchCallback callback = new MatchCallback() {

                                    @Override
                                    public void onMatch(String pointIdentifier, PointValueTime value) {
                                        if (!updatePointValue(value, dp)) {
                                            matcherFailed.set(true);
                                            raiseEvent(POINT_READ_PATTERN_MISMATCH_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.invalidValue", dp.getVO().getXid()));
                                        }
                                    }

                                    @Override
                                    public void pointPatternMismatch(String message, String messageRegex) {
                                    // Ignore as this just isn't a message we care about
                                    }

                                    @Override
                                    public void messagePatternMismatch(String message, String messageRegex) {
                                        raiseEvent(POINT_READ_PATTERN_MISMATCH_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.patternMismatch", messageRegex, message));
                                        matcherFailed.set(true);
                                    }

                                    @Override
                                    public void pointNotIdentified(String message, String messageRegex, int pointIdentifierIndex) {
                                    // Don't Care
                                    }

                                    @Override
                                    public void matchGeneralFailure(Exception e) {
                                        raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.readFailed", e.getMessage()));
                                        matcherFailed.set(true);
                                    }
                                };
                                try {
                                    matchPointValue(message, messageRegex, pointIdentifierIndex, plVo, vo.isHex(), LOG, callback);
                                } catch (Exception e) {
                                    callback.matchGeneralFailure(e);
                                }
                            }
                        } finally {
                            pointListChangeLock.readLock().unlock();
                        }
                        // If no failures...
                        if (!matcherFailed.get())
                            returnToNormal(POINT_READ_PATTERN_MISMATCH_EVENT, System.currentTimeMillis());
                        returnToNormal(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis());
                    }
                    if (evt instanceof TimeoutSerialEvent) {
                        // Clear the buffer
                        this.buffer.popAll();
                    } else {
                        // Check to see if we have remaining data, if not cancel timeout
                        if (this.buffer.size() == 0)
                            this.timeoutTask.cancel();
                    }
                }
                return;
            } else {
                // Do we have a timeout generated message?
                if (evt instanceof TimeoutSerialEvent) {
                    String msg = null;
                    // We are a timeout event so we have a timeout, pop everything into the message and assume its a message
                    if (this.vo.isHex()) {
                        msg = convertFromHex(buffer.popAll());
                    } else {
                        msg = new String(buffer.popAll(), Common.UTF8_CS);
                    }
                    // Just do a match on the Entire Message because we are not using Terminator
                    // String messageRegex = ".*"; //Match everything
                    // int pointIdentifierIndex = 0; //Whole message
                    // "!([A-Z0-9]{3,3})([a-zA-Z])(.*);";
                    String messageRegex = vo.getMessageRegex();
                    // DS Information
                    int pointIdentifierIndex = vo.getPointIdentifierIndex();
                    if (LOG.isDebugEnabled())
                        LOG.debug("Matching will use String: " + msg);
                    final AtomicBoolean matcherFailed = new AtomicBoolean(false);
                    synchronized (pointListChangeLock) {
                        for (final DataPointRT dp : this.dataPoints) {
                            SerialPointLocatorVO plVo = dp.getVO().getPointLocator();
                            MatchCallback callback = new MatchCallback() {

                                @Override
                                public void onMatch(String pointIdentifier, PointValueTime pvt) {
                                    if (!updatePointValue(pvt, dp)) {
                                        matcherFailed.set(true);
                                        raiseEvent(POINT_READ_PATTERN_MISMATCH_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.invalidValue", dp.getVO().getXid()));
                                    }
                                    // Ensure we clear out the buffer...
                                    buffer.popAll();
                                }

                                @Override
                                public void pointPatternMismatch(String message, String messageRegex) {
                                // Ignore as this just isn't a message we care about
                                }

                                @Override
                                public void messagePatternMismatch(String message, String messageRegex) {
                                    raiseEvent(POINT_READ_PATTERN_MISMATCH_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.patternMismatch", messageRegex, message));
                                    matcherFailed.set(true);
                                }

                                @Override
                                public void pointNotIdentified(String message, String messageRegex, int pointIdentifierIndex) {
                                // Don't Care
                                }

                                @Override
                                public void matchGeneralFailure(Exception e) {
                                    raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.readFailed", e.getMessage()));
                                    matcherFailed.set(true);
                                }
                            };
                            try {
                                matchPointValue(msg, messageRegex, pointIdentifierIndex, plVo, vo.isHex(), LOG, callback);
                            } catch (Exception e) {
                                callback.matchGeneralFailure(e);
                            }
                        }
                    }
                    // If no failures...
                    if (!matcherFailed.get())
                        returnToNormal(POINT_READ_PATTERN_MISMATCH_EVENT, System.currentTimeMillis());
                    returnToNormal(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis());
                }
            }
        } catch (Exception e) {
            LOG.error(e.getMessage(), e);
            // Ensure we clear out the buffer...
            this.buffer.popAll();
            raiseEvent(POINT_READ_EXCEPTION_EVENT, System.currentTimeMillis(), true, new TranslatableMessage("event.serial.readFailed", e.getMessage()));
        }
    }
// End synch
}
Also used : InputStream(java.io.InputStream) MatchCallback(com.infiniteautomation.mango.regex.MatchCallback) ShouldNeverHappenException(com.serotonin.ShouldNeverHappenException) SerialPortException(com.infiniteautomation.mango.io.serial.SerialPortException) IOException(java.io.IOException) TimeoutTask(com.serotonin.m2m2.util.timeout.TimeoutTask) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) DataPointRT(com.serotonin.m2m2.rt.dataImage.DataPointRT) PointValueTime(com.serotonin.m2m2.rt.dataImage.PointValueTime) SerialPointLocatorVO(com.infiniteautomation.serial.vo.SerialPointLocatorVO) TranslatableMessage(com.serotonin.m2m2.i18n.TranslatableMessage)

Example 7 with PointValueTime

use of com.serotonin.m2m2.rt.dataImage.PointValueTime in project ma-modules-public by infiniteautomation.

the class SerialDataSourceTest method testCustomPoint.

/**
 * TODO Break this into pieces to be re-usable
 */
@Test
public void testCustomPoint() {
    String message = "000005,Fri 11 January 2013 15:18:55,\u0002Q,244,000.03,1017.3,049.2,+021.4,+10.3,+040.50,+000.06,+000.04,0000.000,+11.6,00,\u000277\r\n";
    String[] expected = { "244", "000.03", "+000.06" };
    // Setup Data Source
    String dataSourceMessageRegex = "()[\\d\\D\\s\\S\\w\\W]*";
    int dataSourcePointIdentifierIndex = 1;
    boolean dataSourceUseTerminator = true;
    String dataSourceMessageTerminator = "\n";
    SerialDataSourceVO vo = SerialDataSourceTestData.getStandardDataSourceVO();
    vo.setMessageRegex(dataSourceMessageRegex);
    vo.setPointIdentifierIndex(dataSourcePointIdentifierIndex);
    vo.setUseTerminator(dataSourceUseTerminator);
    vo.setMessageTerminator(dataSourceMessageTerminator);
    SerialDataSourceRT rt = (SerialDataSourceRT) vo.createDataSourceRT();
    // Setup Data Point RTs
    // String pointIdentifier = "";
    // "([\\d\\D\\s\\S\\w\\W]*),[\\d\\D\\s\\S\\w\\W]*";
    String windDirectionRegex = "[\\d]*,[\\w\\s:]*,[\u0002\\w]*,([\\w]*),[\\d\\D\\s\\S\\w\\W]*";
    // "([\\d\\D\\s\\S\\w\\W]*),[\\d\\D\\s\\S\\w\\W]*";
    String windSpeedRegex = "[\\d]*,[\\w\\s:]*,[\u0002\\w]*,[\\w]*,([\\d\\.]*),[\\d\\D\\s\\S\\w\\W]*";
    // "([\\d\\D\\s\\S\\w\\W]*),[\\d\\D\\s\\S\\w\\W]*";
    String ip1Regex = "[\\d]*,[\\w\\s:]*,[\u0002\\w]*,[\\w]*,[\\d\\.]*,[\\d\\.]*,[\\d\\.]*,[\\d\\.+-]*,[\\d\\.+-]*,[\\d\\.+-]*,([\\d\\.+-]*),[\\d\\D\\s\\S\\w\\W]*";
    DataPointRT windDirection = SerialDataSourceTestData.getCustomPoint("windDirection", "windDirection", windDirectionRegex, 1, "", vo);
    rt.addDataPoint(windDirection);
    DataPointRT windSpeed = SerialDataSourceTestData.getCustomPoint("windSpeed", "windSpeed", windSpeedRegex, 1, "", vo);
    rt.addDataPoint(windSpeed);
    DataPointRT ip1 = SerialDataSourceTestData.getCustomPoint("ip1", "ip1", ip1Regex, 1, "", vo);
    rt.addDataPoint(ip1);
    // Connect
    try {
        assertTrue(rt.connect());
    } catch (Exception e) {
        e.printStackTrace();
        fail(e.getMessage());
    }
    vo.setMessageTerminator("\n");
    vo.setUseTerminator(true);
    // load a test input
    proxy.getTestInputStream().pushToMockStream(message);
    // Create an event to force the Data Source to read the port
    SerialPortProxyEvent evt = new SerialPortProxyEvent(System.currentTimeMillis());
    rt.serialEvent(evt);
    // test the return value(s), reverse list because Mango stores latest value at [0]
    List<PointValueTime> windSpeedValues = Lists.reverse(windSpeed.getLatestPointValues(1));
    List<PointValueTime> windDirectionValues = Lists.reverse(windDirection.getLatestPointValues(1));
    List<PointValueTime> ip1Values = Lists.reverse(ip1.getLatestPointValues(1));
    List<PointValueTime> received = new ArrayList<PointValueTime>();
    received.addAll(windSpeedValues);
    received.addAll(windDirectionValues);
    received.addAll(ip1Values);
    boolean found;
    for (int k = 0; k < expected.length; k += 1) {
        found = false;
        for (int i = 0; i < received.size(); i += 1) {
            if (expected[k].equals(received.get(i).getStringValue()))
                found = true;
        }
        if (!found)
            fail("No value match found for: '" + expected[k] + "' point value");
    }
}
Also used : SerialDataSourceVO(com.infiniteautomation.serial.vo.SerialDataSourceVO) DataPointRT(com.serotonin.m2m2.rt.dataImage.DataPointRT) PointValueTime(com.serotonin.m2m2.rt.dataImage.PointValueTime) ArrayList(java.util.ArrayList) SerialPortException(com.infiniteautomation.mango.io.serial.SerialPortException) SerialPortProxyEvent(com.infiniteautomation.mango.io.serial.SerialPortProxyEvent) Test(org.junit.Test)

Example 8 with PointValueTime

use of com.serotonin.m2m2.rt.dataImage.PointValueTime in project ma-modules-public by infiniteautomation.

the class ReportPointValueTimeSerializer method putBytes.

/* (non-Javadoc)
	 * @see com.serotonin.m2m2.db.dao.nosql.NoSQLDataSerializer#getBytes(com.serotonin.m2m2.db.dao.nosql.NoSQLDataEntry)
	 */
@Override
public void putBytes(ByteArrayBuilder b, ITime obj, long timestamp, String seriesId) {
    PointValueTime value = (PointValueTime) obj;
    // First put in the data type
    b.putShort((short) value.getValue().getDataType());
    // Second put in the data value
    switch(value.getValue().getDataType()) {
        case DataTypes.ALPHANUMERIC:
            b.putString(value.getStringValue());
            break;
        case DataTypes.BINARY:
            b.putBoolean(value.getBooleanValue());
            break;
        case DataTypes.IMAGE:
            ImageValue imageValue = (ImageValue) value.getValue();
            if (!imageValue.isSaved()) {
                throw new ImageSaveException(new IOException("Image not saved."));
            }
            b.putString(imageValue.getFilename());
            break;
        case DataTypes.MULTISTATE:
            b.putInt(value.getIntegerValue());
            break;
        case DataTypes.NUMERIC:
            b.putDouble(value.getDoubleValue());
            break;
        default:
            throw new ShouldNeverHappenException("Data type of " + value.getValue().getDataType() + " is not supported");
    }
    // Put in annotation
    if (value.isAnnotated()) {
        AnnotatedPointValueTime apv = (AnnotatedPointValueTime) value;
        b.putString(apv.getSourceMessage().serialize());
    } else
        b.putString(null);
}
Also used : AnnotatedPointValueTime(com.serotonin.m2m2.rt.dataImage.AnnotatedPointValueTime) PointValueTime(com.serotonin.m2m2.rt.dataImage.PointValueTime) ShouldNeverHappenException(com.serotonin.ShouldNeverHappenException) AnnotatedPointValueTime(com.serotonin.m2m2.rt.dataImage.AnnotatedPointValueTime) IOException(java.io.IOException) ImageSaveException(com.serotonin.m2m2.ImageSaveException) ImageValue(com.serotonin.m2m2.rt.dataImage.types.ImageValue)

Example 9 with PointValueTime

use of com.serotonin.m2m2.rt.dataImage.PointValueTime in project ma-modules-public by infiniteautomation.

the class ReportDao method runReportSQL.

/**
 * SQL Database Report
 * @param instance
 * @param points
 * @return
 */
public int runReportSQL(final ReportInstance instance, List<PointInfo> points) {
    PointValueDao pointValueDao = Common.databaseProxy.newPointValueDao();
    int count = 0;
    // The timestamp selection code is used multiple times for different tables
    String timestampSql;
    Object[] timestampParams;
    if (instance.isFromInception() && instance.isToNow()) {
        timestampSql = "";
        timestampParams = new Object[0];
    } else if (instance.isFromInception()) {
        timestampSql = "and ${field}<?";
        timestampParams = new Object[] { instance.getReportEndTime() };
    } else if (instance.isToNow()) {
        timestampSql = "and ${field}>=?";
        timestampParams = new Object[] { instance.getReportStartTime() };
    } else {
        timestampSql = "and ${field}>=? and ${field}<?";
        timestampParams = new Object[] { instance.getReportStartTime(), instance.getReportEndTime() };
    }
    // For each point.
    for (PointInfo pointInfo : points) {
        DataPointVO point = pointInfo.getPoint();
        int dataType = point.getPointLocator().getDataTypeId();
        DataValue startValue = null;
        if (!instance.isFromInception()) {
            // Get the value just before the start of the report
            PointValueTime pvt = pointValueDao.getPointValueBefore(point.getId(), instance.getReportStartTime());
            if (pvt != null)
                startValue = pvt.getValue();
            // Make sure the data types match
            if (DataTypes.getDataType(startValue) != dataType)
                startValue = null;
        }
        // Insert the reportInstancePoints record
        String name = Functions.truncate(point.getName(), 100);
        int reportPointId = doInsert(REPORT_INSTANCE_POINTS_INSERT, new Object[] { instance.getId(), point.getDeviceName(), name, pointInfo.getPoint().getXid(), dataType, DataTypes.valueToString(startValue), SerializationHelper.writeObject(point.getTextRenderer()), pointInfo.getColour(), pointInfo.getWeight(), boolToChar(pointInfo.isConsolidatedChart()), pointInfo.getPlotType() }, new int[] { Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.FLOAT, Types.CHAR, Types.INTEGER });
        // Insert the reportInstanceData records
        String insertSQL = // 
        "insert into reportInstanceData " + "  select id, " + reportPointId + // 
        ", pointValue, ts from pointValues " + // 
        "    where dataPointId=? and dataType=? " + StringUtils.replaceMacro(timestampSql, "field", "ts");
        count += ejt.update(insertSQL, appendParameters(timestampParams, point.getId(), dataType));
        // Insert the reportInstanceDataAnnotations records
        ejt.update(// 
        "insert into reportInstanceDataAnnotations " + // 
        "  (pointValueId, reportInstancePointId, textPointValueShort, textPointValueLong, sourceMessage) " + // 
        "  select rd.pointValueId, rd.reportInstancePointId, pva.textPointValueShort, " + // 
        "    pva.textPointValueLong, pva.sourceMessage " + // 
        "  from reportInstanceData rd " + // 
        "    join reportInstancePoints rp on rd.reportInstancePointId = rp.id " + // 
        "    join pointValueAnnotations pva on rd.pointValueId = pva.pointValueId " + "  where rp.id = ?", new Object[] { reportPointId });
        // Insert the reportInstanceEvents records for the point.
        if (instance.getIncludeEvents() != ReportVO.EVENTS_NONE) {
            String eventSQL = // 
            "insert into reportInstanceEvents " + // 
            "  (eventId, reportInstanceId, typeName, subtypeName, typeRef1, typeRef2, activeTs, " + // 
            "   rtnApplicable, rtnTs, rtnCause, alarmLevel, message, ackTs, ackUsername, " + // 
            "   alternateAckSource)" + "  select e.id, " + instance.getId() + // 
            ", e.typeName, e.subtypeName, e.typeRef1, " + // 
            "    e.typeRef2, e.activeTs, e.rtnApplicable, e.rtnTs, e.rtnCause, e.alarmLevel, " + // 
            "    e.message, e.ackTs, u.username, e.alternateAckSource " + // 
            "  from events e join userEvents ue on ue.eventId=e.id " + // 
            "    left join users u on e.ackUserId=u.id " + // 
            "  where ue.userId=? " + // 
            "    and e.typeName=? " + "    and e.typeRef1=? ";
            if (instance.getIncludeEvents() == ReportVO.EVENTS_ALARMS)
                eventSQL += "and e.alarmLevel > 0 ";
            eventSQL += StringUtils.replaceMacro(timestampSql, "field", "e.activeTs");
            ejt.update(eventSQL, appendParameters(timestampParams, instance.getUserId(), EventType.EventTypeNames.DATA_POINT, point.getId()));
        }
        // Insert the reportInstanceUserComments records for the point.
        if (instance.isIncludeUserComments()) {
            String commentSQL = // 
            "insert into reportInstanceUserComments " + // 
            "  (reportInstanceId, username, commentType, typeKey, ts, commentText)" + "  select " + instance.getId() + ", u.username, " + UserCommentVO.TYPE_POINT + // 
            ", " + reportPointId + // 
            ", uc.ts, uc.commentText " + // 
            "  from userComments uc " + // 
            "    left join users u on uc.userId=u.id " + "  where uc.commentType=" + // 
            UserCommentVO.TYPE_POINT + "    and uc.typeKey=? ";
            // Only include comments made in the duration of the report.
            commentSQL += StringUtils.replaceMacro(timestampSql, "field", "uc.ts");
            ejt.update(commentSQL, appendParameters(timestampParams, point.getId()));
        }
    }
    // Insert the reportInstanceUserComments records for the selected events
    if (instance.isIncludeUserComments()) {
        String commentSQL = // 
        "insert into reportInstanceUserComments " + // 
        "  (reportInstanceId, username, commentType, typeKey, ts, commentText)" + "  select " + instance.getId() + ", u.username, " + UserCommentVO.TYPE_EVENT + // 
        ", uc.typeKey, " + // 
        "    uc.ts, uc.commentText " + // 
        "  from userComments uc " + // 
        "    left join users u on uc.userId=u.id " + // 
        "    join reportInstanceEvents re on re.eventId=uc.typeKey " + "  where uc.commentType=" + // 
        UserCommentVO.TYPE_EVENT + "    and re.reportInstanceId=? ";
        ejt.update(commentSQL, new Object[] { instance.getId() });
    }
    // If the report had undefined start or end times, update them with values from the data.
    if (instance.isFromInception() || instance.isToNow()) {
        ejt.query(// 
        "select min(rd.ts), max(rd.ts) " + "from reportInstancePoints rp " + "  join reportInstanceData rd on rp.id=rd.reportInstancePointId " + "where rp.reportInstanceId=?", new Object[] { instance.getId() }, new RowCallbackHandler() {

            @Override
            public void processRow(ResultSet rs) throws SQLException {
                if (instance.isFromInception())
                    instance.setReportStartTime(rs.getLong(1));
                if (instance.isToNow())
                    instance.setReportEndTime(rs.getLong(2));
            }
        });
    }
    return count;
}
Also used : DataPointVO(com.serotonin.m2m2.vo.DataPointVO) DataValue(com.serotonin.m2m2.rt.dataImage.types.DataValue) ExportDataValue(com.serotonin.m2m2.vo.export.ExportDataValue) SQLException(java.sql.SQLException) ExportPointInfo(com.serotonin.m2m2.vo.export.ExportPointInfo) PointValueDao(com.serotonin.m2m2.db.dao.PointValueDao) IdPointValueTime(com.serotonin.m2m2.rt.dataImage.IdPointValueTime) AnnotatedPointValueTime(com.serotonin.m2m2.rt.dataImage.AnnotatedPointValueTime) PointValueTime(com.serotonin.m2m2.rt.dataImage.PointValueTime) ResultSet(java.sql.ResultSet) RowCallbackHandler(org.springframework.jdbc.core.RowCallbackHandler)

Example 10 with PointValueTime

use of com.serotonin.m2m2.rt.dataImage.PointValueTime in project ma-modules-public by infiniteautomation.

the class ReportDao method runReportNoSQL.

/**
 * Generate a report using the NoSQL DB for point value storage
 * @param instance
 * @param points
 * @return
 */
public int runReportNoSQL(final ReportInstance instance, List<PointInfo> points) {
    PointValueDao pointValueDao = Common.databaseProxy.newPointValueDao();
    final MappedCallbackCounter count = new MappedCallbackCounter();
    final NoSQLDao dao = Common.databaseProxy.getNoSQLProxy().createNoSQLDao(ReportPointValueTimeSerializer.get(), "reports");
    // The timestamp selection code is used multiple times for different tables
    long startTime, endTime;
    String timestampSql;
    Object[] timestampParams;
    if (instance.isFromInception() && instance.isToNow()) {
        timestampSql = "";
        timestampParams = new Object[0];
        startTime = 0l;
        endTime = Common.timer.currentTimeMillis();
    } else if (instance.isFromInception()) {
        timestampSql = "and ${field}<?";
        timestampParams = new Object[] { instance.getReportEndTime() };
        startTime = 0l;
        endTime = instance.getReportEndTime();
    } else if (instance.isToNow()) {
        timestampSql = "and ${field}>=?";
        timestampParams = new Object[] { instance.getReportStartTime() };
        startTime = instance.getReportStartTime();
        endTime = Common.timer.currentTimeMillis();
    } else {
        timestampSql = "and ${field}>=? and ${field}<?";
        timestampParams = new Object[] { instance.getReportStartTime(), instance.getReportEndTime() };
        startTime = instance.getReportStartTime();
        endTime = instance.getReportEndTime();
    }
    // For each point.
    List<Integer> pointIds = new ArrayList<Integer>();
    // Map the pointId to the Report PointId
    final Map<Integer, Integer> pointIdMap = new HashMap<Integer, Integer>();
    // the reports table/data store
    for (PointInfo pointInfo : points) {
        DataPointVO point = pointInfo.getPoint();
        pointIds.add(point.getId());
        int dataType = point.getPointLocator().getDataTypeId();
        DataValue startValue = null;
        if (!instance.isFromInception()) {
            // Get the value just before the start of the report
            PointValueTime pvt = pointValueDao.getPointValueBefore(point.getId(), instance.getReportStartTime());
            if (pvt != null)
                startValue = pvt.getValue();
            // Make sure the data types match
            if (DataTypes.getDataType(startValue) != dataType)
                startValue = null;
        }
        // Insert the reportInstancePoints record
        String name = Functions.truncate(point.getName(), 100);
        int reportPointId = doInsert(REPORT_INSTANCE_POINTS_INSERT, new Object[] { instance.getId(), point.getDeviceName(), name, pointInfo.getPoint().getXid(), dataType, DataTypes.valueToString(startValue), SerializationHelper.writeObject(point.getTextRenderer()), pointInfo.getColour(), pointInfo.getWeight(), boolToChar(pointInfo.isConsolidatedChart()), pointInfo.getPlotType() }, new int[] { Types.INTEGER, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.INTEGER, Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.FLOAT, Types.CHAR, Types.INTEGER });
        // Keep the info in the map
        pointIdMap.put(pointInfo.getPoint().getId(), reportPointId);
        // Insert the reportInstanceDataAnnotations records
        ejt.update(// 
        "insert into reportInstanceDataAnnotations " + // 
        "  (pointValueId, reportInstancePointId, textPointValueShort, textPointValueLong, sourceMessage) " + // 
        "  select rd.pointValueId, rd.reportInstancePointId, pva.textPointValueShort, " + // 
        "    pva.textPointValueLong, pva.sourceMessage " + // 
        "  from reportInstanceData rd " + // 
        "    join reportInstancePoints rp on rd.reportInstancePointId = rp.id " + // 
        "    join pointValueAnnotations pva on rd.pointValueId = pva.pointValueId " + "  where rp.id = ?", new Object[] { reportPointId });
        // Insert the reportInstanceEvents records for the point.
        if (instance.getIncludeEvents() != ReportVO.EVENTS_NONE) {
            String eventSQL = // 
            "insert into reportInstanceEvents " + // 
            "  (eventId, reportInstanceId, typeName, subtypeName, typeRef1, typeRef2, activeTs, " + // 
            "   rtnApplicable, rtnTs, rtnCause, alarmLevel, message, ackTs, ackUsername, " + // 
            "   alternateAckSource)" + "  select e.id, " + instance.getId() + // 
            ", e.typeName, e.subtypeName, e.typeRef1, " + // 
            "    e.typeRef2, e.activeTs, e.rtnApplicable, e.rtnTs, e.rtnCause, e.alarmLevel, " + // 
            "    e.message, e.ackTs, u.username, e.alternateAckSource " + // 
            "  from events e join userEvents ue on ue.eventId=e.id " + // 
            "    left join users u on e.ackUserId=u.id " + // 
            "  where ue.userId=? " + // 
            "    and e.typeName=? " + "    and e.typeRef1=? ";
            if (instance.getIncludeEvents() == ReportVO.EVENTS_ALARMS)
                eventSQL += "and e.alarmLevel > 0 ";
            eventSQL += StringUtils.replaceMacro(timestampSql, "field", "e.activeTs");
            ejt.update(eventSQL, appendParameters(timestampParams, instance.getUserId(), EventType.EventTypeNames.DATA_POINT, point.getId()));
        }
        // Insert the reportInstanceUserComments records for the point.
        if (instance.isIncludeUserComments()) {
            String commentSQL = // 
            "insert into reportInstanceUserComments " + // 
            "  (reportInstanceId, username, commentType, typeKey, ts, commentText)" + "  select " + instance.getId() + ", u.username, " + UserCommentVO.TYPE_POINT + // 
            ", " + reportPointId + // 
            ", uc.ts, uc.commentText " + // 
            "  from userComments uc " + // 
            "    left join users u on uc.userId=u.id " + "  where uc.commentType=" + // 
            UserCommentVO.TYPE_POINT + "    and uc.typeKey=? ";
            // Only include comments made in the duration of the report.
            commentSQL += StringUtils.replaceMacro(timestampSql, "field", "uc.ts");
            ejt.update(commentSQL, appendParameters(timestampParams, point.getId()));
        }
    }
    // end for all points
    // Insert the data into the NoSQL DB and track first/last times
    // The series name is reportInstanceId_reportPointId
    final AtomicLong firstPointTime = new AtomicLong(Long.MAX_VALUE);
    final AtomicLong lastPointTime = new AtomicLong(-1l);
    final String reportId = Integer.toString(instance.getId()) + "_";
    pointValueDao.getPointValuesBetween(pointIds, startTime, endTime, new MappedRowCallback<IdPointValueTime>() {

        @Override
        public void row(final IdPointValueTime ipvt, int rowId) {
            dao.storeData(reportId + Integer.toString(pointIdMap.get(ipvt.getId())), ipvt);
            count.increment();
            if (ipvt.getTime() < firstPointTime.get())
                firstPointTime.set(ipvt.getTime());
            if (ipvt.getTime() > lastPointTime.get())
                lastPointTime.set(ipvt.getTime());
        }
    });
    // Insert the reportInstanceUserComments records for the selected events
    if (instance.isIncludeUserComments()) {
        String commentSQL = // 
        "insert into reportInstanceUserComments " + // 
        "  (reportInstanceId, username, commentType, typeKey, ts, commentText)" + "  select " + instance.getId() + ", u.username, " + UserCommentVO.TYPE_EVENT + // 
        ", uc.typeKey, " + // 
        "    uc.ts, uc.commentText " + // 
        "  from userComments uc " + // 
        "    left join users u on uc.userId=u.id " + // 
        "    join reportInstanceEvents re on re.eventId=uc.typeKey " + "  where uc.commentType=" + // 
        UserCommentVO.TYPE_EVENT + "    and re.reportInstanceId=? ";
        ejt.update(commentSQL, new Object[] { instance.getId() });
    }
    // If the report had undefined start or end times, update them with values from the data.
    if (instance.isFromInception() || instance.isToNow()) {
        if (instance.isFromInception()) {
            if (firstPointTime.get() != Long.MAX_VALUE)
                instance.setReportStartTime(firstPointTime.get());
        }
        if (instance.isToNow()) {
            instance.setReportEndTime(lastPointTime.get());
        }
    }
    return count.getCount();
}
Also used : DataPointVO(com.serotonin.m2m2.vo.DataPointVO) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) DataValue(com.serotonin.m2m2.rt.dataImage.types.DataValue) ExportDataValue(com.serotonin.m2m2.vo.export.ExportDataValue) ArrayList(java.util.ArrayList) IdPointValueTime(com.serotonin.m2m2.rt.dataImage.IdPointValueTime) NoSQLDao(com.serotonin.m2m2.db.dao.nosql.NoSQLDao) ExportPointInfo(com.serotonin.m2m2.vo.export.ExportPointInfo) PointValueDao(com.serotonin.m2m2.db.dao.PointValueDao) AtomicLong(java.util.concurrent.atomic.AtomicLong) IdPointValueTime(com.serotonin.m2m2.rt.dataImage.IdPointValueTime) AnnotatedPointValueTime(com.serotonin.m2m2.rt.dataImage.AnnotatedPointValueTime) PointValueTime(com.serotonin.m2m2.rt.dataImage.PointValueTime)

Aggregations

PointValueTime (com.serotonin.m2m2.rt.dataImage.PointValueTime)104 ArrayList (java.util.ArrayList)33 DataPointVO (com.serotonin.m2m2.vo.DataPointVO)31 AnnotatedPointValueTime (com.serotonin.m2m2.rt.dataImage.AnnotatedPointValueTime)29 DataPointRT (com.serotonin.m2m2.rt.dataImage.DataPointRT)24 TranslatableMessage (com.serotonin.m2m2.i18n.TranslatableMessage)23 IdPointValueTime (com.serotonin.m2m2.rt.dataImage.IdPointValueTime)23 IOException (java.io.IOException)18 DataValue (com.serotonin.m2m2.rt.dataImage.types.DataValue)17 HashMap (java.util.HashMap)17 ShouldNeverHappenException (com.serotonin.ShouldNeverHappenException)15 ImageValue (com.serotonin.m2m2.rt.dataImage.types.ImageValue)12 PointValueFacade (com.serotonin.m2m2.rt.dataImage.PointValueFacade)11 ScriptException (javax.script.ScriptException)10 PointValueDao (com.serotonin.m2m2.db.dao.PointValueDao)9 IDataPointValueSource (com.serotonin.m2m2.rt.dataImage.IDataPointValueSource)9 LogStopWatch (com.serotonin.log.LogStopWatch)8 AlphanumericValue (com.serotonin.m2m2.rt.dataImage.types.AlphanumericValue)8 NumericValue (com.serotonin.m2m2.rt.dataImage.types.NumericValue)8 ResultTypeException (com.serotonin.m2m2.rt.script.ResultTypeException)8