Update power target mask for mixed line-rate 71/99671/1
authorBalagangadhar Bathula <bb4341@att.com>
Wed, 26 Jan 2022 14:07:00 +0000 (09:07 -0500)
committerGilles Thouenon <gilles.thouenon@orange.com>
Wed, 9 Feb 2022 08:38:50 +0000 (09:38 +0100)
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 <bb4341@att.com>
Change-Id: Ie7a6196639f3ac386772bf0d1d6d3e1382fc8bf6

api/src/main/yang/transportpce-olm@2021-06-18.yang
olm/src/main/java/org/opendaylight/transportpce/olm/power/PowerMgmtImpl.java
renderer/src/main/java/org/opendaylight/transportpce/renderer/ModelMappingUtils.java
tests/transportpce_tests/1.2.1/test05_olm.py
tests/transportpce_tests/2.2.1/test09_olm.py

index a49fc918986166417a41cacc2aebf5538b409344..24e7feca78e0b1f3b679004953b87596e462a920 100644 (file)
@@ -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;
index 8b637cbfea8c8d41e7371965ba6c11b5948f79bd..9f993bbb5b1f2e4674531d5da981e478dbe0dfe3 100644 (file)
@@ -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;
     }
 
index 1812fe2377dcb298af06361bb61eda3b6bcfb7ed..11c3f9f9070f3cc62e9e7d1c8cc0210a5e90dba0 100644 (file)
@@ -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();
     }
index 27d8ba69cb53dba99d03dc01819d0bb2ee7f5df7..500ae55715dee44a85d1899e842cfe3df69c431e 100644 (file)
@@ -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"
index 62e352cb0f703796c8013e303bdcd239577431d3..a72c10b106aed4befc9c6b9657ef2df33f657558 100644 (file)
@@ -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(