Add to_directory method to relevant object classes
[oam.git] / code / network-generator / network_generation / model / python / o_ran_network.py
index bb39b61..901e83f 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/usr/bin/python
+# !/usr/bin/python
 """
 Module for a class representing a O-RAN Network
 """
 import xml.etree.ElementTree as ET
+import os
+from typing import Any, cast
 
 import network_generation.model.python.hexagon as Hexagon
+from network_generation.model.python.geo_location import (
+    GeoLocation,
+    IGeoLocation,
+)
 from network_generation.model.python.hexagon import Layout
 from network_generation.model.python.o_ran_object import (
     IORanObject,
@@ -30,38 +36,62 @@ from network_generation.model.python.o_ran_spiral_radius_profile import (
 )
 from network_generation.model.python.point import Point
 
+# Define the "IORanNetwork" interface
+IORanNetwork = IORanObject
+
 
 class ORanNetwork(ORanObject):
     """
     Class representing an O-RAN Network object.
     """
 
+    __my_default_value: IORanNetwork = cast(IORanNetwork, ORanObject.default())
+
     # constructor
     def __init__(
-        self, configuration: dict[str, dict], of: IORanObject = None, **kwargs
-    ):
-        super().__init__(of, **kwargs)
+        self,
+        configuration: dict[str, dict],
+        data: dict[str, Any] = cast(dict[str, Any], __my_default_value),
+        **kwargs: dict[str, Any]
+    ) -> None:
+        o_ran_network_data: IORanNetwork = self._to_o_ran_network_data(data)
+        super().__init__(cast(dict[str, Any], o_ran_network_data), **kwargs)
         self.__configuration = configuration
-        self.name = configuration["name"]
-        self.center = configuration["center"]
-        size = configuration["pattern"]["nr-cell-du"]["max-reach"]
+
+        self.name = str(configuration["name"])
+        self._center: IGeoLocation = cast(
+            IGeoLocation, configuration["center"]
+        )
+
+        size: int = int(
+            int(configuration["pattern"]["nrCellDu"]["maxReach"])
+            / (
+                1
+                + int(
+                    configuration["pattern"]["nrCellDu"][
+                        "cellScaleFactorForHandoverArea"
+                    ]
+                )
+                / 100
+            )
+        )
         layout = Layout(
             Hexagon.layout_flat, Point(size, size), Point(0, 0)
         )  # 1 pixel = 1 meter
-        spiral_radius_profile = SpiralRadiusProfile(
+        self._spiral_radius_profile: SpiralRadiusProfile = SpiralRadiusProfile(
             {
                 "oRanSmoSpiralRadiusOfNearRtRics": configuration["pattern"][
                     "smo"
-                ]["near-rt-ric-spiral-radius"],
+                ]["nearRtRicSpiralRadius"],
                 "oRanNearRtRicSpiralRadiusOfOCus": configuration["pattern"][
-                    "near-rt-ric"
-                ]["o-ran-cu-spiral-radius"],
+                    "nearRtRic"
+                ]["oRanCuSpiralRadius"],
                 "oRanCuSpiralRadiusOfODus": configuration["pattern"][
-                    "o-ran-cu"
-                ]["o-ran-du-spiral-radius"],
+                    "oRanCu"
+                ]["oRanDuSpiralRadius"],
                 "oRanDuSpiralRadiusOfTowers": configuration["pattern"][
-                    "o-ran-du"
-                ]["tower-spiral-radius"],
+                    "oRanDu"
+                ]["towerSpiralRadius"],
             }
         )
         self._o_ran_smo = ORanSmo(
@@ -69,22 +99,44 @@ class ORanNetwork(ORanObject):
                 "name": "O-RAN-SMO",
                 "geoLocation": self.center,
                 "layout": layout,
-                "spiralRadiusProfile": spiral_radius_profile,
                 "parent": self,
             }
         )
 
-    # getter
-    def configuration(self) -> dict[str, dict]:
+    def _to_o_ran_network_data(self, data: dict[str, Any]) -> IORanNetwork:
+        result: IORanNetwork = self.__my_default_value
+        for key, key_type in IORanNetwork.__annotations__.items():
+            if key in data:
+                result[key] = data[key]  # type: ignore
+        return result
+
+    @property
+    def center(self) -> GeoLocation:
+        """
+        Getter for a json object representing the O-RAN Network.
+        :return O-RAN Network as json object.
+        """
+        return GeoLocation(self._center)
+
+    @property
+    def spiral_radius_profile(self) -> SpiralRadiusProfile:
+        """
+        Getter for a json object representing the SpiralRadiusProfile.
+        :return SpiralRadiusProfile.
+        """
+        return self._spiral_radius_profile
+
+    @property
+    def configuration(self) -> dict[str, Any]:
         """
         Getter for a json object representing the O-RAN Network.
         :return O-RAN Network as json object.
         """
         return self.__configuration
 
-    def to_topology(self) -> dict[str, dict]:
-        nodes: dict[str, dict] = self._o_ran_smo.to_topology_nodes()
-        links: dict[str, dict] = self._o_ran_smo.to_topology_links()
+    def to_topology(self) -> dict[str, Any]:
+        nodes: list[dict[str, Any]] = self._o_ran_smo.to_topology_nodes()
+        links: list[dict[str, Any]] = self._o_ran_smo.to_topology_links()
         return {
             "ietf-network:networks": {
                 "network": [
@@ -97,6 +149,9 @@ class ORanNetwork(ORanObject):
             }
         }
 
+    def to_directory(self, parent_dir: str) -> None:
+        self._o_ran_smo.to_directory(os.path.join(parent_dir, self.id))
+
     def toKml(self) -> ET.Element:
         root: ET.Element = ET.Element(
             "kml", xmlns="http://www.opengis.net/kml/2.2"
@@ -129,12 +184,15 @@ class ORanNetwork(ORanObject):
             xmlns="http://www.w3.org/2000/svg",
         )
         desc = ET.Element("desc")
-        # desc.text="\n context: " + str(self.id()) + "\n name: " + str(self.name())
+        desc.text = "\n context: " + self.id + "\n name: " + self.name
         root.append(desc)
 
         title = ET.Element("title")
-        title.text = self.configuration()["name"]
+        title.text = str(self.configuration["name"])
         root.append(title)
 
         # root.append(self.__context.svg(x, y))
         return root
+
+    def json(self) -> dict[str, Any]:
+        return super().json()