Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Buses and Equipment lists views #6

Merged
merged 14 commits into from
Nov 12, 2024
16 changes: 8 additions & 8 deletions yagat/app_context.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,6 @@ def selected_view(self, value: str) -> None:
def network(self) -> Optional[pn.Network]:
return self._network

@property
def lf_parameters(self) -> lf.Parameters:
return self._lf_parameters

@property
def network_structure(self) -> Optional[ns.NetworkStructure]:
return self._network_structure

@network.setter
def network(self, new_network: Optional[pn.Network]) -> None:
self._network = new_network
Expand All @@ -85,6 +77,14 @@ def network(self, new_network: Optional[pn.Network]) -> None:
self.selection = (None, None, None)
self.notify_network_changed()

@property
def lf_parameters(self) -> lf.Parameters:
return self._lf_parameters

@property
def network_structure(self) -> Optional[ns.NetworkStructure]:
return self._network_structure

@property
def selection(self) -> tuple[Optional[str], Optional[str], Optional[ns.Connection]]:
return self._selection
Expand Down
2 changes: 1 addition & 1 deletion yagat/frames/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
from .impl.diagram_view import DiagramView
from .impl.load_flow_parameters import LoadFlowParametersView
from .impl.main_application import MainApplication
from .impl.splash_screen import SplashScreen
from .impl.status_bar import StatusBar
from .impl.tabs_view import TabsView
from .impl.tree_and_diagram import TreeAndDiagram
from .impl.tree_view import TreeView
78 changes: 78 additions & 0 deletions yagat/frames/impl/base_list_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#
# Copyright (c) 2024, Damien Jeandemange (https://github.com/jeandemanged)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
import tkinter as tk
from abc import ABC, abstractmethod
from typing import Optional

import pandas as pd
import tksheet as tks

from yagat.app_context import AppContext
from yagat.networkstructure import Connection


class BaseListView(tk.Frame, ABC):

def __init__(self, parent, context: AppContext, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.sheet = tks.Sheet(self, index_align='left')
self.sheet.enable_bindings('single_select',
'drag_select',
'row_select',
'column_select',
'copy',
'column_width_resize',
'double_click_column_resize',
'double_click_row_resize',
'row_width_resize',
'column_height_resize',
'arrowkeys',
)
self.context = context
self.context.add_selection_changed_listener(self.on_selection_changed)

self.sheet.set_index_width(300)
self.sheet.pack(fill="both", expand=True)

@property
@abstractmethod
def tab_name(self) -> str:
pass

@abstractmethod
def get_data_frame(self) -> pd.DataFrame:
pass

@abstractmethod
def filter_data_frame(self, df: pd.DataFrame, voltage_levels: list[str]) -> pd.DataFrame:
pass

def on_selection_changed(self, selection: tuple[Optional[str], Optional[str], Optional[Connection]]):
if not self.context.network_structure:
self.sheet.data = []
return
df = self.get_data_frame()
voltage_levels = self.filtered_voltage_levels(selection)
if voltage_levels:
df = self.filter_data_frame(df, voltage_levels)
self.sheet.data = [l.tolist() for l in df.to_numpy()]
self.sheet.set_index_data(df.index.tolist())
self.sheet.set_header_data(df.columns)
self.sheet.set_all_cell_sizes_to_text()

def filtered_voltage_levels(self,
selection: tuple[Optional[str], Optional[str], Optional[Connection]]) -> list[str]:
voltage_levels: list[str] = []
if selection[0] == 'network' or not selection[0] or not selection[1]:
return voltage_levels
elif selection[0] == 'voltage_level':
voltage_levels = [selection[1]]
elif selection[0] == 'substation':
voltage_levels = [vl.voltage_level_id for vl in
self.context.network_structure.get_substation(selection[1]).voltage_levels]
return voltage_levels
48 changes: 48 additions & 0 deletions yagat/frames/impl/buses_bus_breaker_view_list_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright (c) 2024, Damien Jeandemange (https://github.com/jeandemanged)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
import os
import tkinter as tk

import pandas as pd
import pypowsybl.network as pn

from yagat.app_context import AppContext
from yagat.frames.impl.base_list_view import BaseListView


class BusesBusBreakerViewListView(BaseListView):

def __init__(self, parent, context: AppContext, *args, **kwargs):
BaseListView.__init__(self, parent, context, *args, **kwargs)

@property
def tab_name(self) -> str:
return 'Buses (Bus/Breaker View)'

def get_data_frame(self) -> pd.DataFrame:
return self.context.network_structure.buses_bus_breaker_view

def filter_data_frame(self, df: pd.DataFrame, voltage_levels: list[str]) -> pd.DataFrame:
return df.loc[df['voltage_level_id'].isin(voltage_levels)]


if __name__ == "__main__":

if os.name == 'nt':
# Fixing the blur UI on Windows
from ctypes import windll

windll.shcore.SetProcessDpiAwareness(2)
root = tk.Tk()
ctx = AppContext(root)
bw = BusesBusBreakerViewListView(root, ctx)
bw.pack(fill="both", expand=True)
ctx.network = pn.create_ieee9()
ctx.selection = ('network', '', None)
ctx.selected_tab = bw.tab_name
root.mainloop()
48 changes: 48 additions & 0 deletions yagat/frames/impl/buses_bus_view_list_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright (c) 2024, Damien Jeandemange (https://github.com/jeandemanged)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
import os
import tkinter as tk

import pandas as pd
import pypowsybl.network as pn

from yagat.app_context import AppContext
from yagat.frames.impl.base_list_view import BaseListView


class BusesListView(BaseListView):

def __init__(self, parent, context: AppContext, *args, **kwargs):
BaseListView.__init__(self, parent, context, *args, **kwargs)

@property
def tab_name(self) -> str:
return 'Buses (Bus View)'

def get_data_frame(self) -> pd.DataFrame:
return self.context.network_structure.buses

def filter_data_frame(self, df: pd.DataFrame, voltage_levels: list[str]) -> pd.DataFrame:
return df.loc[df['voltage_level_id'].isin(voltage_levels)]


if __name__ == "__main__":

if os.name == 'nt':
# Fixing the blur UI on Windows
from ctypes import windll

windll.shcore.SetProcessDpiAwareness(2)
root = tk.Tk()
ctx = AppContext(root)
bw = BusesListView(root, ctx)
bw.pack(fill="both", expand=True)
ctx.network = pn.create_ieee9()
ctx.selection = ('network', '', None)
ctx.selected_tab = bw.tab_name
root.mainloop()
48 changes: 48 additions & 0 deletions yagat/frames/impl/dangling_line_list_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright (c) 2024, Damien Jeandemange (https://github.com/jeandemanged)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
import os
import tkinter as tk

import pandas as pd
import pypowsybl.network as pn

from yagat.app_context import AppContext
from yagat.frames.impl.base_list_view import BaseListView


class DanglingLineListView(BaseListView):

def __init__(self, parent, context: AppContext, *args, **kwargs):
BaseListView.__init__(self, parent, context, *args, **kwargs)

@property
def tab_name(self) -> str:
return 'Dangling Lines'

def get_data_frame(self) -> pd.DataFrame:
return self.context.network_structure.dangling_lines

def filter_data_frame(self, df: pd.DataFrame, voltage_levels: list[str]) -> pd.DataFrame:
return df.loc[df['voltage_level_id'].isin(voltage_levels)]


if __name__ == "__main__":

if os.name == 'nt':
# Fixing the blur UI on Windows
from ctypes import windll

windll.shcore.SetProcessDpiAwareness(2)
root = tk.Tk()
ctx = AppContext(root)
bw = DanglingLineListView(root, ctx)
bw.pack(fill="both", expand=True)
ctx.network = pn.create_micro_grid_be_network()
ctx.selection = ('network', '', None)
ctx.selected_tab = bw.tab_name
root.mainloop()
45 changes: 0 additions & 45 deletions yagat/frames/impl/diagram_view.py

This file was deleted.

4 changes: 3 additions & 1 deletion yagat/frames/impl/diagram_view_bus.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,16 @@ def tab_name(self) -> str:
return self._tab_name

def on_selection_changed(self, selection: tuple[Optional[str], Optional[str], Optional[Connection]]):
_, selection_id, selection_connection = selection
selection_type, selection_id, selection_connection = selection
selected_connection_y = 0
if self.context.selected_tab != self.tab_name:
return
logging.info('Start drawing bus view')
for w in self.widgets:
w.destroy()
self.widgets = []
if selection_type not in ['substation', 'voltage_level']:
return
if not selection_id:
return
if self.context.selected_tab != self.tab_name:
Expand Down
48 changes: 48 additions & 0 deletions yagat/frames/impl/generator_list_view.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#
# Copyright (c) 2024, Damien Jeandemange (https://github.com/jeandemanged)
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
#
import os
import tkinter as tk

import pandas as pd
import pypowsybl.network as pn

from yagat.app_context import AppContext
from yagat.frames.impl.base_list_view import BaseListView


class GeneratorListView(BaseListView):

def __init__(self, parent, context: AppContext, *args, **kwargs):
BaseListView.__init__(self, parent, context, *args, **kwargs)

@property
def tab_name(self) -> str:
return 'Generators'

def get_data_frame(self) -> pd.DataFrame:
return self.context.network_structure.generators

def filter_data_frame(self, df: pd.DataFrame, voltage_levels: list[str]) -> pd.DataFrame:
return df.loc[df['voltage_level_id'].isin(voltage_levels)]


if __name__ == "__main__":

if os.name == 'nt':
# Fixing the blur UI on Windows
from ctypes import windll

windll.shcore.SetProcessDpiAwareness(2)
root = tk.Tk()
ctx = AppContext(root)
bw = GeneratorListView(root, ctx)
bw.pack(fill="both", expand=True)
ctx.network = pn.create_ieee9()
ctx.selection = ('network', '', None)
ctx.selected_tab = bw.tab_name
root.mainloop()
Loading