3f816b3c9a712f7951859f0fac2dcfc2af995dc3
[oam.git] / code / network-generator / network_generation / model / python / o_ran_network.py
1 # Copyright 2023 highstreet technologies GmbH
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #     http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # !/usr/bin/python
16 """
17 Module for a class representing a O-RAN Network
18 """
19 import xml.etree.ElementTree as ET
20 from typing import Any, cast
21
22 import network_generation.model.python.hexagon as Hexagon
23 from network_generation.model.python.geo_location import (
24     GeoLocation,
25     IGeoLocation,
26 )
27 from network_generation.model.python.hexagon import Layout
28 from network_generation.model.python.o_ran_object import (
29     IORanObject,
30     ORanObject,
31 )
32 from network_generation.model.python.o_ran_smo import ORanSmo
33 from network_generation.model.python.o_ran_spiral_radius_profile import (
34     SpiralRadiusProfile,
35 )
36 from network_generation.model.python.point import Point
37
38 # Define the "IORanNetwork" interface
39 IORanNetwork = IORanObject
40
41
42 class ORanNetwork(ORanObject):
43     """
44     Class representing an O-RAN Network object.
45     """
46
47     __my_default_value: IORanNetwork = cast(IORanNetwork, ORanObject.default())
48
49     # constructor
50     def __init__(
51         self,
52         configuration: dict[str, dict],
53         data: dict[str, Any] = cast(dict[str, Any], __my_default_value),
54         **kwargs: dict[str, Any]
55     ) -> None:
56         o_ran_network_data: IORanNetwork = self._to_o_ran_network_data(data)
57         super().__init__(cast(dict[str, Any], o_ran_network_data), **kwargs)
58         self.__configuration = configuration
59
60         self.name = str(configuration["name"])
61         self._center: IGeoLocation = cast(
62             IGeoLocation, configuration["center"]
63         )
64
65         size: int = int(configuration["pattern"]["nr-cell-du"]["max-reach"])
66         layout = Layout(
67             Hexagon.layout_flat, Point(size, size), Point(0, 0)
68         )  # 1 pixel = 1 meter
69         self._spiral_radius_profile: SpiralRadiusProfile = SpiralRadiusProfile(
70             {
71                 "oRanSmoSpiralRadiusOfNearRtRics": configuration["pattern"][
72                     "smo"
73                 ]["near-rt-ric-spiral-radius"],
74                 "oRanNearRtRicSpiralRadiusOfOCus": configuration["pattern"][
75                     "near-rt-ric"
76                 ]["o-ran-cu-spiral-radius"],
77                 "oRanCuSpiralRadiusOfODus": configuration["pattern"][
78                     "o-ran-cu"
79                 ]["o-ran-du-spiral-radius"],
80                 "oRanDuSpiralRadiusOfTowers": configuration["pattern"][
81                     "o-ran-du"
82                 ]["tower-spiral-radius"],
83             }
84         )
85         self._o_ran_smo = ORanSmo(
86             {
87                 "name": "O-RAN-SMO",
88                 "geoLocation": self.center,
89                 "layout": layout,
90                 "parent": self,
91             }
92         )
93
94     def _to_o_ran_network_data(self, data: dict[str, Any]) -> IORanNetwork:
95         result: IORanNetwork = self.__my_default_value
96         for key, key_type in IORanNetwork.__annotations__.items():
97             if key in data:
98                 result[key] = data[key]  # type: ignore
99         return result
100
101     @property
102     def center(self) -> GeoLocation:
103         """
104         Getter for a json object representing the O-RAN Network.
105         :return O-RAN Network as json object.
106         """
107         return GeoLocation(self._center)
108
109     @property
110     def spiral_radius_profile(self) -> SpiralRadiusProfile:
111         """
112         Getter for a json object representing the SpiralRadiusProfile.
113         :return SpiralRadiusProfile.
114         """
115         return self._spiral_radius_profile
116
117     @property
118     def configuration(self) -> dict[str, Any]:
119         """
120         Getter for a json object representing the O-RAN Network.
121         :return O-RAN Network as json object.
122         """
123         return self.__configuration
124
125     def to_topology(self) -> dict[str, Any]:
126         nodes: list[dict[str, Any]] = self._o_ran_smo.to_topology_nodes()
127         links: list[dict[str, Any]] = self._o_ran_smo.to_topology_links()
128         return {
129             "ietf-network:networks": {
130                 "network": [
131                     {
132                         "network-id": self.id,
133                         "node": nodes,
134                         "ietf-network-topology:link": links,
135                     }
136                 ],
137             }
138         }
139
140     def toKml(self) -> ET.Element:
141         root: ET.Element = ET.Element(
142             "kml", xmlns="http://www.opengis.net/kml/2.2"
143         )
144         document = ET.SubElement(root, "Document")
145         open: ET.Element = ET.SubElement(document, "open")
146         open.text = "1"
147         name: ET.Element = ET.SubElement(document, "name")
148         name.text = self.name
149
150         document.append(self._o_ran_smo.toKml())
151
152         return root
153
154     def toSvg(self) -> ET.Element:
155         """
156         Getter for a xml/svg Element object representing the Network.
157         :return Network as SVG object.
158         """
159         root: ET.Element = ET.Element(
160             "svg",
161             # width=str(self.__svg_width()),
162             # height=str(self.__svg_height()),
163             # viewBox=" ".join([
164             #     str(-3*self.FONTSIZE),
165             #     str(-3*self.FONTSIZE),
166             #     str(self.__svg_width()),
167             #     str(self.__svg_height())]
168             # ),
169             xmlns="http://www.w3.org/2000/svg",
170         )
171         desc = ET.Element("desc")
172         desc.text = "\n context: " + self.id + "\n name: " + self.name
173         root.append(desc)
174
175         title = ET.Element("title")
176         title.text = str(self.configuration["name"])
177         root.append(title)
178
179         # root.append(self.__context.svg(x, y))
180         return root
181
182     def json(self) -> dict[str, Any]:
183         return super().json()