From 71aa0aae2ddf8efe5c0a99352e66cd03d71053bf Mon Sep 17 00:00:00 2001 From: Balagangadhar Bathula Date: Wed, 26 Jan 2022 09:07:00 -0500 Subject: [PATCH] Update power target mask for mixed line-rate Update power (P1 [50GHz]) for 400/100G mixed line, according to the openROADM Optical Specifications v5.0 JIRA: TRNSPRTPCE-457 Signed-off-by: Balagangadhar Bathula Change-Id: Ie7a6196639f3ac386772bf0d1d6d3e1382fc8bf6 --- .../yang/transportpce-olm@2021-06-18.yang | 4 +- .../transportpce/olm/power/PowerMgmtImpl.java | 51 ++++++++++++++----- .../renderer/ModelMappingUtils.java | 12 +++-- tests/transportpce_tests/1.2.1/test05_olm.py | 2 +- tests/transportpce_tests/2.2.1/test09_olm.py | 2 +- 5 files changed, 50 insertions(+), 21 deletions(-) diff --git a/api/src/main/yang/transportpce-olm@2021-06-18.yang b/api/src/main/yang/transportpce-olm@2021-06-18.yang index a49fc9189..24e7feca7 100644 --- a/api/src/main/yang/transportpce-olm@2021-06-18.yang +++ b/api/src/main/yang/transportpce-olm@2021-06-18.yang @@ -1,5 +1,5 @@ module transportpce-olm { - yang-version 1; + yang-version 1.1; namespace "http://org/opendaylight/transportpce/olm"; prefix org-opendaylight-transportpce-olm; @@ -146,7 +146,7 @@ module transportpce-olm { description "This RPC can be used by PM monitoring to calculate spanloss periodically"; - input; + // input; output { leaf result { type string; diff --git a/olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmtImpl.java b/olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmtImpl.java index 8b637cbfe..9f993bbb5 100644 --- a/olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmtImpl.java +++ b/olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmtImpl.java @@ -42,6 +42,7 @@ public class PowerMgmtImpl implements PowerMgmt { private static final BigDecimal DEFAULT_TPDR_PWR_100G = new BigDecimal(-5); private static final BigDecimal DEFAULT_TPDR_PWR_400G = new BigDecimal(0); private static final String INTERFACE_NOT_PRESENT = "Interface {} on node {} is not present!"; + private static final double MC_WIDTH_GRAN = 2 * GridConstant.GRANULARITY; private long timer1 = 120000; // openroadm spec value is 120000, functest value is 3000 @@ -174,9 +175,10 @@ public class PowerMgmtImpl implements PowerMgmt { destTpId, nodeId, openroadmVersion.getIntValue()); LOG.info("Spanloss TX is {}", spanLossTx); - if (spanLossTx == null || spanLossTx.intValue() <= 0 || spanLossTx.intValue() > 28) { - LOG.error("Power Value is null: spanLossTx null or out of openROADM range ]0,28] {}", - spanLossTx); + // TODO: The span-loss limits should be obtained from optical specifications + if (spanLossTx == null || spanLossTx.intValue() <= 0 || spanLossTx.intValue() > 27) { + LOG.error("Power Value is null: spanLossTx null or out of openROADM range ]0,27] {}", + spanLossTx); return false; } BigDecimal powerValue = getRdmPowerValue(spanLossTx, input); @@ -369,22 +371,45 @@ public class PowerMgmtImpl implements PowerMgmt { private BigDecimal getRdmPowerValue(BigDecimal spanLossTx, ServicePowerSetupInput input) { - BigDecimal powerValue = spanLossTx.subtract(BigDecimal.valueOf(9)).min(BigDecimal.valueOf(2)); + // TODO: These values will be obtained from the specifications + // power-value here refers to the Pin[50GHz] + BigDecimal powerValue; + if (spanLossTx.doubleValue() >= 23.0) { + powerValue = BigDecimal.valueOf(2.0); + } else if (spanLossTx.doubleValue() >= 8.0) { + powerValue = BigDecimal.valueOf(- (8.0 - spanLossTx.doubleValue()) / 3.0 - 3.0); + } else if (spanLossTx.doubleValue() >= 6.0) { + powerValue = BigDecimal.valueOf(-3.0); + } else { + powerValue = spanLossTx.subtract(BigDecimal.valueOf(9)); + } + // target-output-power yang precision is 2, so we limit here to 2 + powerValue = powerValue.setScale(2, RoundingMode.CEILING); + LOG.info("P1[50GHz]={} dBm for spanloss {} based on OpenROADM-5.0 specs power target mask", powerValue, + spanLossTx); // we work at constant power spectral density (50 GHz channel width @-20dBm=37.5GHz) // 87.5 GHz channel width @-20dBm=75GHz if (input.getMcWidth() != null) { - LOG.debug("Input Gridsize is {}",input.getMcWidth().getValue()); - if (input.getMcWidth().getValue().equals(GridConstant.WIDTH_80)) { - powerValue = powerValue.add(BigDecimal.valueOf(3)); - } else if (input.getMcWidth().getValue().equals(GridConstant.SLOT_WIDTH_87_5)) { - BigDecimal logVal = GridConstant.SLOT_WIDTH_87_5.divide(new BigDecimal(50)); - double pdsVal = 10 * Math.log10(logVal.doubleValue()); - powerValue = powerValue.add(new BigDecimal(pdsVal, new MathContext(3, RoundingMode.HALF_EVEN))); - } + // Units of MC-wdith are in GHz, meaning it should be 40/50/87.5GHz + // TODO: Should we validate this units before proceeding? + LOG.debug("Input Grid size is {}",input.getMcWidth().getValue()); + + // We round-off the mc-width to the nearest grid-value based on the granularity of 12.5 GHz + double nbrMcSlots = Math.ceil(input.getMcWidth().getValue().doubleValue() / MC_WIDTH_GRAN); + LOG.debug("Nearest (ceil) number of slots {}", nbrMcSlots); + BigDecimal mcWidth = new BigDecimal(MC_WIDTH_GRAN * nbrMcSlots); + LOG.info("Given mc-width={}, Rounded mc-width={}", input.getMcWidth().getValue(), mcWidth); + + BigDecimal logVal = mcWidth.divide(new BigDecimal(50)); + double pdsVal = 10 * Math.log10(logVal.doubleValue()); + // Addition of PSD value will give Pin[87.5 GHz] + powerValue = powerValue.add(new BigDecimal(pdsVal, new MathContext(3, + RoundingMode.HALF_EVEN))); + LOG.info("P1[{}GHz]={} dB will be used for OSNR calculation", mcWidth, powerValue); } // FIXME compliancy with OpenROADM MSA and approximations used -- should be addressed with powermask update // cf JIRA ticket https://jira.opendaylight.org/browse/TRNSPRTPCE-494 - LOG.info("Power Value is {}", powerValue); + LOG.info("The power value is {} for spanloss {}", powerValue, spanLossTx); return powerValue; } diff --git a/renderer/src/main/java/org/opendaylight/transportpce/renderer/ModelMappingUtils.java b/renderer/src/main/java/org/opendaylight/transportpce/renderer/ModelMappingUtils.java index 1812fe237..11c3f9f90 100644 --- a/renderer/src/main/java/org/opendaylight/transportpce/renderer/ModelMappingUtils.java +++ b/renderer/src/main/java/org/opendaylight/transportpce/renderer/ModelMappingUtils.java @@ -8,6 +8,7 @@ package org.opendaylight.transportpce.renderer; import com.google.common.util.concurrent.ListenableFuture; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -79,14 +80,17 @@ public final class ModelMappingUtils { olmSetupBldr.setWaveNumber(atoZDirection.getAToZWavelengthNumber()); if (atoZDirection.getAToZMinFrequency() != null) { olmSetupBldr.setLowerSpectralSlotNumber(Uint32 - .valueOf(GridUtils - .getLowerSpectralIndexFromFrequency(atoZDirection.getAToZMinFrequency().getValue()))); + .valueOf(GridUtils + .getLowerSpectralIndexFromFrequency(atoZDirection.getAToZMinFrequency().getValue()))); } if (atoZDirection.getAToZMaxFrequency() != null) { olmSetupBldr.setHigherSpectralSlotNumber(Uint32 - .valueOf(GridUtils - .getHigherSpectralIndexFromFrequency(atoZDirection.getAToZMaxFrequency().getValue()))); + .valueOf(GridUtils + .getHigherSpectralIndexFromFrequency(atoZDirection.getAToZMaxFrequency().getValue()))); } + // Set the MC-width for the OLM + olmSetupBldr.setMcWidth(new FrequencyGHz(atoZDirection.getAToZMaxFrequency().getValue() + .subtract(atoZDirection.getAToZMinFrequency().getValue()).multiply(new BigDecimal(1000)))); } return olmSetupBldr.build(); } diff --git a/tests/transportpce_tests/1.2.1/test05_olm.py b/tests/transportpce_tests/1.2.1/test05_olm.py index 27d8ba69c..500ae5571 100644 --- a/tests/transportpce_tests/1.2.1/test05_olm.py +++ b/tests/transportpce_tests/1.2.1/test05_olm.py @@ -378,7 +378,7 @@ class TransportOlmTesting(unittest.TestCase): self.assertEqual(response.status_code, requests.codes.ok) res = response.json() self.assertEqual("gainLoss", res['roadm-connections'][0]['opticalControlMode']) - self.assertEqual(2, res['roadm-connections'][0]['target-output-power']) + self.assertEqual(-0.63, res['roadm-connections'][0]['target-output-power']) def test_26_service_power_turndown_XPDRA_XPDRC(self): url = "{}/operations/transportpce-olm:service-power-turndown" diff --git a/tests/transportpce_tests/2.2.1/test09_olm.py b/tests/transportpce_tests/2.2.1/test09_olm.py index 62e352cb0..a72c10b10 100644 --- a/tests/transportpce_tests/2.2.1/test09_olm.py +++ b/tests/transportpce_tests/2.2.1/test09_olm.py @@ -310,7 +310,7 @@ class TransportOlmTesting(unittest.TestCase): self.assertEqual(response.status_code, requests.codes.ok) res = response.json() self.assertEqual("gainLoss", res['roadm-connections'][0]['opticalControlMode']) - self.assertEqual(2.0, res['roadm-connections'][0]['target-output-power']) + self.assertEqual(0.21, res['roadm-connections'][0]['target-output-power']) def test_22_get_roadmconnection_ROADMC(self): response = test_utils.check_netconf_node_request( -- 2.36.6