Skip to content

Creating a time series

Doug Schmidt edited this page Oct 31, 2018 · 3 revisions

Uses the Provisioning API to create a basic time-series.

createBasicTimeSeries()

The createBasicTimeSeries() method below will take a <Parameter>.<Label>@<Location> string identifier an create a basic time-series at the named location, using the named parameter and the given label.

Basic logic:

  • Use a regular expression to parse the identifier string into its parameter, label, and location string components
  • Get the matching location uniqueID from the Publish API
  • Get the default monitoring method code from the Provisioning API
  • Get the matching parameter DTO from the Provisioning API
  • Use the parameter's default unit and interpolation type when creating the time-series
  • Use a configurable default gap-tolerance when possible
  • Make the POST request on the Provisioning API to create the time-series
  • Return the unique ID of the created time-series.
  • Throw an exception if something goes wrong
import com.aquaticinformatics.aquarius.sdk.timeseries.AquariusClient;
import com.aquaticinformatics.aquarius.sdk.timeseries.servicemodels.Provisioning;
import com.aquaticinformatics.aquarius.sdk.timeseries.servicemodels.Provisioning.*;
import com.aquaticinformatics.aquarius.sdk.timeseries.servicemodels.Publish.*;
import net.servicestack.func.Func;

import java.time.Duration;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

private AquariusClient _client;

public String createBasicTimeSeries(String timeSeriesIdentifier) {

    Matcher matcher = IDENTIFIER_REGEX.matcher(timeSeriesIdentifier);

    if (!matcher.matches())
        throw new IllegalArgumentException("Can't parse '" + timeSeriesIdentifier + "' as time-series identifier. Expecting <Parameter>.<Label>@<Location");

    String locationIdentifier = matcher.group("location");
    String parameterIdentifier = matcher.group("parameter");
    String label = matcher.group("label");

    return createBasicTimeSeries(parameterIdentifier, label, locationIdentifier);
}

private static final Pattern IDENTIFIER_REGEX = Pattern.compile("^(?<parameter>[^.]+)\\.(?<label>[^@]+)@(?<location>.*)$");

private String createBasicTimeSeries(String parameterIdentifier, String label, String locationIdentifier) {

    String locationUniqueId = GetLocationUniqueId(locationIdentifier);
    Provisioning.MonitoringMethod defaultMonitoringMethod = GetDefaultMonitoringMethod();
    Parameter parameter = GetParameter(parameterIdentifier);

    PostBasicTimeSeries request = new PostBasicTimeSeries()
            .setGapTolerance(GapToleranceForInterpolationType(parameter.InterpolationType));

    // NOTE: The PostBasicTimeSeries request DTO is derived from TimeSeriesBase.
    // As a result, properties defined on the base class have setXXX() methods that return the base class, not the derived class.
    // This unfortunate Java limitation breaks a bit of the fluent nature of these methods.
    request
            .setLocationUniqueId(locationUniqueId)
            .setParameter(parameter.ParameterId)
            .setLabel(label)
            .setUnit(parameter.UnitIdentifier)
            .setInterpolationType(parameter.InterpolationType)
            .setMethod(defaultMonitoringMethod.MethodCode);

    return _client.Provisioning
            .post(request)
            .UniqueId;
}

private String GetLocationUniqueId(String locationIdentifier)
{
    return Func.first(
            _client.Publish
                .get(new LocationDescriptionListServiceRequest().setLocationIdentifier(locationIdentifier))
                .LocationDescriptions,
            l -> l.Identifier.equals(locationIdentifier))
    .UniqueId;
}

private Provisioning.MonitoringMethod GetDefaultMonitoringMethod()
{
    return Func.first(
            _client.Provisioning.get(new GetMonitoringMethods()).Results,
            m -> m.ParameterUniqueId.equals(EMPTY_GUID));
}

private final String EMPTY_GUID = "00000000000000000000000000000000";

private Parameter GetParameter(String parameterIdentifier)
{
    return Func.first(
            _client.Provisioning.get(new GetParameters()).Results,
            p -> p.Identifier.equals(parameterIdentifier));
}

private static Duration GapToleranceForInterpolationType(Provisioning.InterpolationType interpolationType)
{
    return _defaultGapToleranceMinutes < 1 || Func.first(InterpolationTypesWithNoGaps, i -> i == interpolationType) != null
            ? NoGaps
            : Duration.ofMinutes(_defaultGapToleranceMinutes);
}

private static int _defaultGapToleranceMinutes = 0; // TODO: change this as needed

private static final Duration NoGaps = Duration.ofSeconds(Long.MAX_VALUE);

private static final List<Provisioning.InterpolationType> InterpolationTypesWithNoGaps = java.util.Arrays.asList(new Provisioning.InterpolationType[]{
        Provisioning.InterpolationType.InstantaneousTotals,
        Provisioning.InterpolationType.DiscreteValues});

Creating a Reflected time-series instead of a Basic time-series

Use the same logic as above, except use the PostReflectedTimeSeries request DTO instead of the PostBasicTimeSeries request DTO.

Clone this wiki locally