Reformat files according to template
[oam.git] / code / network-generator / network_generation / model / python / tower.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 """
18 A Class representing a Tower to mount O-RAN RUs
19 It can be interpreted as 'resource pool' for physical network
20 functions.
21 """
22 import xml.etree.ElementTree as ET
23 from typing import overload
24
25 from network_generation.model.python.o_ran_node import ORanNode
26 from network_generation.model.python.o_ran_object import IORanObject
27 from network_generation.model.python.o_ran_ru import ORanRu
28 from network_generation.model.python.o_ran_termination_point import (
29     ORanTerminationPoint,
30 )
31
32
33 # Define the "IORanDu" interface
34 class ITower(IORanObject):
35     def __init__(self, o_ran_ru_count: int, **kwargs):
36         super().__init__(**kwargs)
37         self._o_ran_ru_count = o_ran_ru_count
38
39
40 # Implement a concrete O-RAN Node class
41 class Tower(ORanNode):
42     def __init__(self, tower_data: ITower = None, **kwargs):
43         super().__init__(tower_data, **kwargs)
44         self._o_ran_ru_count = (
45             tower_data["oRanRuCount"]
46             if tower_data and "oRanRuCount" in tower_data
47             else 3
48         )
49         self._o_ran_rus: list[ORanRu] = self._create_o_ran_rus()
50
51     def _create_o_ran_rus(self) -> list[ORanRu]:
52         result: list[ORanRu] = []
53         for index in range(self._o_ran_ru_count):
54             s: str = "00" + str(index)
55             name: str = "-".join(
56                 [self.name.replace("Tower", "RU"), s[len(s) - 2 : len(s)]]
57             )
58             cell_count: int = (
59                 self.parent.parent.parent.parent.parent.configuration()[
60                     "pattern"
61                 ]["o-ran-ru"]["nr-cell-du-count"]
62             )
63             cell_angle: int = (
64                 self.parent.parent.parent.parent.parent.configuration()[
65                     "pattern"
66                 ]["nr-cell-du"]["cell-angle"]
67             )
68             ru_angle: int = cell_count * cell_angle
69             ru_azimuth: int = index * ru_angle
70             result.append(
71                 ORanRu(
72                     {
73                         "name": name,
74                         "geoLocation": self.geoLocation,
75                         "position": self.position,
76                         "layout": self.layout,
77                         "spiralRadiusProfile": self.spiralRadiusProfile,
78                         "parent": self,
79                         "cellCount": cell_count,
80                         "ruAngle": ru_angle,
81                         "ruAzimuth": ru_azimuth,
82                     }
83                 )
84             )
85         return result
86
87     @property
88     def o_ran_rus(self) -> list[ORanRu]:
89         return self._o_ran_rus
90
91     @property
92     def termination_points(self) -> list[ORanTerminationPoint]:
93         result: list[ORanTerminationPoint] = super().termination_points
94         phy_tp: str = "-".join([self.name, "phy".upper()])
95         result.append({"tp-id": phy_tp})
96         for interface in ["e2", "o1", "ofhm", "ofhc", "ofhu", "ofhs"]:
97             result.append(
98                 {
99                     "tp-id": "-".join([self.name, interface.upper()]),
100                     "supporting-termination-point": [
101                         {
102                             "network-ref": type(
103                                 self.parent.parent.parent.parent
104                             ),
105                             "node-ref": self.name,
106                             "tp-ref": phy_tp,
107                         }
108                     ],
109                 }
110             )
111         return result
112
113     def to_topology_nodes(self) -> list[dict[str, dict]]:
114         result: list[dict[str, dict]] = super().to_topology_nodes()
115         for o_ran_ru in self.o_ran_rus:
116             result.extend(o_ran_ru.to_topology_nodes())
117         return result
118
119     def to_topology_links(self) -> list[dict[str, dict]]:
120         result: list[dict[str, dict]] = super().to_topology_links()
121         for o_ran_ru in self.o_ran_rus:
122             result.extend(o_ran_ru.to_topology_links())
123         return result
124
125     def toKml(self) -> ET.Element:
126         tower: ET.Element = ET.Element("Folder")
127         open: ET.Element = ET.SubElement(tower, "open")
128         open.text = "1"
129         name: ET.Element = ET.SubElement(tower, "name")
130         name.text = self.name
131         for o_ran_ru in self.o_ran_rus:
132             tower.append(o_ran_ru.toKml())
133         return tower
134
135     def toSvg(self) -> None:
136         return None