(gui) - refactored nodetypes to use an id for uniqueness, makes editing and accounting for changes to icons/names an easier process, (rest) - no longer return ctrlnet is session nodes
This commit is contained in:
parent
670ed96167
commit
6d885935b7
10 changed files with 71 additions and 81 deletions
|
@ -98,8 +98,7 @@ public class Controller implements Initializable {
|
||||||
try {
|
try {
|
||||||
coreClient.initialJoin();
|
coreClient.initialJoin();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.error("failure during initial join", ex);
|
Toast.error(String.format("Initial join failure: %s", ex.getMessage()), ex);
|
||||||
Toast.error(String.format("Initial join failure: %s", ex.getMessage()));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,14 @@ public class CoreRestClient implements ICoreClient {
|
||||||
|
|
||||||
logger.info("joining core session({}) state({}): {}", sessionId, sessionState, session);
|
logger.info("joining core session({}) state({}): {}", sessionId, sessionState, session);
|
||||||
for (CoreNode node : session.getNodes()) {
|
for (CoreNode node : session.getNodes()) {
|
||||||
if (node.getModel() == null) {
|
NodeType nodeType = NodeType.find(node.getType(), node.getModel());
|
||||||
logger.info("skipping joined session node: {}", node.getName());
|
if (nodeType == null) {
|
||||||
|
logger.info(String.format("failed to find node type(%s) model(%s): %s",
|
||||||
|
node.getType(), node.getModel(), node.getName()));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeType nodeType = NodeType.getNodeType(node.getNodeTypeKey());
|
node.setNodeType(nodeType);
|
||||||
node.setIcon(nodeType.getIcon());
|
|
||||||
networkGraph.addNode(node);
|
networkGraph.addNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,8 @@ public class CoreNode {
|
||||||
private String emane;
|
private String emane;
|
||||||
private String url;
|
private String url;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
|
private NodeType nodeType;
|
||||||
|
@JsonIgnore
|
||||||
private String icon;
|
private String icon;
|
||||||
@JsonIgnore
|
@JsonIgnore
|
||||||
private boolean loaded = true;
|
private boolean loaded = true;
|
||||||
|
@ -42,12 +44,6 @@ public class CoreNode {
|
||||||
this.loaded = false;
|
this.loaded = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void setExternalIcon(String iconPath) {
|
|
||||||
// icon = iconPath;
|
|
||||||
// graphIcon = IconUtils.getExternalLayeredIcon(icon);
|
|
||||||
// graphIcon.add(radioIcon);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void setNodeType(NodeType nodeType) {
|
public void setNodeType(NodeType nodeType) {
|
||||||
type = nodeType.getValue();
|
type = nodeType.getValue();
|
||||||
model = nodeType.getModel();
|
model = nodeType.getModel();
|
||||||
|
@ -58,14 +54,6 @@ public class CoreNode {
|
||||||
graphIcon = IconUtils.getLayeredIcon(icon);
|
graphIcon = IconUtils.getLayeredIcon(icon);
|
||||||
}
|
}
|
||||||
graphIcon.add(radioIcon);
|
graphIcon.add(radioIcon);
|
||||||
}
|
this.nodeType = nodeType;
|
||||||
|
|
||||||
@JsonIgnore
|
|
||||||
public String getNodeTypeKey() {
|
|
||||||
if (model == null) {
|
|
||||||
return type.toString();
|
|
||||||
} else {
|
|
||||||
return String.format("%s-%s", type, model);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,28 @@
|
||||||
package com.core.data;
|
package com.core.data;
|
||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
|
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
|
||||||
public class NodeType {
|
public class NodeType {
|
||||||
private static final Logger logger = LogManager.getLogger();
|
private static final Logger logger = LogManager.getLogger();
|
||||||
|
private static final AtomicInteger idGenerator = new AtomicInteger(0);
|
||||||
|
private static final Map<Integer, NodeType> ID_LOOKUP = new HashMap<>();
|
||||||
public static final int DEFAULT = 0;
|
public static final int DEFAULT = 0;
|
||||||
public static final int SWITCH = 4;
|
public static final int SWITCH = 4;
|
||||||
public static final int HUB = 5;
|
public static final int HUB = 5;
|
||||||
public static final int WLAN = 6;
|
public static final int WLAN = 6;
|
||||||
public static final int EMANE = 10;
|
public static final int EMANE = 10;
|
||||||
private static final Map<String, NodeType> LOOKUP = new HashMap<>();
|
@EqualsAndHashCode.Include
|
||||||
private static final Map<Integer, String> DISPLAY_MAP = new HashMap<>();
|
private final int id;
|
||||||
private final int value;
|
private final int value;
|
||||||
private String display;
|
private String display;
|
||||||
private String model;
|
private String model;
|
||||||
|
@ -37,50 +42,45 @@ public class NodeType {
|
||||||
addNodeType(new NodeType(DEFAULT, "host", "Host", "/icons/host-100.png"));
|
addNodeType(new NodeType(DEFAULT, "host", "Host", "/icons/host-100.png"));
|
||||||
addNodeType(new NodeType(DEFAULT, "PC", "PC", "/icons/pc-100.png"));
|
addNodeType(new NodeType(DEFAULT, "PC", "PC", "/icons/pc-100.png"));
|
||||||
addNodeType(new NodeType(DEFAULT, "mdr", "MDR", "/icons/router-100.png"));
|
addNodeType(new NodeType(DEFAULT, "mdr", "MDR", "/icons/router-100.png"));
|
||||||
addNodeType(new NodeType(SWITCH, "Switch", "/icons/switch-100.png"));
|
addNodeType(new NodeType(SWITCH, "lanswitch", "Switch", "/icons/switch-100.png"));
|
||||||
addNodeType(new NodeType(HUB, "Hub", "/icons/hub-100.png"));
|
addNodeType(new NodeType(HUB, "hub", "Hub", "/icons/hub-100.png"));
|
||||||
addNodeType(new NodeType(WLAN, "wlan", "WLAN", "/icons/wlan-100.png"));
|
addNodeType(new NodeType(WLAN, "wlan", "WLAN", "/icons/wlan-100.png"));
|
||||||
addNodeType(new NodeType(EMANE, "EMANE", "/icons/emane-100.png"));
|
addNodeType(new NodeType(EMANE, "wlan", "EMANE", "/icons/emane-100.png"));
|
||||||
|
|
||||||
DISPLAY_MAP.put(HUB, "Hub");
|
|
||||||
DISPLAY_MAP.put(SWITCH, "Switch");
|
|
||||||
DISPLAY_MAP.put(WLAN, "WLAN");
|
|
||||||
DISPLAY_MAP.put(EMANE, "EMANE");
|
|
||||||
}
|
|
||||||
|
|
||||||
public NodeType(int value, String display, String icon) {
|
|
||||||
this(value, null, display, icon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public NodeType(int value, String model, String display, String icon) {
|
public NodeType(int value, String model, String display, String icon) {
|
||||||
|
this.id = idGenerator.incrementAndGet();
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.model = model;
|
this.model = model;
|
||||||
this.display = display;
|
this.display = display;
|
||||||
this.icon = icon;
|
this.icon = icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getKey() {
|
|
||||||
if (model == null) {
|
|
||||||
return Integer.toString(value);
|
|
||||||
} else {
|
|
||||||
return String.format("%s-%s", value, model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static NodeType getNodeType(String key) {
|
|
||||||
return LOOKUP.get(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getDisplay(Integer value) {
|
|
||||||
return DISPLAY_MAP.get(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addNodeType(NodeType nodeType) {
|
public static void addNodeType(NodeType nodeType) {
|
||||||
LOOKUP.put(nodeType.getKey(), nodeType);
|
ID_LOOKUP.put(nodeType.getId(), nodeType);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Collection<NodeType> getNodeTypes() {
|
public static NodeType get(Integer id) {
|
||||||
return LOOKUP.values();
|
return ID_LOOKUP.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Collection<NodeType> getAll() {
|
||||||
|
return ID_LOOKUP.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static NodeType find(Integer type, String model) {
|
||||||
|
return ID_LOOKUP.values().stream()
|
||||||
|
.filter(nodeType -> {
|
||||||
|
boolean sameType = nodeType.getValue() == type;
|
||||||
|
boolean sameModel;
|
||||||
|
if (model != null) {
|
||||||
|
sameModel = model.equals(nodeType.getModel());
|
||||||
|
} else {
|
||||||
|
sameModel = nodeType.getModel() == null;
|
||||||
|
}
|
||||||
|
return sameType && sameModel;
|
||||||
|
})
|
||||||
|
.findFirst().orElse(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,13 +47,12 @@ public class NetworkGraph {
|
||||||
|
|
||||||
private SubnetUtils subnetUtils = new SubnetUtils("10.0.0.0/24");
|
private SubnetUtils subnetUtils = new SubnetUtils("10.0.0.0/24");
|
||||||
private CoreAddresses coreAddresses = new CoreAddresses("10.0");
|
private CoreAddresses coreAddresses = new CoreAddresses("10.0");
|
||||||
private NodeType nodeType = NodeType.getNodeType("0-host");
|
private NodeType nodeType;
|
||||||
private Map<Integer, CoreNode> nodeMap = new ConcurrentHashMap<>();
|
private Map<Integer, CoreNode> nodeMap = new ConcurrentHashMap<>();
|
||||||
private int vertexId = 1;
|
private int vertexId = 1;
|
||||||
private int linkId = 1;
|
private int linkId = 1;
|
||||||
private Supplier<CoreNode> vertexFactory = () -> new CoreNode(vertexId++);
|
private Supplier<CoreNode> vertexFactory = () -> new CoreNode(vertexId++);
|
||||||
private Supplier<CoreLink> linkFactory = () -> new CoreLink(linkId++);
|
private Supplier<CoreLink> linkFactory = () -> new CoreLink(linkId++);
|
||||||
private Set<NodeType> nodeTypes = new HashSet<>();
|
|
||||||
private CorePopupGraphMousePlugin customPopupPlugin;
|
private CorePopupGraphMousePlugin customPopupPlugin;
|
||||||
private CoreAnnotatingGraphMousePlugin<CoreNode, CoreLink> customAnnotatingPlugin;
|
private CoreAnnotatingGraphMousePlugin<CoreNode, CoreLink> customAnnotatingPlugin;
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,14 @@ public class GraphToolbar extends VBox {
|
||||||
private static final PseudoClass STOP_CLASS = PseudoClass.getPseudoClass("stop");
|
private static final PseudoClass STOP_CLASS = PseudoClass.getPseudoClass("stop");
|
||||||
private static final PseudoClass SELECTED_CLASS = PseudoClass.getPseudoClass("selected");
|
private static final PseudoClass SELECTED_CLASS = PseudoClass.getPseudoClass("selected");
|
||||||
private final Controller controller;
|
private final Controller controller;
|
||||||
|
private final Map<Integer, Label> labelMap = new HashMap<>();
|
||||||
|
private SVGGlyph startIcon;
|
||||||
|
private SVGGlyph stopIcon;
|
||||||
|
private JFXListView<Label> nodesList = new JFXListView<>();
|
||||||
|
private JFXListView<Label> devicesList = new JFXListView<>();
|
||||||
|
private JFXButton selectedEditButton;
|
||||||
|
private NodeType selectedNodeType;
|
||||||
|
private boolean isEditing = false;
|
||||||
|
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton runButton;
|
private JFXButton runButton;
|
||||||
|
@ -58,16 +66,6 @@ public class GraphToolbar extends VBox {
|
||||||
@FXML
|
@FXML
|
||||||
private JFXButton devicesButton;
|
private JFXButton devicesButton;
|
||||||
|
|
||||||
private SVGGlyph startIcon;
|
|
||||||
private SVGGlyph stopIcon;
|
|
||||||
private JFXListView<Label> nodesList = new JFXListView<>();
|
|
||||||
private JFXListView<Label> devicesList = new JFXListView<>();
|
|
||||||
private Map<String, NodeType> nodeTypeMap = new HashMap<>();
|
|
||||||
private Map<String, Label> labelMap = new HashMap<>();
|
|
||||||
private JFXButton selectedEditButton;
|
|
||||||
private NodeType selectedNodeType;
|
|
||||||
private boolean isEditing = false;
|
|
||||||
|
|
||||||
public GraphToolbar(Controller controller) {
|
public GraphToolbar(Controller controller) {
|
||||||
this.controller = controller;
|
this.controller = controller;
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/graph_toolbar.fxml"));
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/graph_toolbar.fxml"));
|
||||||
|
@ -145,13 +143,13 @@ public class GraphToolbar extends VBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupNodeTypes() {
|
private void setupNodeTypes() {
|
||||||
for (NodeType nodeType : NodeType.getNodeTypes()) {
|
for (NodeType nodeType : NodeType.getAll()) {
|
||||||
ImageView icon = new ImageView(nodeType.getIcon());
|
ImageView icon = new ImageView(nodeType.getIcon());
|
||||||
icon.setFitWidth(NODES_ICON_SIZE);
|
icon.setFitWidth(NODES_ICON_SIZE);
|
||||||
icon.setFitHeight(NODES_ICON_SIZE);
|
icon.setFitHeight(NODES_ICON_SIZE);
|
||||||
Label label = new Label(nodeType.getDisplay(), icon);
|
Label label = new Label(nodeType.getDisplay(), icon);
|
||||||
nodeTypeMap.put(nodeType.getDisplay(), nodeType);
|
label.setUserData(nodeType.getId());
|
||||||
labelMap.put(nodeType.getDisplay(), label);
|
labelMap.put(nodeType.getId(), label);
|
||||||
|
|
||||||
if (nodeType.getValue() == NodeType.DEFAULT) {
|
if (nodeType.getValue() == NodeType.DEFAULT) {
|
||||||
nodesList.getItems().add(label);
|
nodesList.getItems().add(label);
|
||||||
|
@ -167,7 +165,7 @@ public class GraphToolbar extends VBox {
|
||||||
// initial node
|
// initial node
|
||||||
nodesList.getSelectionModel().selectFirst();
|
nodesList.getSelectionModel().selectFirst();
|
||||||
Label selectedNodeLabel = nodesList.getSelectionModel().getSelectedItem();
|
Label selectedNodeLabel = nodesList.getSelectionModel().getSelectedItem();
|
||||||
selectedNodeType = nodeTypeMap.get(selectedNodeLabel.getText());
|
selectedNodeType = NodeType.get((int) selectedNodeLabel.getUserData());
|
||||||
selectedEditButton = nodesButton;
|
selectedEditButton = nodesButton;
|
||||||
controller.getNetworkGraph().setNodeType(selectedNodeType);
|
controller.getNetworkGraph().setNodeType(selectedNodeType);
|
||||||
updateButtonValues(nodesButton, selectedNodeLabel);
|
updateButtonValues(nodesButton, selectedNodeLabel);
|
||||||
|
@ -200,7 +198,8 @@ public class GraphToolbar extends VBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtonValues(nodesButton, current);
|
updateButtonValues(nodesButton, current);
|
||||||
selectedNodeType = nodeTypeMap.get(current.getText());
|
selectedNodeType = NodeType.get((int) current.getUserData());
|
||||||
|
logger.info("selected node type: {}", selectedNodeType);
|
||||||
setSelectedEditButton(nodesButton);
|
setSelectedEditButton(nodesButton);
|
||||||
devicesList.getSelectionModel().clearSelection();
|
devicesList.getSelectionModel().clearSelection();
|
||||||
controller.getNetworkGraph().setNodeType(selectedNodeType);
|
controller.getNetworkGraph().setNodeType(selectedNodeType);
|
||||||
|
@ -220,7 +219,8 @@ public class GraphToolbar extends VBox {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButtonValues(devicesButton, current);
|
updateButtonValues(devicesButton, current);
|
||||||
selectedNodeType = nodeTypeMap.get(current.getText());
|
selectedNodeType = NodeType.get((int) current.getUserData());
|
||||||
|
logger.info("selected node type: {}", selectedNodeType);
|
||||||
controller.getNetworkGraph().setNodeType(selectedNodeType);
|
controller.getNetworkGraph().setNodeType(selectedNodeType);
|
||||||
setSelectedEditButton(devicesButton);
|
setSelectedEditButton(devicesButton);
|
||||||
nodesList.getSelectionModel().clearSelection();
|
nodesList.getSelectionModel().clearSelection();
|
||||||
|
@ -241,14 +241,14 @@ public class GraphToolbar extends VBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateNodeType(String display, String uri) {
|
public void updateNodeType(int id, String uri) {
|
||||||
Label label = labelMap.get(display);
|
Label label = labelMap.get(id);
|
||||||
ImageView icon = new ImageView(uri);
|
ImageView icon = new ImageView(uri);
|
||||||
icon.setFitWidth(NODES_ICON_SIZE);
|
icon.setFitWidth(NODES_ICON_SIZE);
|
||||||
icon.setFitHeight(NODES_ICON_SIZE);
|
icon.setFitHeight(NODES_ICON_SIZE);
|
||||||
label.setGraphic(icon);
|
label.setGraphic(icon);
|
||||||
|
|
||||||
if (selectedNodeType.getDisplay().equals(display)) {
|
if (selectedNodeType.getId() == id) {
|
||||||
updateButtonValues(nodesButton, label);
|
updateButtonValues(nodesButton, label);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ public class NodeDetails extends ScrollPane {
|
||||||
if (node.getType() == NodeType.DEFAULT) {
|
if (node.getType() == NodeType.DEFAULT) {
|
||||||
addRow("Model", node.getModel());
|
addRow("Model", node.getModel());
|
||||||
} else {
|
} else {
|
||||||
addRow("Type", NodeType.getDisplay(node.getType()));
|
addRow("Type", node.getNodeType().getDisplay());
|
||||||
}
|
}
|
||||||
if (node.getEmane() != null) {
|
if (node.getEmane() != null) {
|
||||||
addRow("EMANE", node.getEmane());
|
addRow("EMANE", node.getEmane());
|
||||||
|
|
|
@ -85,14 +85,14 @@ public class NodeTypesDialog extends StageDialog {
|
||||||
String iconPath = iconTextField.getText();
|
String iconPath = iconTextField.getText();
|
||||||
selectedNodeType.setIcon(iconPath);
|
selectedNodeType.setIcon(iconPath);
|
||||||
for (CoreNode node : controller.getNetworkGraph().getGraph().getVertices()) {
|
for (CoreNode node : controller.getNetworkGraph().getGraph().getVertices()) {
|
||||||
if (!selectedNodeType.getKey().equals(node.getNodeTypeKey())) {
|
if (selectedNodeType != node.getNodeType()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
node.setNodeType(selectedNodeType);
|
node.setNodeType(selectedNodeType);
|
||||||
}
|
}
|
||||||
controller.getNetworkGraph().getGraphViewer().repaint();
|
controller.getNetworkGraph().getGraphViewer().repaint();
|
||||||
controller.getGraphToolbar().updateNodeType(selectedNodeType.getDisplay(), iconPath);
|
controller.getGraphToolbar().updateNodeType(selectedNodeType.getId(), iconPath);
|
||||||
Toast.info(String.format("Node %s Updated", selectedNodeType.getDisplay()));
|
Toast.info(String.format("Node %s Updated", selectedNodeType.getDisplay()));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ public class NodeTypesDialog extends StageDialog {
|
||||||
public void showDialog() {
|
public void showDialog() {
|
||||||
listView.getItems().clear();
|
listView.getItems().clear();
|
||||||
nodeTypeMap.clear();
|
nodeTypeMap.clear();
|
||||||
for (NodeType nodeType : NodeType.getNodeTypes()) {
|
for (NodeType nodeType : NodeType.getAll()) {
|
||||||
if (nodeType.getValue() != NodeType.DEFAULT) {
|
if (nodeType.getValue() != NodeType.DEFAULT) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
package com.core.ui;
|
package com.core.ui;
|
||||||
|
|
||||||
import com.core.Controller;
|
import com.core.Controller;
|
||||||
import com.core.data.SessionState;
|
|
||||||
import com.core.client.rest.GetSessions;
|
import com.core.client.rest.GetSessions;
|
||||||
import com.core.client.rest.GetSessionsData;
|
import com.core.client.rest.GetSessionsData;
|
||||||
|
import com.core.data.SessionState;
|
||||||
import com.jfoenix.controls.JFXButton;
|
import com.jfoenix.controls.JFXButton;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.control.TableColumn;
|
import javafx.scene.control.TableColumn;
|
||||||
|
@ -43,7 +43,7 @@ public class SessionsDialog extends StageDialog {
|
||||||
try {
|
try {
|
||||||
getCoreClient().joinSession(row.getId(), true);
|
getCoreClient().joinSession(row.getId(), true);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
logger.error("error joining session: {}", row.getId());
|
Toast.error(String.format("error joining session: %s", row.getId()), ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
close();
|
close();
|
||||||
|
|
|
@ -108,6 +108,9 @@ def get_session(session_id):
|
||||||
nodes = []
|
nodes = []
|
||||||
links = []
|
links = []
|
||||||
for node in session.objects.itervalues():
|
for node in session.objects.itervalues():
|
||||||
|
if not isinstance(node.objid, int):
|
||||||
|
continue
|
||||||
|
|
||||||
emane_model = None
|
emane_model = None
|
||||||
if nodeutils.is_node(node, NodeTypes.EMANE):
|
if nodeutils.is_node(node, NodeTypes.EMANE):
|
||||||
emane_model = node.model.name
|
emane_model = node.model.name
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue