Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Introduction

The embedded Fews PI service is a SOAP service hosted by a FEWS client instance (SA/OC/headless) ande uses XFire, a java SOAP framework. This framework allows a client application to obtain a proxy instance to the FewsPiService API hosted by a FEWS client. With this API the client can retrieve data from or write data to a FEWS client instance. Before a client application can access the FEWS system there is some configuration work that needs to be done.

...

Anchor
getClientConfigFile
getClientConfigFile

System info
Code Block

String getClientConfigFile(String clientId, String fileExtension);

...

  • clientId: File name of client configuration file located in the OC configuration directory 'PiClientConfigFiles'. This file is free format and content is only read by client application. Only requirement is that content is text based.
  • fileExtension: Extension of client file.
  • returns: Text file containing client configuration.
Code Block

Date getSystemTime(String clientId);

...

  • clientId: <id not required>
  • returns: Date field containing OC system time.
Code Block

long getLastUpdateTime();

...

  • returns: Long representation of time (modified Julian date).
Code Block

String getDisplayUnit(String parameterId);

...

  • returns: String holding the unit
Identifiers
Code Block

String getTimeZoneId(String clientId);

...

  • clientId: <id not required>
  • returns: String representation of time zone.
Code Block

String[] getSelectedFilterIds();

...

  • returns: String array holding the identifiers of the selected filters
Code Block

String[] getSelectedLocationIds();

...

  • returns: String array holding the identifiers of the selected locations
Code Block

String[] getSelectedParameters();

...

  • returns: String array holding the identifiers of the selected parameters
Code Block

String getActiveSegmentId();

...

  • returns: String identifier to active segement node
Code Block

String[] getColdStateIds(String clientId, String id);

...

Anchor
getAvailableStateTimes
getAvailableStateTimes

Code Block

Date[] getAvailableStateTimes(String clientId, String id);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a ModuleState element in the service configuration file.
  • returns: Available warm state times for requested ModuleState.
Code Block

int[] getEnsembleMemberIndices(String clientId, String ensembleId);

...

  • clientId: <id not required>
  • ensembleId: Id of requested ensemble.
  • returns: Available member indices of requested ensemble.
Content
Code Block

String getFilters(String piVersion);

...

  • piVersion: (Optional) Pi Version for the return file. Defaults to the latest PI version.
  • returns: String content of a Pi_Filters XML file containing Fews Filters.
Code Block

String getLocations(String clientId, String filterId, String piVersion);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD. If not
    provided then no id mapping will be done.
  • filterId: Filter Id. Can be retrieved using the String getFilters(String piVersion) method.
  • piVersion: (Optional) Pi Version for the return file. Defaults to the latest PI version.
  • returns: String content of a Pi_Locations XML file containing the locations available for passed filter id.
Code Block

String getParameters(String clientId, String filterId, String piVersion);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD. If not provided then no id mapping will be done.
  • filterId: Filter Id. Can be retrieved using the String getFilters(String piVersion) method.
  • piVersion: (Optional) Pi Version for the return file. Defaults to the latest PI version.
  • returns: String content of a Pi_TimeSeriesParameters XML file containing the parameters available for passed filter id.
Code Block

String getRatingCurves(String[] ratingCurveIds);

...

  • ratingCurveIds: String array with lcoation identifiers of the ratings
  • returns: Xml string in Pi_ratyingcurves format holding rating curves
Code Block

String getLogMessages(String clientId, String taskId)

...

  • clientId: <id not required but can not be null>
  • taskId: Task ID for which to retrieve log messages. Only messages for the last run are returned.
  • returns: String containing the log messages in the format defined by the PI Diag XSD
Code Block

byte[] getModuleDataSet(String clientId, String id, String ensembleId, int ensembleMemberIndex)

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a ModuleDataSet element in the service configuration file.
  • ensembleId: <currently not supported>
  • ensembleMemberIndex: <currently not supported>
  • returns: Binary content of the ModuleDataSet file for requested ModuleState.
Code Block

byte[] getModuleParameterSet(String clientId, String id, String ensembleId, int ensembleMemberIndex)

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a ModuleParameterSet element in the service configuration file.
  • ensembleId: <currently not supported>
  • ensembleMemberIndex: <currently not supported>
  • returns: String content of the ModuleParameterSet file for requested ModuleState.
Code Block

byte[] getModuleStateBinary(String clientId, String id, Date stateTime, String ensembleId, int ensembleMemberIndex);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a ModuleState element in the service configuration file.
  • stateTime: Time for which to retrieve warm state file. Time values can be obtained from method #getAvailableStateTimes
  • ensembleId: <currently not supported>
  • ensembleMemberIndex: <currently not supported>
Timeseries
Code Block

String getTimeSeriesHeaders(String clientId, String id, String taskId, Date startTime,
		Date timeZero, Date endTime, String[] parameterIds, String[] locationIds, String ensembleId, int ensembleMemberIndex,
		boolean thresholdsVisible);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a TimeSeries element in the service configuration file.
  • taskId: <id not required however can not be null>
  • startTime: Start date/time of run - Long.MAXVALUE if the configured default is to be used
  • timeZero: Forecast time zero.
  • endTime: End date/time of run - Long.MAXVALUE if the configured default is to be used
  • parameterIds: Subset of parameter IDs for which to retrieve timeseries.
  • locationIds: Subset of location IDs for which to retrieve timeseries.
  • ensembleId: Id of the ensemble, can be null.
  • ensembleMemberIndex Ensemble member index for this time series. (Only if configured)
  • thresholdsVisible: (Optional) Option to add threshold values in the header if set to TRUE. Default is FALSE
  • returns: String content of a PiTimeseries XML file only containing header information.
Code Block

String getTimeSeries(String clientId, String id, String taskId, Date startTime,
		Date timeZero, Date endTime, String[] parameterIds, String[] locationIds, String ensembleId, int ensembleMemberIndex,
		boolean thresholdsVisible);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a TimeSeries element in the service configuration file.
  • taskId: <id not required however can not be null>
  • startTime: Start date/time of run - Long.MAXVALUE if the configured default is to be used
  • timeZero: Forecast time zero.
  • endTime: End date/time of run - Long.MAXVALUE if the configured default is to be used
  • parameterIds: Subset of parmater IDs for which to retrieve timeseries.
  • locationIds: Subset of location IDs for which to retrieve timeseries.
  • ensembleId: Id of the ensemble, can be null.
  • ensembleMemberIndex Ensemble member index for this time series. (Only if configured)
  • thresholdsVisible: (Optional) Option to add threshold values in the header if set to TRUE. Default is FALSE
  • returns: String content of a PiTimeseries XML file.
Code Block

byte[] getTimeSeriesBytes(String clientId, String id, String taskId, Date startTime,
		Date timeZero, Date endTime,&nbsp;String[] parameterIds, String[] locationIds,
                String ensembleId, int ensembleMemberIndex);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Reference to the ID of a TimeSeries element in the service configuration file.
  • taskId: <id not required however can not be null>
  • startTime: Start date/time of run - Long.MAXVALUE if the configured default is to be used
  • timeZero: Forecast time zero.
  • endTime: End date/time of run - Long.MAXVALUE if the configured default is to be used
  • parameterIds: Subset of parameter IDs for which to retrieve timeseries.
  • locationIds: Subset of location IDs for which to retrieve timeseries.
  • ensembleId: Id of the ensemble, can be null.
  • ensembleMemberIndex Ensemble member index for this time series. (Only if configured)
  • returns: Content of the binary file that can be exported together with the PITimeseries XML files.
Code Block

String getTimeSeriesHeadersForFilter(String clientId, Date startTime, Date timeZero, Date endTime, String filterId, String[] locationIds, String[] parameterIds, boolean useDisplayUnits, String piVersion);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD. If not
    provided then no id mapping will be done.
  • startTime: Start date/time of run - Long.MAXVALUE if the configured default is to be used
  • timeZero: Forecast time zero.
  • endTime: End date/time of run - Long.MAXVALUE if the configured default is to be used
  • filterId: Filter Id. Can be retrieved using the String getFilters(String piVersion) method.
  • locationIds: Subset of location IDs for which to retrieve timeseries.
  • parameterIds: Subset of parameter IDs for which to retrieve timeseries.
  • useDisplayUnits: (Optional) Option to export values using display units (TRUE) instead of database units (FALSE).
  • piVersion: (Optional) Pi Version for the return file. Defaults to the latest PI version.
  • returns: String content of a Pi_Timeseries XML file only containing header information.
Code Block

String getTimeSeriesForFilter(String clientId, Date startTime, Date timeZero, Date endTime, String filterId, String[] locationIds, String[] parameterIds, boolean convertDatum, boolean useDisplayUnits, String piVersion);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD. If not
    provided then no id mapping will be done.
  • startTime: Start date/time of run - Long.MAXVALUE if the configured default is to be used
  • timeZero: Forecast time zero.
  • endTime: End date/time of run - Long.MAXVALUE if the configured default is to be used
  • filterId: Filter Id. Can be retrieved using the String getFilters(String piVersion) method.
  • locationIds: Subset of location IDs for which to retrieve timeseries.
  • parameterIds: Subset of parameter IDs for which to retrieve timeseries.
  • convertDatum: Option to convert values from relative to location height to absolute values (TRUE). If FALSE values remain relative.
  • useDisplayUnits: Option to export values using display units (TRUE) instead of database units (FALSE).
  • piVersion: (Optional) Pi Version for the return file. Defaults to the latest PI version.
  • returns: String content of a Pi_Timeseries XML file only containing header information.
Code Block

String getTimeSeriesForSegment(String segmentId, String clientId, Date timeZero, Date startTime, Date endTime, boolean thresholdsVisible);

...

Client datasets
Code Block

String[] getAllNodesWithDataset();

...

  • returns: Array of string identifiers of nodes
Code Block

String[] getAllDataSetsIdsForNode(String nodeId, String clientId);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • nodeId: Segment node identifier
  • returns: Array of string identifiers referring to client datasets
Code Block

String getDescription(String id, String clientId)

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Identifier of client dataset
  • returns: String description of dataset content
Code Block

byte[] getDataSet(String id, String clientId)

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Identifier of client dataset
  • returns: Byte content of the requested client dataset
Code Block

long getLastModificationTimeDataSets();

...

  • returns: Modifcation Time as Long (modified Julian date)

Setter methods

Code Block

void setSystemTime(Date systemTime);

...

  • systemTime: new SystemTime
Code Block

void putLogMessage(String clientId, String piDiagnosticsXmlContent);

...

  • clientId: <id only used as description>
  • piDiagnosticsXmlContent: String containing the log messages in the format defined by the PI Diag XSD
Code Block

void putModuleDataSet(String clientId, String taskId, String id, byte[] byteModuleDataSetContent,
               Date validityStartTime, Date validityEndTime, String ensembleId, int ensembleMemberIndex);

...

  • <not implemented>
Code Block

void putModuleParameterSet(String clientId, String id, String taskId, String piParameterSetXmlContent,
               Date validityStartTime, Date validityEndTime, String ensembleId, int ensembleMemberIndex);

...

  • <not implemented>
Code Block

void putState(String clientId, String taskId, String piStateXmlContent, String byteStateFileName,
                byte[] byteStateContent, String ensembleId, int ensembleMemberIndex);
  • <not implemented>
Code Block

void putTimeSeries(String clientId, String taskId, String id, String piTimeSeriesXmlContent,
                String ensembleId, int ensembleMemberIndex);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • taskId: <id not required>
  • id: Reference to the ID of a TimeSeries element in the service configuration file.
  • piTimeSeriesXmlContent: Time Series content in the form of a Pi timeseries xml file.
  • ensembleId: Id of the ensemble
  • ensembleMemberIndex: Ensemble member index for this time series. NULL if this is not an ensemble.
Code Block

void putTimeSeriesBinary(String clientId, String taskId, String id, String piTimeSeriesXmlContent,
                 byte[] byteTimeSeriesContent, String ensembleId, int ensembleMemberIndex);

...

  • clientId: File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • taskId: <id not required>
  • id: Reference to the ID of a TimeSeries element in the service configuration file.
  • piTimeSeriesXmlContent: Time Series content in the form of a Pi timeseries xml file.
  • byteTimeSeriesContent: TimeSeries data content in the form of a byte array.
  • ensembleId: Id of the ensemble
  • ensembleMemberIndex: Ensemble member index for this time series. NULL if this is not an ensemble.
Code Block

void putTimeSeriesForFilters(String clientId, String piTimeSeriesXmlContent, byte[] byteTimeSeriesContent, boolean convertDatum);

...

Anchor
createTask
createTask

Code Block

String createTask(String clientId);

...

Anchor
runTask
runTask

Code Block

String runTask(String clientId, String taskId, String workflowId, Date startTime, Date timeZero,
          Date endTime, String coldStateId, String scenarioId, String userId, String description);

...

  • clientId: <not required>
  • taskId: Id obtained by calling method #createTask
  • workflowId: Id of workflow to run by task.
  • startTime: <not required>
  • timeZero: <not required>
  • endTime: <not required>
  • coldStateId: <not implemented>
  • userId: Id of user running task.
  • scenarioId: Id of what-if scenario.
  • description: Description
  • returns: TaskRun id
Code Block

void cancelTask(String clientId, String taskId);

...

  • <not implemented>
Code Block

boolean waitForTask(String clientId, String taskId, int waitMillis);

...

Conversion methods

Code Block

float[] convertToDisplayUnitValue(String parameterId, float[] value);

...

  • parameterId: Parameter identifier, used to trace down the associated base unit as well as the display unit
  • value: array of values to be converted
  • returns: Array of converted values (floats)
Code Block

float []inverseConvertToDisplayUnitValue(String parameterId, float[] value);

...

  • parameterId: Parameter identifier, used to trace down the associated base unit as well as the display unit
  • value: array of values to be converted
  • returns: Array of converted values (floats)
Code Block

float[] convertStageToDischarge(float[] stages, String locationId, long time);

...

  • locationId: Identifier of the rating cruve location
  • time: time for which the rating curve should be valid
  • stages: array of stages to be converted to discharge
  • returns: array of values respresenting discharges
Code Block

float[] convertDischargeToStage(float[] discharges, String locationId, long time);

...

Data management methods for client data sets

Code Block

void saveDataSet(String id, String description, byte[] dataSet, String nodeId, String clientId);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Identifier of client data set
  • description: (Optional) description of the client dataset content
  • dataSet: Byte object holding the client dataset
  • nodeId: Segment/nodeId which is associated to this client dataset
Code Block

void updateDataSet(String id, String description, byte[] dataSet, String nodeId, String clientId);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Identifier of client data set
  • description: (Optional) description of the client dataset content
  • dataSet: Byte object holding the client dataset
  • nodeId: Segment/nodeId which is associated to this client dataset
Code Block

void deleteDataSet(String id, String clientId);

...

  • clientId: (Optional) File name of service configuration file located in the OC configuration directory 'PiServiceConfigFiles'. This file is an instance of the FewsPiServiceConfig XSD.
  • id: Identifier of client data set
Code Block

void uploadDataSets();

Initiates a database synchronization to upload the client data set to the Master Controller

...

The FEWS system does not automatically start up the PI service listener environment. This needs to be configured in the Explorer configuration file located in the directory 'SystemConfigFiles' of the region configuration. To do this the following line must be entered at the end of Explorer configuration file:

Code Block

<piServicePortRange start="8100" end="8100"/>

...

The backend FEWS PI Service can be started in Windows by installing a Windows service that can start and stop the FEWS PI Service. Unpack the following archive containing the service installation files: NT_FewsEnvironmentShell_Service_Install.zip. Open a DOS command prompt in the directory containing the unpacked archive. Run the install:

Code Block

install_service.bat <work dir> <region name>

# Where 'work dir' is the directory containing the BIN, JRE and REGION dirs
# and 'region name' is the directory name of the region for which to install the service

...

Or in Linux by using the Fews-piservice.sh file. This file should be placed in the same directory as the links to the JRE, BIN and the REGION dirs.

Code Block

# start the service
./fews_piservice.sh <REGION NAME> start

# stop the servie
./fews_piservice.sh <REGION NAME> stop

...

Before starting the client will require the following library: xfire-all-1.2.5.jar. This library can be found in the bin directory of the FEWS system.

Code Block

ObjectServiceFactory serviceFactory = new ObjectServiceFactory();
Service service = serviceFactory.create(FewsPiService.class);
XFireProxyFactory proxyFactory = new XFireProxyFactory();
 //port Number must be equal to the number configured in the Explorer.xml
int portNumber = 8100;
//localhost can be replaced by the ip address of the machine on which the FEWS system is running.
FewsPiService serviceProxy = (FewsPiService) proxyFactory.create(service, "http://localhost:" + portNumber + "/FewsPiService")

...

For the example fewspi.tcl file used refer to the attachment fewspi-C.tgz

Code Block

#include <stdio.h>
#include <tcl.h>

/* Define some helper variables and functions */

Tcl_Interp *interp;

int main( int argc, char *argv[] ) {

    /* Get the library started */

    if ( Init( argv[0] ) != TCL_OK ) {
        fprintf( stderr, "Sorry, initialisation failed: %s\n",
            Tcl_GetStringResult( interp ) );
    }

    /* Here insert calls to Pi Service */
    fprintf( stdout, "Locations: %s\n", getLocations( "id not required" ) );
    fprintf( stdout, "New task: %s\n", createTask( "id not required" ) );
}

void TearDown () {Tcl_Finalize();}

int EvalFile (char *fileName) {
    return Tcl_EvalFile(interp, fileName);
}

int Init (char *argv0) {
    char *pchar;
    char  buffer[1000];

    /* Initialise the library itself */

    Tcl_FindExecutable(argv0);
    interp = Tcl_CreateInterp();
    if (Tcl_Init(interp) != TCL_OK) {
        return TCL_ERROR;
    }

    /* Initialise the FEWS PI services */

    strcpy( buffer, argv0 );
    pchar = strrchr( buffer, '/' );
    if ( pchar == NULL ) {
        pchar = strrchr( buffer, '\\' );
    }
    if ( pchar == NULL ) {
        pchar = buffer;
    }
    strcpy( buffer, "fewspi.tcl" );

    return EvalFile( buffer );
}

...

Here follow some code examples of how to query the PI Service proxy from the client application. The configuration used to make these examples can be found in the attached Example Configuration.

Code Block

   /**
     * Test the retrieval of system time.
     * <p/>
     * With this test the system time of a running Fews Region (on port 8191) can be retrieved. If the
     * system time of the region is changed then the returned value here will match the change.
     */
    public void testSystemTime() {
        String clientId = "not required";
        Date date = serviceProxy.getSystemTime(clientId);


        System.out.println("Current System time : " + dateFormat.format(date));
    }

    /**
     * Return the warm state times from the data base for the configured moduleState id=RSNWELEV_DETO3I
     * in the service configuration file = TestConfig.
     */
    public void testGetWarmStateTimes() {
        //name of service config file
        String clientId = "TestConfig";
        //id of moduleState element
        String moduleId = "RSNWELEV_DETO3I";

        Date[] stateTimes = serviceProxy.getAvailableStateTimes(clientId, moduleId);

        System.out.println("State times for Module " + moduleId);
        for (Date stateTime : stateTimes) {
            System.out.println("time: " + dateFormat.format(stateTime));
        }
    }

    /**
     * Return the cold state ids from the data base for the configured moduleState id=RSNWELEV_DETO3I
     * in the service configuration file = TestConfig.
     */
    public void testGetColdStateIds() {
        //name of service config file
        String clientId = "TestConfig";
        //id of moduleState element
        String moduleId = "RSNWELEV_DETO3I";

        String[] stateIds = serviceProxy.getColdStateIds(clientId, moduleId);

        System.out.println("Cold state ids for model " + moduleId);
        for (String id : stateIds) {
            System.out.println("cold state: " + id);
        }
    }

    /**
     * Return the warm state file from the data base for the configured moduleState id=SNOW17_LSMO3U
     * in the service configuration file = TestConfig. Write file to location d:/temp/<moduleStateId>.zip
     */
    public void testGetModuleStateBinary() throws IOException {
        //name of service config file
        String clientId = "TestConfig";
        //id of moduleState element
        String moduleId = "SNOW17_LSMO3U";

        Date[] stateTimes = serviceProxy.getAvailableStateTimes(clientId, moduleId);
        byte[] binary = serviceProxy.getModuleStateBinary(clientId, moduleId, stateTimes[0], null, -1);

        ZipInputStream zipInputStream = new ZipInputStream(new ByteArrayInputStream(binary));
        try {
            ZipUtils.unzipFiles(zipInputStream, new File("d:/temp/" + moduleId + ".zip"));
        } finally {
            zipInputStream.close();
        }
    }

    /**
     * Returns the content of a client configuration file from the config directory PiClientConfigFiles.
     *
     * Only requirement is that a configuration file (any type) with the clientId as name and moduleId as extension
     * must exist in this config directory.
     */
    public void testGetClientConfigurationFile(){
        //Name of client file
        String clientId = "MyClientConfigFile";
        //extension of client file
        String moduleId = "txt";

        String clientText = serviceProxy.getClientConfigFile(clientId, moduleId);

        System.out.println("Client file content: " + clientText);

    }

    /**
     * Retrieve the content of the locations xml. Write this to d:/temp/locations.xml
     * @throws IOException
     */
    public void testGetLocations() throws IOException {

        String locations = serviceProxy.getLocations("id not required");

        System.out.println("Content of locations xml file: " + locations);
        FileUtils.writeText("d:/temp/locations.xml", IOUtils.UTF8_CHARSET, locations);

    }

    /**
     * Return the member indices for the ensemble id = "ESP" from the timeseries table.
     *
     * This only works when there are ensemble members in the TimeSeries table.
     */
    public void testGetEnsembleMemberIndices(){

        String ensembleId = "ESP";
        int[] indices = serviceProxy.getEnsembleMemberIndices("id not required", ensembleId);

        System.out.println("Ensemble id " + ensembleId + " contains " + indices.length + " members.");
        System.out.println("indices are: ");
        for (int indice : indices) {
            System.out.println(indice);
        }

    }

    /**
     * Get the logentries for an Import TaskId.
     *
     * Check the LogEntries table to find a matching taskId.
     *
     * @throws IOException
     */
    public void testGetLogInformation() throws IOException {

        String taskId = "NWSNWMC00:0000026"; //=import
        String logInfo = serviceProxy.getLogMessages("id not required", taskId);

        System.out.println("Content of log: " + logInfo);
        FileUtils.writeText("d:/temp/log.xml", IOUtils.UTF8_CHARSET, logInfo);

    }

    /**
     * Return the timeseries defined in the service configuration file under timeSeries element with id 'Reservoir'.
     *
     * Filter using parameter ids QIN and RQIN and location ids DETO3, GPRO3 and FOSO3
     *
     * Check timeseries table to look for existing times for these timeseries.
     *
     * @throws IOException
     */
    public void testGetTimeSeries() throws IOException {

        Date systemTime = serviceProxy.getSystemTime("id not required");
        Calendar instance = GregorianCalendar.getInstance(TimeZone.getTimeZone("GMT"));
        instance.set(2009, 4, 1);
        Date start = instance.getTime();
        instance.set(2009, 4, 11);
        Date end = instance.getTime();
        String[] params = new String[]{"QIN", "RQIN"};
        String[] locs = new String[]{"DETO3","GPRO3","FOSO3"};
        String headers = serviceProxy.getTimeSeriesHeaders("TestConfig", "Reservoir", null, start, systemTime, end, params, locs, null, -1);

        System.out.println("Content of tineseries headers: " + headers);

        String timeseriesfile = serviceProxy.getTimeSeries("TestConfig", "Reservoir", null, start, systemTime, end, params, locs, null, -1);

        FileUtils.writeText("d:/temp/timeseries.xml", IOUtils.UTF8_CHARSET, timeseriesfile);

    }

    /**
     * Upload a pi_diag log file to the region.
     *
     * Make sure to create an input file in corresponding directory.
     *
     * @throws IOException
     */
    public void testInsertLogMessages() throws IOException {

        String logText = FileUtils.readText("d:/temp/inputlog.xml");
        serviceProxy.putLogMessage("used as description", logText);
    }

    /**
     * Upload a pi_timeseries file to the Region. The timeseries in this file must be linked to timeseries configured
     * in the PiServiceConfig file.
     *
     * Make sure to create an input file in the corresponding directory.
     *
     * @throws IOException
     */
    public void testInsertTimeSeries() throws IOException {

        String timeseriesText = FileUtils.readText("d:/temp/inputtimeseries.xml");
        System.out.println("Input timeseries: " + timeseriesText);
        serviceProxy.putTimeSeries("TestConfig", null, "Reservoir", timeseriesText, null, -1);
    }

    /**
     * Schedule a task run and wait for it to finish.
     *
     */
    public void testRunningTask(){
        String taskId = serviceProxy.createTask("id not required");
        Date date = serviceProxy.getSystemTime("");
        System.out.println("Starting task with id " + taskId + " time=" + new Date(System.currentTimeMillis()));
        String taskRunId = serviceProxy.runTask("id not required", taskId, "Santiam_Forecast", date, date, date, null, null, "Test user", "PiWebservice taskrun");

        boolean result = serviceProxy.waitForTask("id not required", taskRunId, 120000);
        System.out.println("Task with id " + taskId + (result ? " finished successfully" : " failed"));
        System.out.println("time=" + new Date(System.currentTimeMillis()));
    }

...

Here follow some code examples of how to query the PI Service proxy from the client application. The configuration used to make these examples can be found in the attached Example Configuration.

Code Block

/* Fews PI services: wrapper functions */

char *getLocations( char *clientId ) {
    char buffer[1000];

    strcpy( buffer, "getLocations " );
    strcat( buffer, clientId );

    if ( Tcl_Eval( interp, buffer ) != TCL_OK )
{
        return NULL;
    } else {
        return Tcl_GetStringResult( interp ) ;
    }
}

char *createTask( char *clientId ) {
    Tcl_Obj *obj[2];

    obj[0] = Tcl_NewStringObj( "createTask", -1 );
    obj[1] = Tcl_NewStringObj( clientId, -1 );

    Tcl_IncrRefCount( obj[0] ) ;
    Tcl_IncrRefCount( obj[1] ) ;

    if ( Tcl_EvalObjv( interp, 2, obj, 0 ) != TCL_OK ) {
        return NULL;
    } else {

        Tcl_DecrRefCount( obj[0] ) ;
        Tcl_DecrRefCount( obj[1] ) ;
        return Tcl_GetStringResult( interp ) ;
    }
}

...

Example of the FewsPiService class. This class defines the API.

No Format

/* ================================================================
 * Delft FEWS
 * ================================================================
 *
 * Project Info:  http://www.wldelft.nl/soft/fews/index.html
 * Project Lead:  Karel Heynert (karel.heynert@wldelft.nl)
 *
 * (C) Copyright 2003, by WL | Delft Hydraulics
 *                        P.O. Box 177
 *                        2600 MH  Delft
 *                        The Netherlands
 *                        http://www.wldelft.nl
 *
 * DELFT-FEWS is a sophisticated collection of modules designed
 * for building a FEWS customised to the specific requirements
 * of individual agencies. An open modelling approach allows users
 * to add their own modules in an efficient way.
 *
 * ----------------------------------------------------------------
 * WebService.java
 * ----------------------------------------------------------------
 * (C) Copyright 2003, by WL | Delft Hydraulics
 *
 * Original Author:  Erik de Rooij
 * Contributor(s):
 *
 * Changes:
 * --------
 * 10-Sep-2007 : Version 1 ();
 *
 *
 */
package nl.wldelft.fews.system.pi;

import java.util.Date;

/**
 * TODO <code>ISSUES</code>
 *<li>Optional Date arguments can not be set to NULL when not used.</li>
 *<li> When retrieving timeseries. What use is it to add ensemble Id? Because the timeseries set already contains the ensemble id. </li>
 *<li> Some interface call do not require the clientId. Should we remove this to simplify things?</li>
 */
public interface FewsPiService {


    String getLocations(String clientId);
    /**
     * Retrieve the configuration file for the .

     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param fileExtension. Case insensitive. Extension of the config file (e.g. xml, ini), One client can have multiple config files
     * with different file extensions.
     * @return client config text file. Format of file must be known by client.
     */
    String getClientConfigFile(String clientId, String fileExtension);


    /**
     * Create a new Task. Use return Task id when exporting data to the WebService.

     * @param clientId Id of web service client (obtained on command line when invoked)
     * @return Task id for the new task.
     */
    String createTask(String clientId);

    /**
     * Return the current time zero of the system.
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @return Time zero
     */
    Date getSystemTime(String clientId);


    /**
     * TODO
     *
     * ID of Configured timezone for the webservice
     * @param clientId
     * @return
     */
    String getTimeZoneId(String clientId);

    /**
     * Run a Single task. TaskId must be obtained using the method {@link FewsPiService#createTask(String)}.
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId Task Id
     * @param workflowId Workflow Id
     * @param startTime start date/time of run - NULL if the configured default is to be used
     * @param timeZero Forecast time zero.
     * @param endTime end date/time of run - NULL if the configured default is to be used
     * @param coldStateId String identifying the cold state to use - NULL if a cold state start is not forced
     * @param scenarioId String identifying the "what if" scenario - NULL if not used
     * @param userId Id of user running task.
     * @param description Description
     * @return Returns the TaskRun id
     */
    String runTask(String clientId, String taskId, String workflowId, Date startTime, Date timeZero, Date endTime, String coldStateId, String scenarioId, String userId, String description);

	/**
	 * Request Ids of available cold states
	 *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param id Id of the State module instance for which to retrieve the cold state ids.
	 * @return List of available cold state groups
	 */
	String[] getColdStateIds(String clientId, String id);

    /**
     * Request run status of task. This can be used to wait for a task to complete
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId Task Id
     * @param waitMillis number of milli-seconds to wait between status requests
     * @return boolean if task is complete or has been cancelled
     */
    boolean waitForTask(String clientId, String taskId, int waitMillis);

    /**
     * cancel task. Cancel a running task
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId Task Id
     */
    void cancelTask(String clientId, String taskId);

    /**
     * Retrieve the indices for the given ensemble id.
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param ensembleId Id of the ensemble
     * @return All valid indices for this ensemble.
     */
    int[] getEnsembleMemberIndices(String clientId, String ensembleId);

    /**
     * Write timeseries associated to a specific task to webservice. The webservice will store this information in the database.
     *
     * If the time series is an ensemble then each ensemble member needs to be submitted individually.
     * using the <i>ensembleMemberIndex</i> argument. For deterministic time series the <i>ensembleMemberIndex</i> is NULL
     * Use {@link FewsPiService#getEnsembleMemberIndices(String, String)}
     * to obtain valid ensemble member index values.
     *
     * The TaskId may be NULL or the requested task id.
     * In case it is NULL the time series is written as data visible to all other processes in FEWS
     * In case it is TaskId the time series will be used only by the task run with TaskId (e.g. scenario time series)
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param id Id of the Pi timeseries xml content.
     * @param piTimeSeriesXmlContent  Time Series content in the form of a Pi timeseries xml file.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    void putTimeSeries(String clientId, String taskId, String id, String piTimeSeriesXmlContent, String ensembleId, int ensembleMemberIndex);

    /**
     * Write timeseries. The webservice will store this information in the database.
     *
     * <p>
     * For performance reasons it is possible to split the timeseries header information from the timeseries data. The header information
     * is stored in the <i>piTimeSeriesXmlContent</i> and the timeseries data is stored in the <i>byteTimeSeriesContent</i>.
     * <p>
     * If the time series is an ensemble then each ensemble member needs to be submitted individually.
     * using the <i>ensembleMemberIndex</i> argument. For deterministic time series the <i>ensembleMemberIndex</i> is NULL
     * Use {@link FewsPiService#getEnsembleMemberIndices(String, String)}
     * to obtain valid ensemble member index values.
     *
     * The TaskId may be NULL or the requested task id.
     * In case it is NULL the time series is written as data visible to all other processes in FEWS
     * In case it is TaskId the time series will be used only by the task run with TaskId (e.g. scenario time series)
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param id Id of the Pi timeseries xml content.
     * @param piTimeSeriesXmlContent  TimeSeries content in the form of a Pi timeseries xml file.
     * @param byteTimeSeriesContent  TimeSeries data content in the form of a byte array.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    void putTimeSeriesBinary(String clientId, String taskId, String id, String piTimeSeriesXmlContent, byte[] byteTimeSeriesContent, String ensembleId, int ensembleMemberIndex);

    /**
     * Write information about the parameter set file given the webservice.
     *
     * The TaskId may be NULL or the requested task id.
     * In case it is NULL the parameters version will be upaded
     * In case it is TaskId the parameters will be used only by the task run with TaskId (e.g. scenario run)
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param id Id of parameter set
     * @param piParameterSetXmlContent  Parameters content in the form of a Pi parameters xml file.
     * @param validityStartTime Start time of parameter validity (NULL if not applicable)
     * @param validityEndTime End time of parameter validity (NULL if not applicable)
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    void putModuleParameterSet(String clientId, String id, String taskId, String piParameterSetXmlContent, Date validityStartTime, Date validityEndTime, String ensembleId, int ensembleMemberIndex);

    /**
     * Write information about the dataset file for the given taskId back to the webservice. The webservice will store this information and will add it to the
     * task properties when the task is run.
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param id Id of Module DataSet file.
     * @param byteModuleDataSetContent Zipped module dataset file
     * @param validityStartTime Start time of dataset validity (NULL if not applicable)
     * @param validityEndTime End time of dataset validity (NULL if not applicable)
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    void putModuleDataSet(String clientId, String taskId, String id, byte[] byteModuleDataSetContent, Date validityStartTime, Date validityEndTime, String ensembleId, int ensembleMemberIndex);

    /**
     * Write state information to webservice. The webservice will store this information in the database.
     *
     * <p>
     * The state information consists of two seperate parts. The <i>piStateXmlContent</i> containing information
     * about the state files. And the <i>byteStateContent</i> containing the actual state data for the module.
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param piStateXmlContent  Pi state xml file.
     * @param byteStateFileName  name of the state file data content byte array.
     * @param byteStateContent  State file data content in the form of a byte array.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    void putState(String clientId, String taskId, String piStateXmlContent, String byteStateFileName, byte[] byteStateContent, String ensembleId, int ensembleMemberIndex);


    /**
     * Put a log message
     *
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param piDiagnosticsXmlContent Pi Diagnostics xml file.
     */
    void putLogMessage(String clientId, String piDiagnosticsXmlContent);

    /**
     * Read module dataset information from webservice.
     *
     * <p>
     *Default data set is returned.
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id Id of the module data set .
     * @return Module data set file as byte array.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    byte[] getModuleDataSet(String clientId, String id, String ensembleId, int ensembleMemberIndex);

    /**
     * Read module parameter set information from webservice.
     *
     * <p>
     *Default data parameterSet is returned.
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id name of the binary module parameter set file.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     * @return Module parameter set PiParameters xml.
     */
    String getModuleParameterSet(String clientId, String id, String ensembleId, int ensembleMemberIndex);


    /**
     * Read all available state times for requested state file.
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id Id of the module state .
     * @return All available state times for this module state file.
     */
    Date[] getAvailableStateTimes(String clientId, String id);


    /**
     * Read module state information from webservice.
     *
     * <p>
     *Module state data file is returned for given time. Use method {@link FewsPiService#getAvailableStateTimes(String, String)}
     * to retrieve the available state times.
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id Id of the state .
     * @param stateTime Time for which to retrieve a state file.
     * @return Module state data file as byte array.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. NULL if this is not an ensemble.
     */
    byte[] getModuleStateBinary(String clientId, String id, Date stateTime, String ensembleId, int ensembleMemberIndex);


    /**
     * Read the timeseries from the webservice. Returns a pi timeseries xml file containing the timeseries information.
     *
     * <p>
     * If the ensemble id has been configured for this timeseries then add the <i>ensembleMemberIndex</i> as argument. Use NULL if not an ensemble
     * Use {@link FewsPiService#getEnsembleMemberIndices(String, String)}
     * to obtain valid index values.
     *
     * The TaskId may be NULL or the requested task id.
	 * In case it is TaskId the time series is retrieved for the taskId only for simulated time series
	 * In case it is NULL time series for the current forecast will be retreived
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id Id of the time series string.
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param startTime start date/time of run - NULL if the configured default is to be used
     * @param timeZero Forecast time zero.
     * @param endTime end date/time of run - NULL if the configured default is to be used
     * @param parameterIds Subset of parmaters for which to retrieve timeseries.
     * @param locationIds Subset of locations for which to retrieve timeseries.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. (Only if configured)
     * @return  PiTimeseries xml file content.
     */
    String getTimeSeries(String clientId, String id, String taskId, Date startTime, Date timeZero, Date endTime, String[] parameterIds, String[] locationIds, String ensembleId, int ensembleMemberIndex);


    /**
     * Read the timeseries from the webservice. Returns a pi timeseries xml file
     * containing the timeseries headers information. Retrieve the timeseries data using the method
     * {@link FewsPiService#getTimeSeriesBytes(String, String, String, java.util.Date, java.util.Date, java.util.Date, String[], String[], String, int)}
     *
     * <p>
     * If the ensemble id has been configured for this timeseries then add the <i>ensembleMemberIndex</i> as argument. Otherwise
     * this argument is skipped by the webservice.
     * Use {@link FewsPiService#getEnsembleMemberIndices(String, String)}
     * to obtain valid index values.
     *
     * The TaskId may be NULL or the requested task id.
	 * In case it is TaskId the time series is retrieved for the taskId only for simulated time series
	 * In case it is NULL time series for the current forecast will be retreived
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id Id of the time series string.
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param startTime start date/time of run - NULL if the configured default is to be used
     * @param timeZero Forecast time zero.
     * @param endTime end date/time of run - NULL if the configured default is to be used
     * @param parameterIds Subset of parmaters for which to retrieve timeseries.
     * @param locationIds Subset of locations for which to retrieve timeseries.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. (Only if configured)
     * @return  PiTimeseries xml file content.
     */
    String getTimeSeriesHeaders(String clientId, String id, String taskId, Date startTime, Date timeZero, Date endTime, String[] parameterIds, String[] locationIds, String ensembleId, int ensembleMemberIndex);

    /**
     * Read the timeseries data from the webservice. Returns the data belonging to the
     * timeseries that are retrieved when the method  {@link FewsPiService#getTimeSeriesBytes(String, String, String, java.util.Date, java.util.Date, java.util.Date, String[], String[], String, int)}
     * is called using the same arguments.
     *
     * <p>
     * If the ensemble id has been configured for this timeseries then add the <i>ensembleMemberIndex</i> as argument. Otherwise
     * this argument is skipped by the webservice.
     * Use {@link FewsPiService#getEnsembleMemberIndices(String, String)}
     * to obtain valid index values.
     *
     * The TaskId may be NULL or the requested task id.
	 * In case it is TaskId the time series is retrieved for the taskId only for simulated time series
	 * In case it is NULL time series for the current forecast will be retreived
     *
     * @param clientId Id of webservice configuration that is to be queried
     * @param id Id of the time series string.
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @param startTime start date/time of run - NULL if the configured default is to be used
     * @param timeZero Forecast time zero.
     * @param endTime end date/time of run - NULL if the configured default is to be used
     * @param parameterIds Subset of parmaters for which to retrieve timeseries.
     * @param locationIds Subset of locations for which to retrieve timeseries.
     * @param ensembleId Id of the ensemble
     * @param ensembleMemberIndex Ensemble member index for this time series. (Only if configured)
     * @return  PiTimeseries xml file content.
     */
    byte[] getTimeSeriesBytes(String clientId, String id, String taskId, Date startTime, Date timeZero, Date endTime, String[] parameterIds, String[] locationIds, String ensembleId, int ensembleMemberIndex);

    /**
     * get a log message associated to a specified taskId
     * @param clientId Id of web service client (obtained on command line when invoked)
     * @param taskId  Task id. Obtained using method {@link FewsPiService#createTask(String)}
     * @return PiDiagnostics XML file content.
     */
    String getLogMessages(String clientId, String taskId);


}

...

To start Delft-FEWS in the background on Linux with no window present, use the following
receipe recipe:

  • Start the X virtual framebuffer server, Xvfb
  • Set the DISPLAY environment variable to point to that display
  • Start FEWS in the background

This way no window will be visible and no monitor will be needed. A small shell script
will take care of the details:

No Format

#
# Start the Xvfb server using screen "1" (to avoid issues with a possibly running X server)
Xvfb :1
#
# Set the DISPLAY environment variable so that FEWS will use the Xvfb server
#
export DISPLAY=:1.0
#
# Start FEWS (standalone or operator client) in the background
#
bin/fews.sh REGION