All Downloads are FREE. Search and download functionalities are using the official Maven repository.

lrgs.lrgsmain.JavaLrgsStatusProvider Maven / Gradle / Ivy

Go to download

A collection of software for aggregatting and processing environmental data such as from NOAA GOES satellites.

The newest version!
/*
*  $Id$
*/
package lrgs.lrgsmain;

import java.net.InetAddress;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;

import ilex.util.Logger;

import lrgs.apistatus.AttachedProcess;
import lrgs.apistatus.DownLink;
import lrgs.apistatus.ArchiveStatistics;
import lrgs.apistatus.QualityMeasurement;
import lrgs.archive.QualLogFile;
import lrgs.archive.QualLogEntry;
import lrgs.archive.MergeFilter;
import lrgs.common.LrgsStatusProvider;
import lrgs.ddsserver.JLddsThread;
import lrgs.gui.LrgsApp;
import lrgs.ldds.LddsParams;
import lrgs.statusxml.LrgsStatusSnapshotExt;
import lrgs.dqm.DqmInterface;

/**
  Class JavaLrgsStatusProvider implements the LrgsStatusProvide interface
  by accessing java-only methods in the archive and downlinks.
*/
public class JavaLrgsStatusProvider
    implements LrgsStatusProvider
{
    /** Reference back to parent. */
    private LrgsMain lrgsMain;

    /** The status snapshot that everyone will work from. */
    private LrgsStatusSnapshotExt lsse;

    /** The last time a message was received. */
    private int lastMsgRcv;

    /** Used to maintain the quality log. */
    QualLogFile qualLogFile;

    /** Current minute's quality log entry. */
    QualLogEntry minuteQuality;

    /** Slot number for the DdsRecv main interface (set from LrgsMain) */
    public int ddsRecvMainSlotNum;

    /** Slot number for the DdsRecv main interface (set from LrgsMain) */
    public int ddsRecvSecMainSlotNum;

    /** Slot number for the DrgsRecv main interface (set from LrgsMain) */
    public int drgsRecvMainSlotNum;

    public int networkDcpMainSlotNum;

    /** Slot number for the NoaaportRecv main interface (set from LrgsMain) */
    public int noaaportRecvMainSlotNum;

    public Date lrgsStartupTime;

    /** Last hour we put dd info into. */
    private int lastDomsatDroppedHour = -1;

    /** The DQM Interface if one is active. */
    private DqmInterface dqmInterface;

    /** Last Domsat Sequence Number Seen */
    public int lastDomsatSequenceNum;

    public long qualLogLastModified = 0L;

    /**
     * Construct the provider and an internal status snapshot structure,
     * along with all the subordinate structures.
     * @param lrgsMain the parent.
     */
    public JavaLrgsStatusProvider(LrgsMain lrgsMain)
    {
        this.lrgsMain = lrgsMain;
        ddsRecvMainSlotNum = -1;
        drgsRecvMainSlotNum = -1;
        noaaportRecvMainSlotNum = -1;
        networkDcpMainSlotNum = -1;
        ddsRecvSecMainSlotNum=-1; // added for secondary group

        lsse = new LrgsStatusSnapshotExt();

        lsse.fullVersion = LrgsApp.AppVersion + " (" + LrgsApp.releasedOn + ")";

        LrgsConfig cfg = LrgsConfig.instance();
        lsse.setMaxDownlinks(cfg.maxDownlinks);
        lsse.setMaxClients(cfg.ddsMaxClients);
        lsse.isUsable = false;
        lsse.currentNumClients = 0;

        lsse.lss.lrgsTime = (int)(System.currentTimeMillis() / 1000L);
        lsse.lss.currentHour = (short)((lsse.lss.lrgsTime / 3600) % 24);
        lsse.lss.primaryMissingCount = 0;
        lsse.lss.totalRecoveredCount = 0;
        lsse.lss.totalGoodCount = 0;

        lsse.lss.downLinks = new DownLink[lsse.maxDownlinks];
        for(int i=0; i cfg.timeoutSeconds
         && !cfg.getNoTimeout())
        {
            if (lsse.isUsable)
            {
                lsse.isUsable = false;
                Logger.instance().failure(
                    LrgsMain.module + ":" + LrgsMain.EVT_TIMEOUT
                    + " LRGS Timeout: No data in "
                    + cfg.timeoutSeconds + " seconds.");
            }
            lsse.systemStatus = "Timeout";
        }
        else if (!lsse.isUsable)
        {
            Logger.instance().info(
                LrgsMain.module + ":" + (-LrgsMain.EVT_TIMEOUT)
                + " LRGS Recovery: Receiving Data Again!");
            lsse.isUsable = true;
            lsse.systemStatus = "Running";
        }

        syncDownlinks();

        lsse.currentNumClients = getAllClients(lsse.lss.attProcs);

        int hour = (lsse.lss.lrgsTime / 3600) % 24;
        if (hour != lsse.lss.currentHour)
        {
            // Starting a new hour, zero out the status structs.
            lsse.lss.currentHour = (short)hour;
            lsse.domsatDropped[hour] = 0;
            QualityMeasurement qm = lsse.lss.qualMeas[hour];
            qm.containsData = true;
            qm.numGood = 0;
            qm.numDropped = 0;
            qm.numRecovered = 0;

            for(int i=0; i= 0)
        {
            lsse.lss.arcStats.dirNext = idxNum+1;
        }
        DownLink dl = lsse.lss.downLinks[dl_slot];
        dl.lastMsgRecvTime = arcTime;

        int goodInc = (failcode == 'G') ? 1 : 0;
        int badInc  = (failcode == '?') ? 1 : 0;

        if (seqNum != -1)
        {
            lsse.lss.arcStats.lastSeqNum = seqNum;
            dl.lastSeqNum = seqNum;
        }

        // Update this slot's quality measurement for this hour.
        int hour = (arcTime / 3600) % 24;
        QualityMeasurement qm = lsse.downlinkQMs[dl_slot].dl_qual[hour];
        qm.containsData = true;
        qm.numGood += goodInc;
        qm.numDropped += badInc;

        // Update the 'archived' quality measurements for this hour.
        QualityMeasurement arcQM = lsse.lss.qualMeas[hour];
        arcQM.containsData = true;

        if (mergeResult == MergeFilter.SAVE_DCPMSG)
        {
            arcQM.numGood += goodInc;
            arcQM.numDropped += badInc;
            minuteQuality.archivedGood += goodInc;
            minuteQuality.archivedErr += badInc;
        }
        else if (mergeResult == MergeFilter.OVERWRITE_PREV_BAD)
        {
            // It could be a bad overwriting a bad, so use the incs:
            arcQM.numGood += goodInc;
            arcQM.numDropped += badInc;
            arcQM.numDropped--;
            minuteQuality.archivedGood++;
            minuteQuality.archivedErr--;
        }
        // Else no changes to archived stats: Either discarded or overwrote-good

        /*
          DDS and DRGS are composit downlinks that may have several connections.
          After tracking the individual slot quality, we also aggregate
          statistics in the parent slot.
        */
        if (dl.type == LrgsInputInterface.DL_DDSCON && dl.group.equalsIgnoreCase(LrgsInputInterface.PRIMARY))
        {
            dl = lsse.lss.downLinks[ddsRecvMainSlotNum];
            dl.lastMsgRecvTime = arcTime;
            QualityMeasurement mainQM =
                lsse.downlinkQMs[ddsRecvMainSlotNum].dl_qual[hour];
            mainQM.containsData = true;
            mainQM.numGood += goodInc;
            mainQM.numDropped += badInc;
            minuteQuality.ddsGood += goodInc;
            minuteQuality.ddsErr += badInc;
        }
        else if (dl.type == LrgsInputInterface.DL_DDSCON && dl.group.equalsIgnoreCase(LrgsInputInterface.SECONDARY))
        {
            dl = lsse.lss.downLinks[ddsRecvSecMainSlotNum];
            dl.lastMsgRecvTime = arcTime;
            QualityMeasurement mainQM =
                lsse.downlinkQMs[ddsRecvSecMainSlotNum].dl_qual[hour];
            mainQM.containsData = true;
            mainQM.numGood += goodInc;
            mainQM.numDropped += badInc;
            minuteQuality.ddsGood += goodInc;
            minuteQuality.ddsErr += badInc;
        }
        else if (dl.type == LrgsInputInterface.DL_DRGSCON)
        {
            dl = lsse.lss.downLinks[drgsRecvMainSlotNum];
            dl.lastMsgRecvTime = arcTime;
            QualityMeasurement mainQM =
                lsse.downlinkQMs[drgsRecvMainSlotNum].dl_qual[hour];
            mainQM.containsData = true;
            mainQM.numGood += goodInc;
            mainQM.numDropped += badInc;
            minuteQuality.drgsGood += goodInc;
            minuteQuality.drgsErr += badInc;
        }
        else if (dl.type == LrgsInputInterface.DL_NETDCPCONT
              || dl.type == LrgsInputInterface.DL_NETDCPPOLL)
        {
            dl = lsse.lss.downLinks[networkDcpMainSlotNum];
            dl.lastMsgRecvTime = arcTime;
            QualityMeasurement mainQM =
                lsse.downlinkQMs[networkDcpMainSlotNum].dl_qual[hour];
            mainQM.containsData = true;
            mainQM.numGood += goodInc;
            mainQM.numDropped += badInc;
            minuteQuality.drgsGood += goodInc;
            minuteQuality.drgsErr += badInc;
        }
        else if (dl.type == LrgsInputInterface.DL_DOMSAT)
        {
            minuteQuality.domsatGood += goodInc;
            minuteQuality.domsatErr += badInc;
            lastDomsatSequenceNum = seqNum;
        }
        else if (dl.type == LrgsInputInterface.DL_NOAAPORTCON)
        {
            dl = lsse.lss.downLinks[noaaportRecvMainSlotNum];
            dl.lastMsgRecvTime = arcTime;
            QualityMeasurement npQM =
                lsse.downlinkQMs[noaaportRecvMainSlotNum].dl_qual[hour];
            npQM.containsData = true;
            npQM.numGood += goodInc;
            npQM.numDropped += badInc;
            minuteQuality.noaaportGood += goodInc;
            minuteQuality.noaaportErr += badInc;
        }
        else if (dl.type == LrgsInputInterface.DL_LRIT)
        {
            minuteQuality.lritGood += goodInc;
            minuteQuality.lritErr += badInc;
        }
        else if (dl.type == LrgsInputInterface.DL_GR3110)
        {
            minuteQuality.gr3110Count += goodInc;
        }
        else if (dl.type == LrgsInputInterface.DL_IRIDIUM)
            minuteQuality.iridiumCount += goodInc;
        else if (dl.type == LrgsInputInterface.DL_EDL)
            minuteQuality.edlCount += goodInc;
    }

    /**
     * Called when a domsat dropout is detected.
     * @param numDropped the number of messages dropped.
     * @param arcTime the current time_t
     * @param gapStart the sequence number of the start of the gap.
     * @param elapsedSec the elapsed number of seconds in the gap.
     */
    public synchronized void domsatDropped(int numDropped, int arcTime,
        int gapStart, int elapsedSec)
    {
        int hour = (arcTime / 3600) % 24;
        if (hour != lastDomsatDroppedHour)
        {
            // Starting new hour? Zero it out first.
            lsse.domsatDropped[hour] = 0;
            lastDomsatDroppedHour = hour;
        }
        lsse.domsatDropped[hour] += numDropped;

        minuteQuality.domsatDropped += numDropped;

        /*
         * This is a hook for DAPS, which monitors quality on the DOMSAT
         * uplink. Most LRGS systems will not have a dqmInterface.
         */
        if (dqmInterface != null)
            dqmInterface.domsatDropped(gapStart, numDropped, elapsedSec);
    }


    public void setSystemStatus(String status)
    {
        lsse.systemStatus = status;
    }

    /**
     * Called when we get a new client connection.
     * @return AttachedProcess with which to track the client's status,
     *         or null if all client slots are used.
     */
    public AttachedProcess getFreeClientSlot()
    {
        for(int i=0; i< lsse.lss.attProcs.length; i++)
        {
            AttachedProcess ap = lsse.lss.attProcs[i];
            if (ap.pid == -1)
            {
                return ap;
            }
        }
        return null;
    }

    /**
     * @return ms time for the last time message was received over the
     * DDS link.
     */
    public long getLastDdsReceiveTime()
    {
        if (ddsRecvMainSlotNum == -1)
        {
            Logger.instance().debug1("StatusProvider.getLastDdsReceiveTime no " +
                "ddsRecvMainSlotNum, returning now - 1 hour");
            return System.currentTimeMillis() - 3600000L;
        }
        else
        {
            DownLink dl = lsse.lss.downLinks[ddsRecvMainSlotNum];
            Logger.instance().debug1("StatusProvider.getLastDdsReceiveTime "
                + "returning " + new Date(dl.lastMsgRecvTime * 1000L));
            return dl.lastMsgRecvTime * 1000L;
        }
    }

    /**
     * @return ms time for the last time message was received over the
     * DDS Secondary(Backup) link.
     */
    public long getLastSecDdsReceiveTime()
    {
        if (ddsRecvSecMainSlotNum == -1)
        {
            return System.currentTimeMillis() - 3600000L;
        }
        else
        {
            DownLink dl = lsse.lss.downLinks[ddsRecvSecMainSlotNum];
            return dl.lastMsgRecvTime * 1000L;
        }
    }


    /**
     * @return ms time for the last time message was received over any link.
     */
    public long getLastReceiveTime()
    {
        long latest = 0L;
        String latestName = "(unknown)";
        for(int slot = 0; slot latest)
                {
                    latest = t;
                    latestName = lsse.lss.downLinks[slot].name;
                }
            }
        }
        Logger.instance().info("At LRGS Startup, last msg was received at "
            + new Date(latest) + " on downlink " + latestName);
        return latest;
    }

    public boolean isUsable()
    {
        return lsse.isUsable;
    }

    public void setIsUsable(boolean tf) { lsse.isUsable = tf; }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy