TimeSeriesDslLoaderTest.java
/*
* Copyright (c) 2021, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.metrix.mapping;
import com.google.common.collect.ImmutableSet;
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.commons.io.table.TableFormatterConfig;
import com.powsybl.commons.test.TestUtil;
import com.powsybl.iidm.network.Network;
import com.powsybl.metrix.mapping.util.MappingTestNetwork;
import com.powsybl.timeseries.ReadOnlyTimeSeriesStore;
import com.powsybl.timeseries.ReadOnlyTimeSeriesStoreCache;
import com.powsybl.timeseries.RegularTimeSeriesIndex;
import com.powsybl.timeseries.StoredDoubleTimeSeries;
import com.powsybl.timeseries.StringTimeSeries;
import com.powsybl.timeseries.TimeSeries;
import com.powsybl.timeseries.TimeSeriesDataType;
import com.powsybl.timeseries.TimeSeriesIndex;
import com.powsybl.timeseries.TimeSeriesMetadata;
import com.powsybl.timeseries.UncompressedDoubleDataChunk;
import com.powsybl.timeseries.ast.IntegerNodeCalc;
import groovy.lang.MissingMethodException;
import org.junit.jupiter.api.Test;
import org.threeten.extra.Interval;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* @author Paul Bui-Quang {@literal <paul.buiquang at rte-france.com>}
*/
class TimeSeriesDslLoaderTest {
private final MappingParameters parameters = MappingParameters.load();
private final Network network = MappingTestNetwork.create();
private final FileSystem fileSystem = Jimfs.newFileSystem(Configuration.unix());
private final String tagScript = String.join(System.lineSeparator(),
"ts['one'] = 1",
"ts['test'] = %s",
"tag(ts['test'], 'calculatedTag', 'calculatedParam')",
"metadata_value = getMetadataTags(ts['test'])",
"println metadata_value"
);
private final String statScript = String.join(System.lineSeparator(),
"allVersions = %s",
"res_sum = sum(ts['test'], allVersions)",
"res_avg = avg(ts['test'], allVersions)",
"res_min = min(ts['test'], allVersions)",
"res_max = max(ts['test'], allVersions)",
"res_median = median(ts['test'], allVersions)",
"println res_sum",
"println res_avg",
"println res_min",
"println res_max",
"println res_median"
);
@Test
void mappingFileTest() throws URISyntaxException {
File mappingFile = new File(Objects.requireNonNull(getClass().getResource("/emptyScript.groovy")).toURI());
TimeSeriesMappingConfig config = new TimeSeriesDslLoader(mappingFile).load(network, parameters, new ReadOnlyTimeSeriesStoreCache(), new DataTableStore(), null);
assertTrue(config.getMappedTimeSeriesNames().isEmpty());
}
@Test
void mappingScriptTest() {
TimeSeriesMappingConfig config = new TimeSeriesDslLoader("").load(network, parameters, new ReadOnlyTimeSeriesStoreCache(), new DataTableStore(), null);
assertTrue(config.getMappedTimeSeriesNames().isEmpty());
}
@Test
void mappingReaderTest() throws IOException {
try (Reader reader = new InputStreamReader(Objects.requireNonNull(TimeSeriesDslLoaderTest.class.getResourceAsStream("/emptyScript.groovy")), StandardCharsets.UTF_8)) {
TimeSeriesMappingConfig config = new TimeSeriesDslLoader(reader).load(network, parameters, new ReadOnlyTimeSeriesStoreCache(), new DataTableStore(), null, null);
assertTrue(config.getMappedTimeSeriesNames().isEmpty());
}
}
@Test
void mappingPathTest() throws IOException {
Path mappingFile = fileSystem.getPath("/emptyScript.groovy");
try (Writer writer = Files.newBufferedWriter(mappingFile, StandardCharsets.UTF_8)) {
writer.write(String.join(System.lineSeparator(), ""));
}
TimeSeriesMappingConfig config = new TimeSeriesDslLoader(mappingFile).load(network, parameters, new ReadOnlyTimeSeriesStoreCache(), new DataTableStore(), null);
assertTrue(config.getMappedTimeSeriesNames().isEmpty());
}
@Test
void mappingTest() {
// mapping script
String script = String.join(System.lineSeparator(),
"mapPlannedOutages {",
" 'multiple_ouverture_id'",
"}",
"timeSeries['zero'] = 0",
"mapToGenerators {",
" timeSeriesName 'zero'",
"}",
"mapToGenerators {",
" timeSeriesName 'nucl_ts'",
" filter {",
" generator.energySource == NUCLEAR",
" }",
" distributionKey {",
" generator.maxP",
" }",
"}",
"mapToGenerators {",
" timeSeriesName 'hydro_ts'",
" filter {",
" generator.energySource == HYDRO",
" }",
"}",
"mapToLoads {",
" timeSeriesName 'load1_ts'",
" filter {",
" load.terminal.voltageLevel.id == 'VL1'",
" }",
"}",
"mapToLoads {",
" timeSeriesName 'load2_ts'",
" filter {",
" load.terminal.voltageLevel.id == 'VL2' && load.terminal.voltageLevel.substation.country == FR",
" }",
"}",
"mapToBreakers {",
" timeSeriesName 'switch_ts'",
" filter {",
" breaker.voltageLevel.id == 'VL1' && breaker.kind == com.powsybl.iidm.network.SwitchKind.BREAKER",
" }",
"}",
"mapToPhaseTapChangers {",
" timeSeriesName 'switch_ts'",
"}");
// create time series space mock
TimeSeriesIndex index = RegularTimeSeriesIndex.create(Interval.parse("2015-01-01T00:00:00Z/2015-07-20T00:00:00Z"), Duration.ofDays(200));
ReadOnlyTimeSeriesStoreCache store = new ReadOnlyTimeSeriesStoreCache(
TimeSeries.createDouble("nucl_ts", index, 1d, 1d),
TimeSeries.createDouble("hydro_ts", index, 1d, 1d),
TimeSeries.createDouble("load1_ts", index, 1d, 1d),
TimeSeries.createDouble("load2_ts", index, 1d, 1d),
TimeSeries.createDouble("switch_ts", index, 0d, 1d),
TimeSeries.createDouble("multiple_ouverture_id", index, 1d, 1d)
) {
@Override
public Optional<StringTimeSeries> getStringTimeSeries(String timeSeriesName, int version) {
return Optional.of(TimeSeries.createString("multiple_ouverture_id", index, "1", "G1,twt,L1"));
}
};
// load mapping script
TimeSeriesDslLoader dsl = new TimeSeriesDslLoader(script);
TimeSeriesMappingConfig config = dsl.load(network, parameters, store, new DataTableStore(), null);
TimeSeriesMappingConfigSynthesisCsvWriter csvWriter = new TimeSeriesMappingConfigSynthesisCsvWriter(config);
csvWriter.printMappingSynthesis(System.out, new TableFormatterConfig());
// Compare to the expected TimeSeriesMappingConfig
TimeSeriesMappingConfig expectedConfig = new TimeSeriesMappingConfig();
Map<MappingKey, List<String>> timeSeriesToGeneratorsMapping = new HashMap<>();
timeSeriesToGeneratorsMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "multiple_ouverture_id_G1"), List.of("G1"));
timeSeriesToGeneratorsMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "zero"), List.of("G4"));
timeSeriesToGeneratorsMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "nucl_ts"), List.of("G1", "G2"));
timeSeriesToGeneratorsMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "hydro_ts"), List.of("G3"));
expectedConfig.setTimeSeriesToGeneratorsMapping(timeSeriesToGeneratorsMapping);
Map<MappingKey, List<String>> timeSeriesToLoadsMapping = new HashMap<>();
timeSeriesToLoadsMapping.put(new MappingKey(EquipmentVariable.P0, "load1_ts"), List.of("LD1"));
timeSeriesToLoadsMapping.put(new MappingKey(EquipmentVariable.P0, "load2_ts"), List.of("LD2", "LD3"));
expectedConfig.setTimeSeriesToLoadsMapping(timeSeriesToLoadsMapping);
Map<MappingKey, List<String>> timeSeriesToPhaseTapChangersMapping = new HashMap<>();
timeSeriesToPhaseTapChangersMapping.put(new MappingKey(EquipmentVariable.PHASE_TAP_POSITION, "switch_ts"), List.of("twt"));
expectedConfig.setTimeSeriesToPhaseTapChangersMapping(timeSeriesToPhaseTapChangersMapping);
Map<MappingKey, List<String>> timeSeriesToBreakersMapping = new HashMap<>();
timeSeriesToBreakersMapping.put(new MappingKey(EquipmentVariable.OPEN, "switch_ts"), List.of("SW1", "SW2"));
expectedConfig.setTimeSeriesToBreakersMapping(timeSeriesToBreakersMapping);
Map<MappingKey, List<String>> timeSeriesToTransformersMapping = new HashMap<>();
timeSeriesToTransformersMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "multiple_ouverture_id_twt"), List.of("twt"));
expectedConfig.setTimeSeriesToTransformersMapping(timeSeriesToTransformersMapping);
Map<MappingKey, List<String>> timeSeriesToLinesMapping = new HashMap<>();
timeSeriesToLinesMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "multiple_ouverture_id_L1"), List.of("L1"));
expectedConfig.setTimeSeriesToLinesMapping(timeSeriesToLinesMapping);
Map<MappingKey, List<String>> generatorToTimeSeriesMapping = new HashMap<>();
generatorToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "G1"), List.of("multiple_ouverture_id_G1"));
generatorToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G1"), List.of("nucl_ts", "zero"));
generatorToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G2"), List.of("nucl_ts", "zero"));
generatorToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G3"), List.of("hydro_ts", "zero"));
generatorToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G4"), List.of("zero"));
expectedConfig.setGeneratorToTimeSeriesMapping(generatorToTimeSeriesMapping);
Map<MappingKey, List<String>> loadToTimeSeriesMapping = new HashMap<>();
loadToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.P0, "LD1"), List.of("load1_ts"));
loadToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.P0, "LD2"), List.of("load2_ts"));
loadToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.P0, "LD3"), List.of("load2_ts"));
expectedConfig.setLoadToTimeSeriesMapping(loadToTimeSeriesMapping);
Map<MappingKey, List<String>> phaseTapChangerToTimeSeriesMapping = new HashMap<>();
phaseTapChangerToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.PHASE_TAP_POSITION, "twt"), List.of("switch_ts"));
expectedConfig.setPhaseTapChangerToTimeSeriesMapping(phaseTapChangerToTimeSeriesMapping);
Map<MappingKey, List<String>> breakerToTimeSeriesMapping = new HashMap<>();
breakerToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.OPEN, "SW1"), List.of("switch_ts"));
breakerToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.OPEN, "SW2"), List.of("switch_ts"));
expectedConfig.setBreakerToTimeSeriesMapping(breakerToTimeSeriesMapping);
Map<MappingKey, List<String>> transformerToTimeSeriesMapping = new HashMap<>();
transformerToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "twt"), List.of("multiple_ouverture_id_twt"));
expectedConfig.setTransformerToTimeSeriesMapping(transformerToTimeSeriesMapping);
Map<MappingKey, List<String>> lineToTimeSeriesMapping = new HashMap<>();
lineToTimeSeriesMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "L1"), List.of("multiple_ouverture_id_L1"));
expectedConfig.setLineToTimeSeriesMapping(lineToTimeSeriesMapping);
Set<String> generatorSet = ImmutableSet.of("G1", "G2", "G3", "G4");
expectedConfig.setUnmappedMinPGenerators(generatorSet);
expectedConfig.setUnmappedMaxPGenerators(generatorSet);
Map<String, Set<String>> timeSeriesToPlannedOutagesMappingExpected = Map.of("multiple_ouverture_id", Set.of("1", "G1", "twt", "L1"));
expectedConfig.setTimeSeriesToPlannedOutagesMapping(timeSeriesToPlannedOutagesMappingExpected);
expectedConfig.setTimeSeriesNodes(Map.of("zero", new IntegerNodeCalc(0)));
expectedConfig.setMappedTimeSeriesNames(Set.of("zero", "nucl_ts", "hydro_ts", "load1_ts", "load2_ts", "switch_ts", "multiple_ouverture_id_G1", "multiple_ouverture_id_L1", "multiple_ouverture_id_twt"));
DistributionKey distributionKey = new NumberDistributionKey(1.0);
Map<MappingKey, DistributionKey> distributionKeyMapping = new HashMap<>();
distributionKeyMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "twt"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "G1"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.DISCONNECTED, "L1"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.OPEN, "SW1"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.OPEN, "SW2"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G1"), new NumberDistributionKey(1000.0));
distributionKeyMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G2"), new NumberDistributionKey(500.0));
distributionKeyMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G3"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.TARGET_P, "G4"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.P0, "LD1"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.P0, "LD2"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.P0, "LD3"), distributionKey);
distributionKeyMapping.put(new MappingKey(EquipmentVariable.PHASE_TAP_POSITION, "twt"), distributionKey);
expectedConfig.setDistributionKeys(distributionKeyMapping);
assertEquals(expectedConfig, config);
}
@Test
void loadMappingErrorTest() {
// mapping script
String script = String.join(System.lineSeparator(),
"timeSeries['zero'] = 0",
"mapToLoads {",
" timeSeriesName 'zero'",
" filter {",
" load.id == 'LD1'",
" }",
" variable p0",
"}",
"mapToLoads {",
" timeSeriesName 'zero'",
" filter {",
" load.id == 'LD1'",
" }",
" variable fixedActivePower",
"}"
);
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache();
// load mapping script
TimeSeriesDslLoader dsl = new TimeSeriesDslLoader(script);
DataTableStore dataTableStore = new DataTableStore();
TimeSeriesMappingException exception = assertThrows(TimeSeriesMappingException.class, () -> dsl.load(network, parameters, store, dataTableStore, null));
assertEquals("Load 'LD1' is mapped on p0 and on one of the detailed variables (fixedActivePower/variableActivePower)", exception.getMessage());
}
@Test
void switchMappingErrorTest() {
// mapping script
String script = String.join(System.lineSeparator(),
"timeSeries['zero'] = 0",
"mapToBreakers {",
" timeSeriesName 'zero'",
" filter {",
" breaker.id == 'SW1'",
" }",
" distributionKey p0",
"}"
);
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache();
// load mapping script
TimeSeriesDslLoader dsl = new TimeSeriesDslLoader(script);
DataTableStore dataTableStore = new DataTableStore();
assertThrows(MissingMethodException.class, () -> dsl.load(network, parameters, store, dataTableStore, null));
}
@Test
void tsStatsFunctions() throws IOException {
final String expectedWithAllVersions = "1.0\n0.2\n-5.0\n3.0\n1.0\n";
final String expectedWithoutAllVersions = "6.0\n2.0\n1.0\n3.0\n2.0\n";
TimeSeriesIndex index = RegularTimeSeriesIndex.create(Interval.parse("2015-01-01T00:00:00Z/2015-07-20T00:00:00Z"), Duration.ofDays(50));
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache(
TimeSeries.createDouble("test", index, 1d, 2d, 3d, -5d, 0d)
);
TimeSeriesDslLoader dslWithoutAllVersions = new TimeSeriesDslLoader(String.format(statScript, false));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
dslWithoutAllVersions.load(network, parameters, store, new DataTableStore(), out, null);
}
String output = TestUtil.normalizeLineSeparator(outputStream.toString());
assertEquals(expectedWithAllVersions, output);
outputStream.reset();
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
dslWithoutAllVersions.load(network, parameters, store, new DataTableStore(), out, new ComputationRange(Collections.singleton(1), 0, 3));
}
output = TestUtil.normalizeLineSeparator(outputStream.toString());
assertEquals(expectedWithoutAllVersions, output);
TimeSeriesDslLoader dslWithAllVersions = new TimeSeriesDslLoader(String.format(statScript, true));
outputStream.reset();
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
dslWithAllVersions.load(network, parameters, store, new DataTableStore(), out, new ComputationRange(Collections.singleton(1), 0, 3));
}
output = TestUtil.normalizeLineSeparator(outputStream.toString());
assertEquals(expectedWithAllVersions, output);
}
@Test
void testParameters() {
// mapping script
String script = String.join(System.lineSeparator(),
"parameters {",
" toleranceThreshold 0.5",
" withTimeSeriesStats true",
"}"
);
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache();
// load mapping script
TimeSeriesDslLoader dsl = new TimeSeriesDslLoader(script);
dsl.load(network, parameters, store, new DataTableStore(), null);
assertEquals(0.5f, parameters.getToleranceThreshold(), 0f);
assertTrue(parameters.getWithTimeSeriesStats());
}
@Test
void writeLogTest() throws IOException {
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache();
String script = "writeLog(\"LOG_TYPE\", \"LOG_SECTION\", \"LOG_MESSAGE\")";
TimeSeriesDslLoader dsl = new TimeSeriesDslLoader(script);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
dsl.load(network, parameters, store, new DataTableStore(), out, null);
}
String output = outputStream.toString();
String expectedMessage = "LOG_TYPE;LOG_SECTION;LOG_MESSAGE" + System.lineSeparator();
assertEquals(expectedMessage, output);
}
@Test
void metadataTest() throws IOException {
// mapping script
String script = String.join(System.lineSeparator(),
"ts['one'] = 1",
"metadata_ts = getMetadataTags(ts['test'])",
"metadata_int = getMetadataTags(ts['one'])",
"string_metadatas = stringMetadatas()",
"double_metadatas = doubleMetadatas()",
"int_metadatas = intMetadatas()",
"boolean_metadatas = booleanMetadatas()",
"println metadata_ts",
"println metadata_int",
"println string_metadatas",
"println double_metadatas",
"println int_metadatas",
"println boolean_metadatas"
);
TimeSeriesIndex index = RegularTimeSeriesIndex.create(Interval.parse("2015-01-01T00:00:00Z/2015-07-20T00:00:00Z"), Duration.ofDays(50));
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache(
new StoredDoubleTimeSeries(
new TimeSeriesMetadata("test", TimeSeriesDataType.DOUBLE, Map.of("tag", "value"), index),
new UncompressedDoubleDataChunk(0, new double[]{1d})));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
new TimeSeriesDslLoader(script).load(network, parameters, store, new DataTableStore(), out, null);
}
String output = TestUtil.normalizeLineSeparator(outputStream.toString());
assertEquals("[tag:value]\n[:]\n[:]\n[:]\n[:]\n[:]\n", output);
}
void simpleCalculatedTagTest(String expression) throws IOException {
tagTest(String.format(tagScript, expression), "[calculatedTag:calculatedParam]");
}
void tagTest(String script, String expectedTag) throws IOException {
TimeSeriesIndex index = RegularTimeSeriesIndex.create(Interval.parse("2015-01-01T00:00:00Z/2015-07-20T00:00:00Z"), Duration.ofDays(50));
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache(
new StoredDoubleTimeSeries(
new TimeSeriesMetadata("test", TimeSeriesDataType.DOUBLE, Map.of("storedTag", "storedParam"), index),
new UncompressedDoubleDataChunk(0, new double[]{1d})));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
new TimeSeriesDslLoader(script).load(network, parameters, store, new DataTableStore(), out, null);
}
String output = TestUtil.normalizeLineSeparator(outputStream.toString());
assertEquals(TestUtil.normalizeLineSeparator(expectedTag + "\n"), output);
}
@Test
void simpleCalculatedTagTest() throws IOException {
// IntegerNodeCalc
simpleCalculatedTagTest("new Integer(1)");
// FloatNodeCalc
simpleCalculatedTagTest("new Float(0.1)");
// DoubleNodeCalc
simpleCalculatedTagTest("new Double(0.1)");
// BigDecimal
simpleCalculatedTagTest("new BigDecimal(0.1)");
// BinaryOperation
simpleCalculatedTagTest("ts['test'] + 1");
// UnaryOperation
simpleCalculatedTagTest("- ts['test']");
// MinNodeCalc
simpleCalculatedTagTest("ts['one'].min(1)");
// MaxNodeCalc
simpleCalculatedTagTest("ts['one'].max(1)");
// TimeNodeCalc
simpleCalculatedTagTest("ts['one'].time()");
}
@Test
void storedTagTest() throws IOException {
String script = String.join(System.lineSeparator(),
"metadata_test = getMetadataTags(ts['test'])",
"println metadata_test",
"ts['test'] = ts['test']",
"metadata_test = getMetadataTags(ts['test'])",
"println metadata_test",
"tag(ts['test'], 'calculatedTag', 'calculatedParam')",
"metadata_test = getMetadataTags(ts['test'])",
"println metadata_test"
);
tagTest(script, "[storedTag:storedParam]\n[storedTag:storedParam]\n[calculatedTag:calculatedParam, storedTag:storedParam]");
}
@Test
void calculatedTimeSeriesTagTest() throws IOException {
// mapping script
String script = String.join(System.lineSeparator(),
"ts['calculated'] = ts['test']",
"ts['calculated_same_as_previous_one'] = ts['test']",
"tag(ts['calculated'], 'tag', 'param')",
"tag(ts['calculated_same_as_previous_one'], 'tag_same_as_previous_one', 'param_same_as_previous_one')",
"metadata_calculated = getMetadataTags(ts['calculated'])",
"metadata_calculated_same_as_previous_one = getMetadataTags(ts['calculated_same_as_previous_one'])",
"println metadata_calculated",
"println metadata_calculated_same_as_previous_one"
);
tagTest(script, "[tag:param, storedTag:storedParam]\n[tag_same_as_previous_one:param_same_as_previous_one, storedTag:storedParam]");
}
@Test
void tagOnAbsentTimeSeries() throws IOException {
String expression = "new Integer(1)";
String tagScriptError = String.join(System.lineSeparator(),
"ts['one'] = 1",
"ts['test'] = %s"
);
Map<String, String> newInsideTags = new HashMap<>();
newInsideTags.put("testTag", "testParam");
Map<String, Map<String, String>> newTags = new HashMap<>();
newTags.put("test", newInsideTags);
// mapping script
String script = String.format(tagScriptError, expression);
TimeSeriesIndex index = RegularTimeSeriesIndex.create(Interval.parse("2015-01-01T00:00:00Z/2015-07-20T00:00:00Z"), Duration.ofDays(50));
ReadOnlyTimeSeriesStore store = new ReadOnlyTimeSeriesStoreCache(
new StoredDoubleTimeSeries(
new TimeSeriesMetadata("test", TimeSeriesDataType.DOUBLE, Map.of("storedTag", "storedParam"), index),
new UncompressedDoubleDataChunk(0, new double[]{1d})));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
TimeSeriesMappingConfig timeSeriesMappingConfig;
Map<String, Map<String, String>> tags;
try (Writer out = new BufferedWriter(new OutputStreamWriter(outputStream))) {
timeSeriesMappingConfig = new TimeSeriesDslLoader(script).load(network, parameters, store, new DataTableStore(), out, null);
timeSeriesMappingConfig.setTimeSeriesNodeTags(newTags);
timeSeriesMappingConfig.addTag("testError", "calculatedTagError", "calculatedParamError");
tags = timeSeriesMappingConfig.getTimeSeriesNodeTags();
}
assertTrue(tags.containsKey("test"));
assertTrue(tags.get("test").containsKey("testTag"));
assertEquals("testParam", tags.get("test").get("testTag"));
assertFalse(tags.containsKey("testError"));
assertFalse(tags.get("test").containsKey("calculatedTagError"));
}
}