+ private Map<String, Double> getTxPowerRangeMap(Nodes inputNode, String destTpId, String nodeId,
+ Integer openroadmVersion) {
+
+ Optional<Mapping> mappingObject = inputNode.nonnullMapping().values().stream()
+ .filter(o -> o.key().equals(new MappingKey(destTpId))).findFirst();
+ if (mappingObject.isEmpty()) {
+ LOG.info("Mapping object not found for nodeId: {}", nodeId);
+ // FIXME shouldn't it be LOG.error ?
+ return null;
+ // return null here means return false in setPower()
+ // TODO Align protections with getSRGRxPowerRangeMap
+ }
+
+ String circuitPackName = mappingObject.orElseThrow().getSupportingCircuitPackName();
+ String portName = mappingObject.orElseThrow().getSupportingPort();
+ switch (openroadmVersion) {
+ case 1:
+ return PowerMgmtVersion121.getXponderPowerRange(circuitPackName, portName,
+ nodeId, deviceTransactionManager);
+ case 2:
+ return PowerMgmtVersion221.getXponderPowerRange(circuitPackName, portName,
+ nodeId, deviceTransactionManager);
+ case 3:
+ return PowerMgmtVersion710.getXponderPowerRange(circuitPackName, portName,
+ nodeId, deviceTransactionManager);
+ default:
+ LOG.error("Unrecognized OpenRoadm version");
+ return new HashMap<>();
+ // FIXME shouldn't it lead to a return false in setPower()?
+ }
+ }
+
+
+ private Map<String, Double> getSRGRxPowerRangeMap(String srgId, String nodeId, Integer openroadmVersion) {
+
+ Nodes inputNode = this.portMapping.getNode(nodeId);
+ int rdmOpenroadmVersion = inputNode.getNodeInfo().getOpenroadmVersion().getIntValue();
+ Optional<Mapping> mappingObject = inputNode.nonnullMapping().values().stream()
+ .filter(o -> o.key().equals(new MappingKey(srgId)))
+ .findFirst();
+
+ if (mappingObject.isEmpty()) {
+ return new HashMap<>();
+ // FIXME shouldn't it lead to a return false in setPower() ?
+ }
+
+ String circuitPackName = mappingObject.orElseThrow().getSupportingCircuitPackName();
+ String portName = mappingObject.orElseThrow().getSupportingPort();
+ switch (rdmOpenroadmVersion) {
+ case 1:
+ return PowerMgmtVersion121.getSRGRxPowerRange(nodeId, srgId,
+ deviceTransactionManager, circuitPackName, portName);
+ case 2:
+ return PowerMgmtVersion221.getSRGRxPowerRange(nodeId, srgId,
+ deviceTransactionManager, circuitPackName, portName);
+ case 3:
+ return PowerMgmtVersion710.getSRGRxPowerRange(nodeId, srgId,
+ deviceTransactionManager, circuitPackName, portName);
+ default:
+ LOG.error("Unrecognized OpenRoadm version");
+ return null;
+ //return null here means return false in setPower()
+ // TODO Align protections with getTxPowerRangeMap
+ }
+ }
+
+ private BigDecimal getSpanLossTx(String supportingOts, String destTpId, String nodeId, Integer openroadmVersion) {
+ try {
+ switch (openroadmVersion) {
+ case 1:
+ Optional<Interface> interfaceOpt =
+ this.openRoadmInterfaces.getInterface(nodeId, supportingOts);
+ if (interfaceOpt.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
+ return null;
+ }
+ if (interfaceOpt.orElseThrow().augmentation(Interface1.class).getOts()
+ .getSpanLossTransmit() == null) {
+ LOG.error("interface {} has no spanloss value", interfaceOpt.orElseThrow().getName());
+ return null;
+ }
+ return interfaceOpt.orElseThrow()
+ .augmentation(Interface1.class)
+ .getOts().getSpanLossTransmit().getValue().decimalValue();
+ case 2:
+ Optional<org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev181019
+ .interfaces.grp.Interface> interfaceOpt1 =
+ this.openRoadmInterfaces.getInterface(nodeId, supportingOts);
+ if (interfaceOpt1.isEmpty()) {
+ LOG.error(INTERFACE_NOT_PRESENT, supportingOts, nodeId);
+ return null;
+ }
+ if (interfaceOpt1.orElseThrow().augmentation(org.opendaylight.yang.gen.v1.http.org
+ .openroadm.optical.transport.interfaces.rev181019.Interface1.class).getOts()
+ .getSpanLossTransmit() == null) {
+ LOG.error("interface {} has no spanloss value", interfaceOpt1.orElseThrow().getName());
+ return null;
+ }
+ return interfaceOpt1.orElseThrow()
+ .augmentation(org.opendaylight.yang.gen.v1.http.org
+ .openroadm.optical.transport.interfaces.rev181019.Interface1.class)
+ .getOts().getSpanLossTransmit().getValue().decimalValue();
+ // TODO no case 3 ?
+ default:
+ return null;
+ }
+ } catch (OpenRoadmInterfaceException ex) {
+ LOG.error("Failed to get interface {} from node {}!",
+ supportingOts, nodeId, ex);
+ return null;
+ } catch (IllegalArgumentException ex) {
+ LOG.error("Failed to get non existing interface {} from node {}!",
+ supportingOts, nodeId);
+ return null;
+ }
+ }
+
+ private BigDecimal getXpdrPowerValue(Nodes inputNode, String destTpId, String nodeId, Integer openroadmVersion,
+ String srgId, String nextNodeId) {
+
+ Map<String, Double> txPowerRangeMap = getTxPowerRangeMap(inputNode, destTpId, nodeId, openroadmVersion);
+ if (txPowerRangeMap == null) {
+ return null;
+ // return null here means return false in setPower()
+ }
+ BigDecimal powerVal =
+ openroadmVersion == 3 ? DEFAULT_TPDR_PWR_400G : DEFAULT_TPDR_PWR_100G;
+ if (txPowerRangeMap.isEmpty()) {
+ LOG.info("Tranponder range not available setting to default power for nodeId: {}", nodeId);
+ return powerVal;
+ }
+
+ Map<String, Double> rxSRGPowerRangeMap = getSRGRxPowerRangeMap(srgId, nextNodeId, openroadmVersion);
+ if (rxSRGPowerRangeMap == null) {
+ return null;
+ // return null here means return false in setPower()
+ // TODO empty txPowerRangeMap + null rxSRGPowerRangeMap is allowed
+ // => confirm this behavior is OK
+ }
+ if (rxSRGPowerRangeMap.isEmpty()) {
+ LOG.info("SRG Power Range not found, setting the Transponder range to default");
+ return powerVal;
+ }
+
+ powerVal = new BigDecimal(txPowerRangeMap.get("MaxTx"))
+ .min(new BigDecimal(rxSRGPowerRangeMap.get("MaxRx")));
+ LOG.info("Calculated Transponder Power value is {}" , powerVal);
+ return powerVal;
+ }
+
+
+ private BigDecimal getRdmPowerValue(BigDecimal spanLossTx, ServicePowerSetupInput input) {
+ // 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));
+ }
+ BigDecimal mcWidth = new BigDecimal(50);
+ // 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) {
+ // Units of MC-width 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);
+ mcWidth = new BigDecimal(MC_WIDTH_GRAN * nbrMcSlots);
+ LOG.debug("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)));
+ }
+ // FIXME compliancy with OpenROADM MSA and approximations used -- should be addressed with powermask update
+ // cf JIRA ticket https://jira.opendaylight.org/browse/TRNSPRTPCE-494
+ powerValue = powerValue.setScale(2, RoundingMode.CEILING);
+ // target-output-power yang precision is 2, so we limit here to 2
+ LOG.info("The power value is P1[{}GHz]={} dB for spanloss {}", mcWidth, powerValue, spanLossTx);
+ return powerValue;
+ }
+