1 # Copyright 2023 highstreet technologies GmbH
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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.
18 A Class representing an O-RAN O-Cloud resource pool for O-RAN distributed units (ORanDu)
19 By default all O-RAN-DUs associated with the towers around are deployed here.
20 Maybe dedicated hardware is required to host O-DUs, but it is expected
21 that the O-Cloud mechanism and concepts can be applied here.
23 from typing import overload
24 import model.python.hexagon as Hexagon
25 from model.python.hexagon import Hex
26 from model.python.cube import Cube
27 from model.python.tower import Tower
28 from model.python.o_ran_object import IORanObject
29 from model.python.o_ran_node import ORanNode
30 from model.python.o_ran_termination_point import ORanTerminationPoint
31 import xml.etree.ElementTree as ET
34 # Define the "IORanDu" interface
35 class IORanCloudDu(IORanObject):
36 def __init__(self, **kwargs):
37 super().__init__(**kwargs)
40 # Implements a concrete O-RAN Node class
41 class ORanCloudDu(ORanNode, IORanCloudDu):
42 def __init__(self, o_ran_du_data: IORanCloudDu = None, **kwargs):
43 super().__init__(o_ran_du_data, **kwargs)
44 self._towers: list[Tower] = self._calculate_towers()
46 def _calculate_towers(self) -> list[Tower]:
47 hex_ring_radius: int = self.spiralRadiusProfile.oRanDuSpiralRadiusOfTowers
48 hex_list: list[Hex] = Cube.spiral(self.position, hex_ring_radius)
49 result: list[Tower] = []
50 for index, hex in enumerate(hex_list):
51 s: str = "00" + str(index)
53 [self.name.replace("O-Cloud-DU", "Tower"), s[len(s) - 2 : len(s)]]
55 network_center: dict = self.parent.parent.parent.parent.center
56 newGeo = Hexagon.hex_to_geo_location(
57 self.layout, hex, network_center
63 "geoLocation": newGeo,
65 "layout": self.layout,
66 "spiralRadiusProfile": self.spiralRadiusProfile,
74 def towers(self) -> list[Tower]:
78 def termination_points(self) -> list[ORanTerminationPoint]:
79 result: list[ORanTerminationPoint] = super().termination_points
80 phy_tp: str = "-".join([self.name, "phy".upper()])
81 result.append(ORanTerminationPoint({"id": phy_tp, "name": phy_tp}))
82 for interface in ["o2"]:
83 id:str = "-".join([self.name, interface.upper()])
84 result.append(ORanTerminationPoint({"id": id, "name":id, "supporter": phy_tp, "parent":self}))
87 def to_topology_nodes(self) -> list[dict[str, dict]]:
88 result: list[dict[str, dict]] = super().to_topology_nodes()
89 for tower in self.towers:
90 result.extend(tower.to_topology_nodes())
93 def to_topology_links(self) -> list[dict[str, dict]]:
94 result: list[dict[str, dict]] = super().to_topology_links()
95 for tower in self.towers:
96 result.extend(tower.to_topology_links())
99 def toKml(self) -> ET.Element:
100 o_ran_cloud_du: ET.Element = ET.Element("Folder")
101 open: ET.Element = ET.SubElement(o_ran_cloud_du, "open")
103 name: ET.Element = ET.SubElement(o_ran_cloud_du, "name")
104 name.text = self.name
105 for tower in self.towers:
106 o_ran_cloud_du.append(tower.toKml())
107 return o_ran_cloud_du
109 def toSvg(self) -> None: