Summary report engineHours calculation

Lucas Bastos4 years ago

Hello,

On this method, engineHours get calculated through the sum of the intervals between ignition: true or between the difference of hours attribute of the first and last position if it exists. Could both implementation result in different values for engineHours or it is not possible at all?

private static SummaryReport calculateSummaryResult(long deviceId, Date from, Date to) throws SQLException {
        SummaryReport result = new SummaryReport();
        result.setDeviceId(deviceId);
        result.setDeviceName(Context.getIdentityManager().getById(deviceId).getName());
        Collection<Position> positions = Context.getDataManager().getPositions(deviceId, from, to);
        if (positions != null && !positions.isEmpty()) {
            Position firstPosition = null;
            Position previousPosition = null;
            double speedSum = 0;
            boolean engineHoursEnabled = Context.getConfig().getBoolean("processing.engineHours.enable");
            for (Position position : positions) {
                if (firstPosition == null) {
                    firstPosition = position;
                }
                if (engineHoursEnabled && previousPosition != null
                        && position.getBoolean(Position.KEY_IGNITION)
                        && previousPosition.getBoolean(Position.KEY_IGNITION)) {
                    // Temporary fallback for old data, to be removed in May 2019
                    result.addEngineHours(position.getFixTime().getTime()
                            - previousPosition.getFixTime().getTime());
                }
                previousPosition = position;
                speedSum += position.getSpeed();
                result.setMaxSpeed(position.getSpeed());
            }
            boolean ignoreOdometer = Context.getDeviceManager()
                    .lookupAttributeBoolean(deviceId, "report.ignoreOdometer", false, false, true);
            result.setDistance(ReportUtils.calculateDistance(firstPosition, previousPosition, !ignoreOdometer));
            result.setAverageSpeed(speedSum / positions.size());
            result.setSpentFuel(ReportUtils.calculateFuel(firstPosition, previousPosition));

            if (engineHoursEnabled
                    && firstPosition.getAttributes().containsKey(Position.KEY_HOURS)
                    && previousPosition.getAttributes().containsKey(Position.KEY_HOURS)) {
                result.setEngineHours(
                        previousPosition.getLong(Position.KEY_HOURS) - firstPosition.getLong(Position.KEY_HOURS));
            }

            if (!ignoreOdometer
                    && firstPosition.getDouble(Position.KEY_ODOMETER) != 0
                    && previousPosition.getDouble(Position.KEY_ODOMETER) != 0) {
                result.setStartOdometer(firstPosition.getDouble(Position.KEY_ODOMETER));
                result.setEndOdometer(previousPosition.getDouble(Position.KEY_ODOMETER));
            } else {
                result.setStartOdometer(firstPosition.getDouble(Position.KEY_TOTAL_DISTANCE));
                result.setEndOdometer(previousPosition.getDouble(Position.KEY_TOTAL_DISTANCE));
            }

        }
        return result;
    }

Thanks!

Anton Tananaev4 years ago

Yes, it's possible if messages are not received from the device in the right order.

Lucas Bastos4 years ago

Even though on the query we order it by fixtime? Why don't we always calculate the engineHours through the interval of ignition: true?

Anton Tananaev4 years ago

It's slower.

Lucas Bastos4 years ago

Completely understood, one last question, for this use case it is really important to have a accurate measure, which value do you think is the most reliable? The one calculated through the sum of intervals or the one through the difference of hours attributes?

I asked it because I have reproduced this logic on a report application and wish to have the most reliable value

Thanks!

Anton Tananaev4 years ago

First one is more reliable.