OAM-447 Align Cell generation in ietf-topo with geo.json 84/14284/1
authorMartin Skorupski <martin.skorupski@highstreet-technologies.com>
Thu, 27 Mar 2025 11:13:49 +0000 (12:13 +0100)
committerMartin Skorupski <martin.skorupski@highstreet-technologies.com>
Thu, 27 Mar 2025 11:13:49 +0000 (12:13 +0100)
- 3 smaller topos added to config
- convert NRCellDUs to TerminationPoints

Issue-ID: OAM-447
Change-Id: I247a91c6b3d6a5d75646e032e9ed63c052afe01c
Signed-off-by: Martin Skorupski <martin.skorupski@highstreet-technologies.com>
code/network-generator/configurations/configA00011.json [new file with mode: 0644]
code/network-generator/configurations/configB00011.json [new file with mode: 0644]
code/network-generator/configurations/configC00011.json [new file with mode: 0644]
code/network-generator/network_generation/model/python/nr_cell_du.py
code/network-generator/network_generation/model/python/o_ran_ru.py

diff --git a/code/network-generator/configurations/configA00011.json b/code/network-generator/configurations/configA00011.json
new file mode 100644 (file)
index 0000000..e7a7743
--- /dev/null
@@ -0,0 +1,80 @@
+{
+  "network": {
+    "name": "O-RAN-Network-Operator-A-small",
+    "host": "to-be-replaced-by-host-fqdn",
+    "version":"v0.0.2",
+    "operationalState": "enabled",
+    "center": {
+      "latitude": 40.545,
+      "longitude": -74.447,
+      "aboveMeanSeaLevel": 51
+    },
+    "disabledResourcesProfile": {
+      "o-ran-sc-network:smo": 0,
+      "o-ran-sc-network:o-cloud": 0,
+      "o-ran-sc-network:tower": 0,
+      "o-ran-sc-network:near-rt-ric": 0,
+      "o-ran-common-identity-refs:o-cu-function": 0,
+      "o-ran-common-identity-refs:o-du-function": 0,
+      "o-ran-common-identity-refs:o-ru-function": 15,
+      "o-ran-sc-network:cell": 0
+    },
+    "pattern": {
+      "tower": {
+        "representation": "hexagon"
+      },
+      "smo": {
+        "fiveGCoreCount": 1,
+        "nearRtRicSpiralRadius": 0,
+        "oCloudResourcePoolCount": 1
+      },
+      "nearRtRic": {
+        "oRanCuSpiralRadius":0
+      },
+      "oRanCu": {
+        "oRanDuSpiralRadius": 0
+      },
+      "oRanDu": {
+        "fronthaulGatewayCount": 0,
+        "towerSpiralRadius": 1,
+        "oRanRuCount": 1
+      },
+      "oRanRu": {
+        "nrCellDuCount": 1
+      },
+      "nrCellDu": {
+        "sectorCount": 1,
+        "cellAngle": 120,
+        "cellScaleFactorForHandoverArea": 20,
+        "maxReach": 400
+      }
+    }
+  },
+  "outputFolder": "output",
+  "generationTasks": {
+    "day0Config": {
+      "enabled": false,
+      "compressed": false
+    },
+    "rfc8345": {
+      "enabled": true,
+      "compressed": false
+    },
+    "svg": {
+      "enabled": false,
+      "compressed": false
+    },
+    "kml": {
+      "enabled": true,
+      "compressed": true
+    },
+    "rfc7946": {
+      "enabled": true,
+      "compressed": false
+    },
+    "teiv": {
+      "enabled": false,
+      "compressed": false
+    }
+  }
+}
\ No newline at end of file
diff --git a/code/network-generator/configurations/configB00011.json b/code/network-generator/configurations/configB00011.json
new file mode 100644 (file)
index 0000000..1257e75
--- /dev/null
@@ -0,0 +1,80 @@
+{
+  "network": {
+    "name": "O-RAN-Network-Operator-B-small",
+    "host": "to-be-replaced-by-host-fqdn",
+    "version":"v0.0.2",
+    "operationalState": "enabled",
+    "center": {
+      "latitude": 40.535,
+      "longitude": -74.457,
+      "aboveMeanSeaLevel": 52
+    },
+    "disabledResourcesProfile": {
+      "o-ran-sc-network:smo": 0,
+      "o-ran-sc-network:o-cloud": 0,
+      "o-ran-sc-network:tower": 0,
+      "o-ran-sc-network:near-rt-ric": 0,
+      "o-ran-common-identity-refs:o-cu-function": 0,
+      "o-ran-common-identity-refs:o-du-function": 0,
+      "o-ran-common-identity-refs:o-ru-function": 25,
+      "o-ran-sc-network:cell": 0
+    },
+    "pattern": {
+      "tower": {
+        "representation": "hexagon"
+      },
+      "smo": {
+        "fiveGCoreCount": 1,
+        "nearRtRicSpiralRadius": 0,
+        "oCloudResourcePoolCount": 1
+      },
+      "nearRtRic": {
+        "oRanCuSpiralRadius":0
+      },
+      "oRanCu": {
+        "oRanDuSpiralRadius": 0
+      },
+      "oRanDu": {
+        "fronthaulGatewayCount": 0,
+        "towerSpiralRadius": 1,
+        "oRanRuCount": 1
+      },
+      "oRanRu": {
+        "nrCellDuCount": 1
+      },
+      "nrCellDu": {
+        "sectorCount": 1,
+        "cellAngle": 120,
+        "cellScaleFactorForHandoverArea": 20,
+        "maxReach": 400
+      }
+    }
+  },
+  "outputFolder": "output",
+  "generationTasks": {
+    "day0Config": {
+      "enabled": false,
+      "compressed": false
+    },
+    "rfc8345": {
+      "enabled": true,
+      "compressed": false
+    },
+    "svg": {
+      "enabled": false,
+      "compressed": false
+    },
+    "kml": {
+      "enabled": true,
+      "compressed": true
+    },
+    "rfc7946": {
+      "enabled": true,
+      "compressed": false
+    },
+    "teiv": {
+      "enabled": false,
+      "compressed": false
+    }
+  }
+}
\ No newline at end of file
diff --git a/code/network-generator/configurations/configC00011.json b/code/network-generator/configurations/configC00011.json
new file mode 100644 (file)
index 0000000..d65bb41
--- /dev/null
@@ -0,0 +1,80 @@
+{
+  "network": {
+    "name": "O-RAN-Network-Operator-C-small",
+    "host": "to-be-replaced-by-host-fqdn",
+    "version":"v0.0.2",
+    "operationalState": "enabled",
+    "center": {
+      "latitude": 40.535,
+      "longitude": -74.447,
+      "aboveMeanSeaLevel": 53
+    },
+    "disabledResourcesProfile": {
+      "o-ran-sc-network:smo": 0,
+      "o-ran-sc-network:o-cloud": 0,
+      "o-ran-sc-network:tower": 0,
+      "o-ran-sc-network:near-rt-ric": 0,
+      "o-ran-common-identity-refs:o-cu-function": 0,
+      "o-ran-common-identity-refs:o-du-function": 0,
+      "o-ran-common-identity-refs:o-ru-function": 20,
+      "o-ran-sc-network:cell": 0
+    },
+    "pattern": {
+      "tower": {
+        "representation": "hexagon"
+      },
+      "smo": {
+        "fiveGCoreCount": 1,
+        "nearRtRicSpiralRadius": 0,
+        "oCloudResourcePoolCount": 1
+      },
+      "nearRtRic": {
+        "oRanCuSpiralRadius": 0
+      },
+      "oRanCu": {
+        "oRanDuSpiralRadius": 0
+      },
+      "oRanDu": {
+        "fronthaulGatewayCount": 0,
+        "towerSpiralRadius": 1,
+        "oRanRuCount": 1
+      },
+      "oRanRu": {
+        "nrCellDuCount": 1
+      },
+      "nrCellDu": {
+        "sectorCount": 1,
+        "cellAngle": 120,
+        "cellScaleFactorForHandoverArea": 20,
+        "maxReach": 400
+      }
+    }
+  },
+  "outputFolder": "output",
+  "generationTasks": {
+    "day0Config": {
+      "enabled": false,
+      "compressed": false
+    },
+    "rfc8345": {
+      "enabled": true,
+      "compressed": false
+    },
+    "svg": {
+      "enabled": false,
+      "compressed": false
+    },
+    "kml": {
+      "enabled": true,
+      "compressed": true
+    },
+    "rfc7946": {
+      "enabled": true,
+      "compressed": false
+    },
+    "teiv": {
+      "enabled": false,
+      "compressed": false
+    }
+  }
+}
\ No newline at end of file
index fc7900e..01c866e 100644 (file)
@@ -28,6 +28,9 @@ from network_generation.model.python.geo_location import (
 )
 from network_generation.model.python.o_ran_node import IORanNode, ORanNode
 from network_generation.model.python.point import Point
+from network_generation.model.python.o_ran_termination_point import (
+    ORanTerminationPoint,
+)
 
 
 # Define the "INrCellDu" interface
@@ -55,8 +58,6 @@ default_value: INrCellDu = cast(
 # Define an abstract O-RAN Node class
 class NrCellDu(ORanNode):
 
-    _interfaces = ["cell"]
-
     def __init__(
         self,
         data: dict[str, Any] = cast(dict[str, Any], default_value),
@@ -64,6 +65,7 @@ class NrCellDu(ORanNode):
     ) -> None:
         cell_data: INrCellDu = self._to_cell_data(data)
         super().__init__(cast(dict[str, Any], cell_data), **kwargs)
+        self.type = "o-ran-sc-network:cell"
         self._cell_angle: int = int(str(cell_data["cellAngle"]))
         self._cell_scale_factor: int = int(
             str(cell_data["cellScaleFactorForHandoverArea"])
@@ -224,6 +226,15 @@ class NrCellDu(ORanNode):
     def get_geojson_href(self) -> str:
         return f"https://{self.network.host}/area/o-ran-network.geo.json/features?properties.name={self.name}"
 
+    def to_termination_point(self) -> ORanTerminationPoint:
+        tp = ORanTerminationPoint({
+            "name": self.name,
+            "type": self.type,
+            "operationalState": self.operationalState,
+            "network": self.network
+        })
+        return tp
+
     def to_geojson_feature(self) -> list[dict[str, Any]]:
         cell_polygon: list[GeoLocation] = self.get_cell_polygons()
         coordinates: list = []
@@ -237,7 +248,7 @@ class NrCellDu(ORanNode):
                     "type": "PropertiesOdu",
                     "name": self.name,
                     "uuid": self.id,
-                    "function": "o-ran-sc-network:cell",
+                    "function": self.type,
                     "newRadioCellGlobalIdentity": {
                         "publicLandMobileNetworkIdentifier": "123-45",
                         "newRadioCellIdentity": "0x0FFFFFFFFF",
index 944b574..a49aecf 100644 (file)
@@ -46,7 +46,7 @@ default_value: IORanRu = cast(
 # Define an abstract O-RAN Node class
 class ORanRu(ORanNode):
 
-    _interfaces = ["ofhc", "ofhu", "ofhs", "ofhm", "cell"]
+    _interfaces = ["ofhc", "ofhu", "ofhs", "ofhm"]
 
     def __init__(
         self,
@@ -104,7 +104,7 @@ class ORanRu(ORanNode):
         for index in range(self._cell_count):
             s: str = "00" + str(index)
             name: str = "-".join(
-                [self.name.replace("RU", "NRCellDu"), s[len(s) - 2: len(s)]]
+                [self.name, s[len(s) - 2: len(s)], "CELL"]
             )
             azimuth: int = index * cell_angle + self._ru_azimuth
             result.append(
@@ -135,17 +135,24 @@ class ORanRu(ORanNode):
         return self._oRanDu
 
     def to_topology_nodes(self) -> list[dict[str, Any]]:
+        # cells should be interpreted as termination points
+        for cell in self.cells:
+            cell_tp = cell.to_termination_point()
+            self.termination_points().append(cell_tp)
         result: list[dict[str, Any]] = super().to_topology_nodes()
         result.extend(self.oRanDu.to_topology_nodes())
         return result
 
+    def to_tmf686_vertex(self) -> list[dict[str, Any]]:
+        result: list[dict[str, Any]] = super().to_tmf686_vertex()
+        result.extend(self.oRanDu.to_tmf686_vertex())
+        return result
+
     def to_topology_links(self) -> list[dict[str, Any]]:
         result: list[dict[str, Any]] = super().to_topology_links()
         result.extend(self.oRanDu.to_topology_links())
         for interface in ["phy", "ofhm", "ofhc", "ofhu", "ofhs"]:
-            link_id: str = "".join(
-                [interface, ":", self.name, "<->", self.oRanDu.name]
-            )
+            link_id: str = "".join([interface, ":", self.name, "<->", self.oRanDu.name])
             source_tp: str = "-".join([self.name, interface.upper()])
             dest_tp: str = "-".join([self.oRanDu.name, interface.upper()])
             result.append(
@@ -191,8 +198,7 @@ class ORanRu(ORanNode):
         """
         Helper method to extend results with references from cells.
 
-        :param super_method: The superclass method to call for the initial
-                             result.
+        :param super_method: The superclass method to call for the initial result.
         :param cell_method_name: The method name to call on each cell.
         :return: A list of dictionaries with the combined results.
         """
@@ -312,6 +318,50 @@ class ORanRu(ORanNode):
             )
         return result
 
+    def toKml(self) -> ET.Element:
+        o_ran_ru: ET.Element = ET.Element("Folder")
+        open: ET.Element = ET.SubElement(o_ran_ru, "open")
+        open.text = "1"
+        name: ET.Element = ET.SubElement(o_ran_ru, "name")
+        name.text = self.name
+        for cell in self.cells:
+            o_ran_ru.append(cell.toKml())
+        return o_ran_ru
+
+    def toSvg(self) -> ET.Element:
+        return ET.Element("to-be-implemented")
+
+    def to_directory(self, parent_dir: str) -> None:
+        self.oRanDu.to_directory(parent_dir)
+        parent_path = os.path.join(parent_dir, self.type)
+        path = os.path.join(parent_path, self.name)
+        if not os.path.exists(parent_path):
+            os.makedirs(parent_path, exist_ok=True)
+        if not os.path.exists(path):
+            os.mkdir(path)
+
+    def _extend_with_cell_references(
+        self: Any, super_method: Any, cell_method_name: str
+    ) -> list[dict[str, Any]]:
+        """
+        Helper method to extend results with references from cells.
+
+        :param super_method: The superclass method to call for the initial result.
+        :param cell_method_name: The method name to call on each cell.
+        :return: A list of dictionaries with the combined results.
+        """
+        result = super_method()
+        result.extend(getattr(self.oRanDu, cell_method_name)())
+        for cell in self.cells:
+            result.extend(self.flatten_list(getattr(cell, cell_method_name)()))
+        return result
+
+    def to_geojson_feature(self) -> list[dict[str, Any]]:
+        return self._extend_with_cell_references(
+            super().to_geojson_feature,
+            "to_geojson_feature",
+        )
+
     def to_tmf633_service_candidate_references(self) -> list[dict[str, Any]]:
         return self._extend_with_cell_references(
             super().to_tmf633_service_candidate_references,