diff --git a/src/iidm/converter/xml/TerminalRefXml.cpp b/src/iidm/converter/xml/TerminalRefXml.cpp index c8777a17..3a7ecad2 100644 --- a/src/iidm/converter/xml/TerminalRefXml.cpp +++ b/src/iidm/converter/xml/TerminalRefXml.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -18,6 +19,7 @@ #include #include #include +#include #include namespace powsybl { @@ -57,6 +59,11 @@ void TerminalRefXml::writeTerminalRef(const Terminal& terminal, NetworkXmlWriter if (!context.getFilter().test(c)) { throw PowsyblException(stdcxx::format("Oups, terminal ref point to a filtered equipment %1%", c.get().getId())); } + if (terminal.getVoltageLevel().getTopologyKind() == TopologyKind::NODE_BREAKER + && context.getOptions().getTopologyLevel() != TopologyLevel::NODE_BREAKER + && stdcxx::isInstanceOf(terminal.getConnectable())) { + throw PowsyblException(stdcxx::format("Terminal ref should not point to a busbar section (here %1%). Try to export in node-breaker or delete this terminal ref.", terminal.getConnectable().get().getId())); + } writer.writeStartElement(nsPrefix, elementName); writer.writeAttribute(ID, context.getAnonymizer().anonymizeString(c.get().getId())); if (c.get().getTerminals().size() > 1) { diff --git a/test/iidm/NodeBreakerVoltageLevelTest.cpp b/test/iidm/NodeBreakerVoltageLevelTest.cpp index 5b57adcf..b96a9de7 100644 --- a/test/iidm/NodeBreakerVoltageLevelTest.cpp +++ b/test/iidm/NodeBreakerVoltageLevelTest.cpp @@ -19,8 +19,10 @@ #include #include #include +#include #include #include +#include #include @@ -1186,6 +1188,25 @@ BOOST_AUTO_TEST_CASE(TestRemoveVoltageLevelWithInternalConnectionsIssue) { POWSYBL_ASSERT_THROW(network.getVoltageLevel("S5 10kV"), PowsyblException, "Unable to find to the identifiable 'S5 10kV'"); } +BOOST_AUTO_TEST_CASE(NbkComprehensiveErrorMessage) { + Network network = powsybl::network::FourSubstationsNodeBreakerFactory::create(); + BusbarSection& busbarSection = network.getBusbarSection("S1VL2_BBS1"); + TwoWindingsTransformer& twt = network.getTwoWindingsTransformer("TWT"); + twt.getPhaseTapChanger().setRegulationTerminal(stdcxx::ref(busbarSection.getTerminal())); + + stdcxx::Properties properties; + properties.set(converter::ExportOptions::TOPOLOGY_LEVEL, "NODE_BREAKER"); + + // make sure no error is thrown while exporting to NODE_BREAKER topology + std::stringstream ss; + Network::writeXml("network.xiidm", ss, network, converter::ExportOptions(properties)); + Network::readXml("network.xiidm", ss); + + // make sure an error is thrown when exporting to BUS_BREAKER topology (see #295) + properties.set(converter::ExportOptions::TOPOLOGY_LEVEL, "BUS_BREAKER"); + POWSYBL_ASSERT_THROW(Network::writeXml("network.xiidm", ss, network, converter::ExportOptions(properties)), PowsyblException, "Terminal ref should not point to a busbar section (here S1VL2_BBS1). Try to export in node-breaker or delete this terminal ref."); +} + BOOST_AUTO_TEST_SUITE_END() } // namespace iidm