A collection of TypeDefinitions for a geographical location
"""
import math
-from model.python.hexagon import Point
+from model.python.point import Point
class IGeoLocationData:
self.longitude = longitude
self.aboveMeanSeaLevel = aboveMeanSeaLevel
- def __str__(self):
+ def __str__(self)-> str:
return f'lat : {self.latitude} : lon : {self.longitude} : amsl : {self.aboveMeanSeaLevel}'
)
@property
- def equatorialRadius(self):
+ def equatorialRadius(self) -> int:
return GeoLocation._equatorialRadius
@property
- def polarRadius(self):
+ def polarRadius(self)-> int:
return GeoLocation._polarRadius
def set_latitude(self, value: float):
raise ValueError('Invalid longitude. Longitude must be between -180 and 180.')
self.longitude = value
- def json(self):
+ def json(self) -> dict[str, float]:
return {
"latitude": self.latitude,
"longitude": self.longitude,
"aboveMeanSeaLevel": self.aboveMeanSeaLevel,
}
- def __str__(self):
+ def __str__(self) -> str:
return str(self.json())
def point_to_geo_location(self, point:Point):
from model.python.o_ran_node import ORanNode
import xml.etree.ElementTree as ET
+
# Define the "INrCellDu" interface
class INrCellDu(IORanObject):
def __init__(self, **kwargs):
def __init__(self, o_ran_smo_data: INrCellDu = None, **kwargs):
super().__init__(o_ran_smo_data, **kwargs)
- def toKml(self):
+ def toKml(self) -> None:
return None
- def toSvg(self):
+ def toSvg(self) -> None:
return None
from model.python.o_ran_node import ORanNode
import xml.etree.ElementTree as ET
+
# Define the "IORanCu" interface
class IORanCu(IORanObject):
def __init__(self, **kwargs):
class ORanCu(ORanNode, IORanCu):
def __init__(self, o_ran_cu_data: IORanCu = None, **kwargs):
super().__init__(o_ran_cu_data, **kwargs)
- self._o_ran_dus: list(ORanCu) = self._calculate_o_ran_dus()
+ self._o_ran_dus: list[ORanCu] = self._calculate_o_ran_dus()
- def _calculate_o_ran_dus(self):
+ def _calculate_o_ran_dus(self) -> list[ORanDu]:
hex_ring_radius: int = self.spiralRadiusProfile.oRanCuSpiralRadiusOfODus
index: int = 0
s: str = "00" + str(index)
name: str = "O-RAN-DU-" + s[len(s) - 2 : len(s)]
- result: list(ORanDu) = []
+ result: list[ORanDu] = []
result.append(
ORanDu(
{
"position": self.position,
"layout": self.layout,
"spiralRadiusProfile": self.spiralRadiusProfile,
- "parent": self
+ "parent": self,
}
)
)
return result
-
+
@property
- def o_ran_dus(self):
+ def o_ran_dus(self) -> list[ORanDu]:
return self._o_ran_dus
@property
- def towers(self):
- result: list(Tower) = []
+ def towers(self) -> list[Tower]:
+ result: list[Tower] = []
for du in self.o_ran_dus:
for tower in du.towers:
result.append(tower)
return result
- def toKml(self):
+ def toKml(self) -> None:
return None
- def toSvg(self):
+ def toSvg(self) -> None:
return None
super().__init__(o_ran_near_rt_ric_data, **kwargs)
self._o_ran_cus: list(ORanCu) = self._calculate_o_ran_cus()
- def _calculate_o_ran_cus(self):
+ def _calculate_o_ran_cus(self) -> list[ORanCu]:
hex_ring_radius: int = self.spiralRadiusProfile.oRanNearRtRicSpiralRadiusOfOCus
index: int = 0
s: str = "00" + str(index)
name: str = "O-RAN-CU-" + s[len(s) - 2 : len(s)]
- result: list(ORanCu) = []
+ result: list[ORanCu] = []
result.append(
ORanCu(
{
return result
@property
- def o_ran_cus(self):
+ def o_ran_cus(self) -> list[ORanCu]:
return self._o_ran_cus
@property
- def towers(self):
- result: list(Tower) = []
+ def towers(self) -> list[Tower]:
+ result: list[Tower] = []
for cu in self.o_ran_cus:
for tower in cu.towers:
result.append(tower)
return result
- def toKml(self):
+ def toKml(self) -> None:
return None
- def toSvg(self):
+ def toSvg(self) -> None:
return None
"""
Module for a class representing a O-RAN Network
"""
-from typing import Any, Dict, List
+from typing import Any
from model.python.o_ran_smo import ORanSmo
from model.python.o_ran_spiral_radius_profile import SpiralRadiusProfile
-from model.python.tower import Tower
from model.python.o_ran_object import IORanObject, ORanObject
import model.python.hexagon as Hexagon
-from model.python.hexagon import Hex, Layout, Point
+from model.python.hexagon import Layout
+from model.python.point import Point
import xml.etree.ElementTree as ET
"""
# constructor
- def __init__(self, configuration: Dict[str, Any], of: IORanObject = None, **kwargs):
+ def __init__(self, configuration: dict[str, Any], of: IORanObject = None, **kwargs):
super().__init__(of, **kwargs)
self.__configuration = configuration
self.name = configuration["name"]
- center = configuration["center"]
+ self.center = configuration["center"]
size = configuration["pattern"]["o-ran-ru"]["max-reach"]
layout = Layout(
Hexagon.layout_flat, Point(size, size), Point(0, 0)
self._o_ran_smo = ORanSmo(
{
"name": "SMO",
- "geoLocation": center,
+ "geoLocation": self.center,
"layout": layout,
"spiralRadiusProfile": spiral_radius_profile,
"parent": self,
)
# getter
- def configuration(self) -> Dict[str, Dict]:
+ def configuration(self) -> dict[str, dict]:
"""
Getter for a json object representing the O-RAN Network.
:return O-RAN Network as json object.
"""
return self.__configuration
- def __appendNodes(self):
- result: List[Dict[str, Any]] = []
+ def __appendNodes(self) -> list[dict[str, Any]]:
+ result: list[dict[str, Any]] = []
for tower in self._o_ran_smo.towers:
result.append(tower.toTopology())
return result
- def toTopology(self):
+ def toTopology(self) -> dict[str, Any]:
return {
"ietf-network:networks": {
"network": [
}
}
- def toKml(self):
+ def toKml(self) -> ET.Element:
root: ET.Element = ET.Element("kml", xmlns="http://www.opengis.net/kml/2.2")
document = ET.SubElement(root, "Document")
open = ET.SubElement(document, "open")
return root
- def toSvg(self):
+ def toSvg(self) -> ET.Element:
"""
Getter for a xml/svg Element object representing the Network.
:return Network as SVG object.
"""
- root: Element = ET.Element(
+ root: ET.Element = ET.Element(
"svg",
# width=str(self.__svg_width()),
# height=str(self.__svg_height()),
An abstract Class for O-RAN Node
"""
from abc import abstractmethod
-from typing import Any, Dict
-
+from typing import Any
+import xml.etree.ElementTree as ET
from model.python.geo_location import GeoLocation
from model.python.o_ran_object import IORanObject, ORanObject
import model.python.hexagon as Hexagon
-from model.python.hexagon import Hex, Layout, Point
+from model.python.hexagon import Hex, Layout
+from model.python.point import Point
from model.python.o_ran_spiral_radius_profile import SpiralRadiusProfile
+from model.python.o_ran_termination_point import ORanTerminationPoint
from model.python.type_definitions import (
AddressType,
)
position: Hex = None,
layout: Layout = None,
spiralRadiusProfile: SpiralRadiusProfile = None,
- parent = None,
+ parent=None,
**kwargs
):
super().__init__(**kwargs)
self.url = url
self.position = position
self.layout = layout
- self.spiralRadiusProfile = spiralRadiusProfile,
- self.parent = parent
+ self.spiralRadiusProfile = (spiralRadiusProfile,)
+ self.parent = parent
+
# Define an abstract O-RAN Node class
class ORanNode(ORanObject, IORanNode):
of["geoLocation"] if of and "geoLocation" in of else GeoLocation()
)
self.url = of["url"] if of and "url" in of else self.id
- self.position = of["position"] if of and "position" in of else Hex(0,0,0)
- self.layout = of["layout"] if of and "layout" in of else Layout(Hexagon.layout_flat, Point(1,1), Point(0,0))
- self.spiralRadiusProfile = of["spiralRadiusProfile"] if of and "spiralRadiusProfile" in of else SpiralRadiusProfile()
+ self.position = of["position"] if of and "position" in of else Hex(0, 0, 0)
+ self.layout = (
+ of["layout"]
+ if of and "layout" in of
+ else Layout(Hexagon.layout_flat, Point(1, 1), Point(0, 0))
+ )
+ self.spiralRadiusProfile = (
+ of["spiralRadiusProfile"]
+ if of and "spiralRadiusProfile" in of
+ else SpiralRadiusProfile()
+ )
self.parent = of["parent"] if of and "parent" in of else None
self._terminationPoints = []
@property
- def address(self):
+ def address(self) -> str:
return self._address
@address.setter
- def address(self, value):
+ def address(self, value: str):
self._address = value
@property
- def geoLocation(self):
+ def geoLocation(self) -> GeoLocation:
return self._geographicalLocation
@geoLocation.setter
- def geoLocation(self, value):
+ def geoLocation(self, value: GeoLocation):
self._geographicalLocation = value
@property
- def url(self):
+ def url(self) -> str:
return self._url
@url.setter
- def url(self, value):
+ def url(self, value: str):
self._url = value
@property
- def position(self):
+ def position(self) -> Hex:
return self._position
@position.setter
- def position(self, value):
+ def position(self, value: Hex):
self._position = value
@property
- def layout(self):
+ def layout(self) -> Layout:
return self._layout
@layout.setter
- def layout(self, value):
+ def layout(self, value: Layout):
self._layout = value
@property
- def spiralRadiusProfile(self):
+ def spiralRadiusProfile(self) -> SpiralRadiusProfile:
return self._spiralRadiusProfile
@spiralRadiusProfile.setter
- def spiralRadiusProfile(self, value):
+ def spiralRadiusProfile(self, value: SpiralRadiusProfile):
self._spiralRadiusProfile = value
@property
- def parent(self):
+ def parent(self) -> Any: # expected are ORanNodes and all inherits for ORanNode
return self._parent
@parent.setter
- def parent(self, value):
+ def parent(self, value: Any):
self._parent = value
@property
- def terminationPoints(self):
+ def terminationPoints(self) -> list[ORanTerminationPoint]:
return self._terminationPoints
- def json(self):
- result: Dict = super().json()
+ def json(self) -> dict[str, Any]:
+ result: dict = super().json()
result["address"] = self.address
result["geoLocation"] = self.geoLocation
result["url"] = self.url
result["parent"] = self.parent
return result
- def toTopology(self):
- result:Dict[str, Any] = {
+ def toTopology(self) -> dict[str, Any]:
+ result: dict[str, Any] = {
"node-id": self.name,
- "ietf-network-topology:termination-point": self.terminationPoints
+ "ietf-network-topology:termination-point": self.terminationPoints,
}
return result
@abstractmethod
- def toKml(self):
+ def toKml(self) -> ET.Element | None:
pass
@abstractmethod
- def toSvg(self):
- pass
\ No newline at end of file
+ def toSvg(self) -> ET.Element | None:
+ pass
An abstract Class for O-RAN Objects
"""
from abc import abstractmethod
-from typing import Dict
-
+from typing import Any
from model.python.top import ITop, Top
-from model.python.geo_location import GeoLocation
# Define the "IORanObject" interface
def __init__(self, of: IORanObject = None, **kwargs):
super().__init__(**kwargs)
- def json(self):
- result: Dict = super().json()
+ def json(self) -> dict[str, Any]:
+ result: dict[str, Any] = super().json()
return result
- def __str__(self):
+ def __str__(self) -> str:
return str(self.json())
@abstractmethod
- def toTopology(self):
- pass
-
- @abstractmethod
- def toKml(self):
- pass
-
- @abstractmethod
- def toSvg(self):
+ def toTopology(self) -> dict[str, Any]:
pass
from model.python.o_ran_node import ORanNode
import xml.etree.ElementTree as ET
+
# Define the "IORanRu" interface
class IORanRu(IORanObject):
def __init__(self, **kwargs):
def __init__(self, o_ran_smo_data: IORanRu = None, **kwargs):
super().__init__(o_ran_smo_data, **kwargs)
- def toKml(self):
+ def toKml(self) -> None:
return None
- def toSvg(self):
+ def toSvg(self) -> None:
return None
class ORanSmo(ORanNode, IORanSmo):
def __init__(self, o_ran_smo_data: IORanSmo = None, **kwargs):
super().__init__(o_ran_smo_data, **kwargs)
- self._o_ran_near_rt_rics: list(ORanNearRtRic) = self._calculate_near_rt_rics()
+ self._o_ran_near_rt_rics: list[ORanNearRtRic] = self._calculate_near_rt_rics()
- def _calculate_near_rt_rics(self):
+ def _calculate_near_rt_rics(self) -> list[ORanNearRtRic]:
hex_ring_radius: int = self.spiralRadiusProfile.oRanSmoSpiralRadiusOfNearRtRics
index: int = 0
s: str = "00" + str(index)
name: str = "Ric-" + s[len(s) - 2 : len(s)]
- result: list(ORanNearRtRic) = []
+ result: list[ORanNearRtRic] = []
result.append(
ORanNearRtRic(
{
# });
@property
- def o_ran_near_rt_rics(self):
+ def o_ran_near_rt_rics(self) -> list[ORanNearRtRic]:
return self._o_ran_near_rt_rics
-
+
@property
- def towers(self):
- result: list(Tower) = []
+ def towers(self) -> list[Tower]:
+ result: list[Tower] = []
for ric in self.o_ran_near_rt_rics:
for tower in ric.towers:
result.append(tower)
return result
- def toKml(self):
+ def toKml(self) -> None:
return None
- def toSvg(self):
+ def toSvg(self) -> None:
return None
An abstract Class for O-RAN TerminationPoint
"""
from abc import abstractmethod
-from typing import Any, Dict
+from typing import Any
from model.python.o_ran_object import ORanObject
+
# Define an abstract O-RAN Node class
class ORanTerminationPoint(ORanObject):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def toTopology(self):
- result: Dict[str, Any] = {"tp-id": self.name}
+ result: dict[str, Any] = {"tp-id": self.name}
return result
-
- @abstractmethod
- def toKml(self):
- pass
-
- @abstractmethod
- def toSvg(self):
- pass
"""
import uuid
from abc import ABC, abstractmethod
-from typing import Optional, Dict, Union
+from typing import Any
from model.python.type_definitions import (
AddressType,
AdministrativeState,
# Define the Top class
class Top(ABC, ITop):
- def __init__(self, data=None):
+ def __init__(self, data: [dict[str, Any] | None] = None):
self._id = data.id if data and data.id else str(uuid.uuid4())
self._name = (
data.name if data and data.name else " ".join(["Name", "of", self._id])
if data and data.lifeCycleState
else LifeCycleState.PLANNED
)
- self._alarmState = (
- data.alarmState if data and data.alarmState else 0
- )
+ self._alarmState = data.alarmState if data and data.alarmState else 0
self._usageState = (
data.usageState if data and data.usageState else UsageState.UNUSED
)
- self._utilization = (
- data.utilization if data and data.utilization else 0
- )
+ self._utilization = data.utilization if data and data.utilization else 0
@property
- def id(self):
+ def id(self) -> str:
return self._id
@id.setter
- def id(self, value):
+ def id(self, value: str):
self._id = value
@property
- def name(self):
+ def name(self) -> str:
return self._name
@name.setter
- def name(self, value):
+ def name(self, value: str):
self._name = value
@property
- def administrativeState(self):
+ def administrativeState(self) -> AdministrativeState:
return self._administrativeState
@administrativeState.setter
- def administrativeState(self, value):
+ def administrativeState(self, value: AdministrativeState):
self._administrativeState = value
@property
- def operationalState(self):
+ def operationalState(self) -> OperationalState:
return self._operationalState
@operationalState.setter
- def operationalState(self, value):
+ def operationalState(self, value: OperationalState):
self._operationalState = value
@property
- def lifeCycleState(self):
+ def lifeCycleState(self) -> LifeCycleState:
return self._lifeCycleState
@lifeCycleState.setter
- def lifeCycleState(self, value):
+ def lifeCycleState(self, value: LifeCycleState):
self._lifeCycleState = value
@property
- def alarmState(self):
+ def alarmState(self) -> AlarmState:
return self._alarmState
@alarmState.setter
- def alarmState(self, value):
+ def alarmState(self, value: AlarmState):
self._alarmState = value
@property
- def usageState(self):
+ def usageState(self) -> UsageState:
return self._usageState
@usageState.setter
- def usageState(self, value):
+ def usageState(self, value: UsageState):
self._usageState = value
@property
- def utilization(self):
+ def utilization(self) -> Utilization:
return self._utilization
@utilization.setter
- def utilization(self, value):
+ def utilization(self, value: Utilization):
self._utilization = value
- def json(self):
+ def json(self) -> dict[str, Any]:
return {
"id": self.id,
"name": self.name,
"utilization": self.utilization,
}
- def __str__(self):
+ def __str__(self) -> str:
return str(self.json())
from enum import Enum
from model.python.countries import Country
+
# Define AdministrativeState enum
class AdministrativeState(Enum):
- LOCKED = 'locked'
- UNLOCKED = 'unlocked'
- SHUTTING_DOWN = 'shutting down'
+ LOCKED = "locked"
+ UNLOCKED = "unlocked"
+ SHUTTING_DOWN = "shutting down"
+
# Define AlarmState type
AlarmState = int
"city": str,
"zip": str,
"state": str,
- "country": Country
+ "country": Country,
}
+
# Define OperationalState enum
class OperationalState(Enum):
- ENABLED = 'enabled'
- DISABLED = 'disabled'
+ ENABLED = "enabled"
+ DISABLED = "disabled"
+
# Define LifeCycleState enum
class LifeCycleState(Enum):
- PLANNED = 'planned'
- ORDERED = 'ordered'
- INSTALLED = 'installed'
- COMMISSIONED = 'commissioned'
- TO_BE_DESTROYED = 'to be destroyed'
- DESTROYED = 'destroyed'
+ PLANNED = "planned"
+ ORDERED = "ordered"
+ INSTALLED = "installed"
+ COMMISSIONED = "commissioned"
+ TO_BE_DESTROYED = "to be destroyed"
+ DESTROYED = "destroyed"
+
# Define UsageState enum
class UsageState(Enum):
- USED = 'used'
- UNUSED = 'unused'
+ USED = "used"
+ UNUSED = "unused"
+
# Define Enumerate type
def Enumerate(N, Acc=None):
return Acc[-1]
return Enumerate(N, Acc + [len(Acc)])
+
# Define Range type
-def Range(F, T):
+def Range(F, T) -> list[int]:
return [i for i in range(F, T + 1)]
+
# Define Procent and Utilization types
Procent = Range(0, 100)
Utilization = Procent
"""
import json
-from typing import Dict
+from typing import Any
from model.python.o_ran_network import ORanNetwork
import xml.etree.ElementTree as ET
"""
This class contains all functions converting the Network into different formats
"""
+
__network: ORanNetwork = None
# constructor
# json format
- def json(self) -> 'NetworkViewer':
+ def json(self) -> "NetworkViewer":
"""
Getter returns the class as json object
:return The class itself, as it is json serializable
"""
return self
- def show_as_json(self) -> dict:
+ def show_as_json(self) -> dict[str, Any]:
"""
Method printing the class in json format.
"""
print(self.__network.json())
- def show(self):
+ def show(self) -> None:
"""
Method printing the network
"""
print(self.__network)
- def save(self, filename: str):
+ def save(self, filename: str) -> None:
"""
Method saving the class content to a file in json format.
:param filename: A valid path to a file on the system.
:type filename: string
"""
- with open(filename, "w", encoding='utf-8') as json_file:
+ with open(filename, "w", encoding="utf-8") as json_file:
output = self.__network.toTopology()
- json.dump(output, json_file,
- ensure_ascii=False, indent=2)
+ json.dump(output, json_file, ensure_ascii=False, indent=2)
print("File '" + filename + "' saved!")
def readStylesFromFile(self) -> str:
Method reading the css styles from known file
return: content of the file as string
"""
- with open('view/svg.style.css') as styles:
+ with open("view/svg.style.css") as styles:
content = styles.read()
return content
- def svg(self, filename: str):
+ def svg(self, filename: str) -> None:
"""
Method saving the class content to a file in xml/svg format.
style = ET.Element("style")
style.text = self.readStylesFromFile()
root.findall(".//desc")[0].append(style)
- ET.ElementTree(root).write(filename,
- encoding="utf-8",
- xml_declaration=True
- )
+ ET.ElementTree(root).write(filename, encoding="utf-8", xml_declaration=True)
print("File '" + filename + "' saved!")
- def kml(self, filename: str):
+ def kml(self, filename: str) -> None:
"""
Method saving the class content to a file in xml/kml format.
:type filename: string
"""
root = self.__network.toKml()
- with open('view/kml.styles.json') as kml_styles:
- styles:Dict[str,Dict] = json.load(kml_styles)
+ with open("view/kml.styles.json") as kml_styles:
+ styles: dict[str, dict] = json.load(kml_styles)
for key, value in styles.items():
# add style
- style = ET.Element("Style",{"id":key})
+ style = ET.Element("Style", {"id": key})
line_style = ET.SubElement(style, "LineStyle")
color = ET.SubElement(line_style, "color")
- color.text = value['stroke']['color']
+ color.text = value["stroke"]["color"]
width = ET.SubElement(line_style, "width")
- width.text = value['stroke']['width']
+ width.text = value["stroke"]["width"]
poly_style = ET.SubElement(style, "PolyStyle")
fill = ET.SubElement(poly_style, "color")
- fill.text = value['fill']['color']
+ fill.text = value["fill"]["color"]
root.findall(".//Document")[0].append(style)
- ET.ElementTree(root).write(filename,
- encoding="utf-8",
- xml_declaration=True
- )
+ ET.ElementTree(root).write(filename, encoding="utf-8", xml_declaration=True)
print("File '" + filename + "' saved!")