2 * Copyright © 2020 AT&T and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.transportpce.olm.power;
11 import com.google.common.util.concurrent.FluentFuture;
12 import java.math.BigDecimal;
13 import java.util.HashMap;
15 import java.util.Optional;
16 import java.util.concurrent.ExecutionException;
17 import java.util.concurrent.Future;
18 import org.eclipse.jdt.annotation.NonNull;
19 import org.opendaylight.mdsal.common.api.CommitInfo;
20 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
21 import org.opendaylight.transportpce.common.Timeouts;
22 import org.opendaylight.transportpce.common.crossconnect.CrossConnect;
23 import org.opendaylight.transportpce.common.device.DeviceTransaction;
24 import org.opendaylight.transportpce.common.device.DeviceTransactionManager;
25 import org.opendaylight.yang.gen.v1.http.org.opendaylight.transportpce.portmapping.rev231221.mapping.Mapping;
26 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.OpticalControlMode;
27 import org.opendaylight.yang.gen.v1.http.org.openroadm.common.link.types.rev191129.PowerDBm;
28 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.OrgOpenroadmDeviceData;
29 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.pack.Ports;
30 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.pack.PortsKey;
31 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacks;
32 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.circuit.packs.CircuitPacksKey;
33 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.Interface;
34 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceBuilder;
35 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.interfaces.grp.InterfaceKey;
36 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.OrgOpenroadmDevice;
37 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.RoadmConnections;
38 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsBuilder;
39 import org.opendaylight.yang.gen.v1.http.org.openroadm.device.rev200529.org.openroadm.device.container.org.openroadm.device.RoadmConnectionsKey;
40 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev200529.och.container.OchBuilder;
41 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.Interface1;
42 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.Interface1Builder;
43 import org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.tributary.signal.interfaces.rev200529.otsi.container.OtsiBuilder;
44 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.IfOCH;
45 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.IfOCHOTU4ODU4;
46 import org.opendaylight.yang.gen.v1.http.org.openroadm.port.types.rev230526.IfOtsiOtsigroup;
47 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
48 import org.opendaylight.yangtools.yang.common.Decimal64;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
54 public final class PowerMgmtVersion710 {
55 private static final Logger LOG = LoggerFactory.getLogger(PowerMgmtVersion710.class);
57 private PowerMgmtVersion710() {
61 * This method provides Transponder transmit power range.
63 * @param circuitPackName
64 * Transponder circuitPack name
66 * Transponder port name
69 * @param deviceTransactionManager
70 * Device transaction manager to read device data
71 * @return HashMap holding Min and Max transmit power for given port
73 public static Map<String, Double> getXponderPowerRange(String circuitPackName, String portName, String deviceId,
74 DeviceTransactionManager deviceTransactionManager) {
75 InstanceIdentifier<Ports> portIID = InstanceIdentifier
76 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
77 .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
78 .child(Ports.class, new PortsKey(portName))
80 LOG.debug("Fetching logical Connection Point value for port {} at circuit pack {}", portName, circuitPackName);
81 Optional<Ports> portObject =
82 deviceTransactionManager.getDataFromDevice(deviceId, LogicalDatastoreType.OPERATIONAL, portIID,
83 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
84 if (!portObject.isPresent()) {
85 return new HashMap<>();
87 Ports port = portObject.orElseThrow();
88 if (port.getTransponderPort() == null || port.getTransponderPort().getPortPowerCapabilityMaxTx() == null) {
89 LOG.warn("Logical Connection Point value missing for {} {}", circuitPackName, port.getPortName());
90 return new HashMap<>();
92 Map<String, Double> powerRangeMap = new HashMap<>();
93 powerRangeMap.put("MaxTx", port.getTransponderPort().getPortPowerCapabilityMaxTx().getValue().doubleValue());
94 powerRangeMap.put("MinTx", port.getTransponderPort().getPortPowerCapabilityMinTx().getValue().doubleValue());
99 * This method provides Transponder transmit power range.
102 * Unique identifier for the mounted netconf- node
104 * SRG Id connected to transponder
105 * @param deviceTransactionManager
106 * Device transaction manager to read device data
107 * @param circuitPackName
108 * SRG circuitpack name
111 * @return HashMap holding Min and Max transmit power for given port
113 public static Map<String, Double> getSRGRxPowerRange(String nodeId, String srgId,
114 DeviceTransactionManager deviceTransactionManager,
115 String circuitPackName, String portName) {
116 LOG.debug("Coming inside SRG power range");
117 LOG.debug("Mapping object exists.");
118 InstanceIdentifier<Ports> portIID = InstanceIdentifier
119 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
120 .child(CircuitPacks.class, new CircuitPacksKey(circuitPackName))
121 .child(Ports.class, new PortsKey(portName))
123 LOG.debug("Fetching logical Connection Point value for port {} at circuit pack {}{}", portName,
124 circuitPackName, portIID);
125 Optional<Ports> portObject =
126 deviceTransactionManager.getDataFromDevice(nodeId, LogicalDatastoreType.OPERATIONAL, portIID,
127 Timeouts.DEVICE_READ_TIMEOUT, Timeouts.DEVICE_READ_TIMEOUT_UNIT);
128 if (!portObject.isPresent()) {
129 LOG.info("Port not found");
130 return new HashMap<>();
132 Ports port = portObject.orElseThrow();
133 if (port.getRoadmPort() == null) {
134 LOG.warn("Roadm ports power value is missing for {} {}", circuitPackName, port.getPortName());
135 return new HashMap<>();
137 LOG.debug("Port found on the node ID");
138 Map<String, Double> powerRangeMap = new HashMap<>();
139 powerRangeMap.put("MinRx", port.getRoadmPort().getPortPowerCapabilityMinRx().getValue().doubleValue());
140 powerRangeMap.put("MaxRx", port.getRoadmPort().getPortPowerCapabilityMaxRx().getValue().doubleValue());
141 return powerRangeMap;
145 * This method retrieves transponder OCH interface and
149 * Unique identifier for the mounted netconf- node
150 * @param interfaceName
151 * OCH interface name carrying WL
153 * Calculated transmit power
154 * @param deviceTransactionManager
155 * Device Transaction Manager
156 * @param interfaceObj
159 * @return true/false based on status of operation
161 public static boolean setTransponderPower(String nodeId, String interfaceName, BigDecimal txPower,
162 DeviceTransactionManager deviceTransactionManager, Interface interfaceObj, Mapping portMap) {
163 LOG.debug("Setting target-power for transponder nodeId: {} InterfaceName: {}",
164 nodeId, interfaceName);
165 // Transponder port can have a port-capability of 100 or 400G
166 // from port-mapping check if has OCH-OTU-ODU cap or OTSI cap
167 // need to set power for OCH port
168 InterfaceBuilder ochOtsiInterfaceBuilder = new InterfaceBuilder(interfaceObj);
169 if (portMap.getSupportedInterfaceCapability().contains(IfOCHOTU4ODU4.VALUE)
170 || portMap.getSupportedInterfaceCapability().contains(IfOCH.VALUE)) {
171 ochOtsiInterfaceBuilder
173 new org.opendaylight.yang.gen.v1.http.org.openroadm.optical.channel.interfaces.rev200529
177 ochOtsiInterfaceBuilder
178 .augmentation(org.opendaylight.yang.gen.v1.http
179 .org.openroadm.optical.channel.interfaces.rev200529.Interface1.class)
181 .setTransmitPower(new PowerDBm(Decimal64.valueOf(txPower)))
184 } else if (portMap.getSupportedInterfaceCapability().contains(IfOtsiOtsigroup.VALUE)) {
185 ochOtsiInterfaceBuilder
187 new Interface1Builder()
189 new OtsiBuilder(ochOtsiInterfaceBuilder.augmentation(Interface1.class).getOtsi())
190 .setTransmitPower(new PowerDBm(Decimal64.valueOf(txPower)))
194 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(nodeId);
195 DeviceTransaction deviceTx;
197 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
198 if (deviceTxOpt.isEmpty()) {
199 LOG.error("Transaction for device {} was not found during transponder power setup for Node:", nodeId);
202 deviceTx = deviceTxOpt.orElseThrow();
203 } catch (InterruptedException | ExecutionException e) {
204 LOG.error("Unable to get transaction for device {} during transponder power setup!", nodeId, e);
207 InstanceIdentifier<Interface> interfacesIID = InstanceIdentifier
208 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
209 .child(Interface.class, new InterfaceKey(interfaceName))
211 deviceTx.merge(LogicalDatastoreType.CONFIGURATION, interfacesIID, ochOtsiInterfaceBuilder.build());
212 FluentFuture<? extends @NonNull CommitInfo> commit =
213 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
216 LOG.info("Transponder Power update is committed");
218 } catch (InterruptedException | ExecutionException e) {
219 LOG.error("Setting transponder power failed: ", e);
225 * This method does an edit-config on roadm connection subtree for a given
226 * connection number in order to set power level for use by the optical
232 * Optical control modelcan be off, power or gainLoss.
234 * Power value in DBm.
235 * @param connectionNumber
236 * Name of the cross connect.
237 * @param crossConnect
239 * @param deviceTransactionManager
240 * Device Transaction Manager.
242 * @return true/false based on status of operation.
244 public static boolean setPowerLevel(String deviceId, OpticalControlMode mode, BigDecimal powerValue,
245 String connectionNumber, CrossConnect crossConnect,
246 DeviceTransactionManager deviceTransactionManager) {
247 @SuppressWarnings("unchecked") Optional<RoadmConnections> rdmConnOpt =
248 (Optional<RoadmConnections>) crossConnect.getCrossConnect(deviceId, connectionNumber);
249 if (!rdmConnOpt.isPresent()) {
250 LOG.warn("Roadm-Connection is null in set power level ({})", connectionNumber);
253 RoadmConnectionsBuilder rdmConnBldr = new RoadmConnectionsBuilder(rdmConnOpt.orElseThrow());
254 rdmConnBldr.setOpticalControlMode(mode);
255 if (powerValue != null) {
256 rdmConnBldr.setTargetOutputPower(new PowerDBm(Decimal64.valueOf(powerValue)));
258 RoadmConnections newRdmConn = rdmConnBldr.build();
259 Future<Optional<DeviceTransaction>> deviceTxFuture = deviceTransactionManager.getDeviceTransaction(deviceId);
260 DeviceTransaction deviceTx;
262 Optional<DeviceTransaction> deviceTxOpt = deviceTxFuture.get();
263 if (!deviceTxOpt.isPresent()) {
264 LOG.error("Transaction for device {} was not found!", deviceId);
267 deviceTx = deviceTxOpt.orElseThrow();
268 } catch (InterruptedException | ExecutionException e) {
269 LOG.error("Unable to get transaction for device {}!", deviceId, e);
272 // post the cross connect on the device
273 InstanceIdentifier<RoadmConnections> roadmConnIID = InstanceIdentifier
274 .builderOfInherited(OrgOpenroadmDeviceData.class, OrgOpenroadmDevice.class)
275 .child(RoadmConnections.class, new RoadmConnectionsKey(connectionNumber))
277 deviceTx.merge(LogicalDatastoreType.CONFIGURATION, roadmConnIID, newRdmConn);
278 FluentFuture<? extends @NonNull CommitInfo> commit =
279 deviceTx.commit(Timeouts.DEVICE_WRITE_TIMEOUT, Timeouts.DEVICE_WRITE_TIMEOUT_UNIT);
282 LOG.info("Roadm connection power level successfully set ");
284 } catch (InterruptedException | ExecutionException ex) {
285 LOG.warn("Failed to post {}", newRdmConn, ex);