Repository: e2nIEE/pandapower

Issue:
PandaPower Toolbox.py get_connected_elements for respect_in_service = True leads to error
Pandapower has a bug in the toolbox.py function where in for the respect_in_service = True option as parameter to find all the connected elements to a bus leads to the following error.
This is also the case for simple pandapower networks
Steps to reproduce:-
Load any exemplary pandapower network
Set at the bus of intrest a generator out of service
Call the folloeing function for that bus

elems_dict = pp.get_connected_elements_dict(network , bus, respect_switches=False,respect_in_service=True)

Error
packages/pandapower/toolbox.py", line 2894, in get_connected_elements
connected_elements -= set(element_table[~element_table.in_service].index)
UnboundLocalError: local variable 'element_table' referenced before assignment


Discussion:
I have a ready solution for that 
How can I make a PR?
Yes please!
You can make a fork of the repository in your GitHub account. Then you can push your changes to your fork of pandapower as a new branch. Afterwards, you can open a pull request and specify your feature-branch as the source branch and "develop" as the desctination branch.
Here the documentation from GitHub about how to open a pull request from a fork:

https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request-from-a-fork
@rbolgaryn 
Done
please take a look at the tests, they are failing at the moment

@rbolgaryn 
Tests are working now
Dear @AnkurArohi ,

please open a separate pull request that just fixes the issue that you brought up and adds a test for it. 

You can open a separate pull request that improves the pylint.

The current pull request changes too much just to be attributed to this issue.
ok, I can try

Resolving patch:
diff --git a/pandapower/toolbox.py b/pandapower/toolbox.py
--- a/pandapower/toolbox.py
+++ b/pandapower/toolbox.py
@@ -2870,6 +2870,7 @@ def get_connected_elements(net, element, buses, respect_switches=True, respect_i
         connected_elements = set(net["impedance"].index[(net.impedance.from_bus.isin(buses)) |
                                                         (net.impedance.to_bus.isin(buses))])
     elif element == "measurement":
+        element_table = net[element]
         connected_elements = set(net.measurement.index[(net.measurement.element.isin(buses)) |
                                                        (net.measurement.element_type == "bus")])
     elif element in pp_elements(bus=False, branch_elements=False):
@@ -2888,7 +2889,7 @@ def get_connected_elements(net, element, buses, respect_switches=True, respect_i
                                                 net.switch.element.isin(connected_elements)].index
             connected_elements -= set(net.switch.element[open_and_connected])
 
-    if respect_in_service:
+    if respect_in_service and "in_service" in element_table and not element_table.empty:
         connected_elements -= set(element_table[~element_table.in_service].index)
 
     return connected_elements
@@ -2983,15 +2984,15 @@ def get_connected_buses(net, buses, consider=("l", "s", "t", "t3", "i"), respect
         else:
             opened_buses_hv = opened_buses_mv = opened_buses_lv = set()
 
-        hvb_trafos3w = set(net.trafo3w.index[
+        hvb_trafos3w = net.trafo3w.index[
             net.trafo3w.hv_bus.isin(buses) & ~net.trafo3w.hv_bus.isin(opened_buses_hv) &
-            in_service_constr3w])
-        mvb_trafos3w = set(net.trafo3w.index[
+            in_service_constr3w]
+        mvb_trafos3w = net.trafo3w.index[
             net.trafo3w.mv_bus.isin(buses) & ~net.trafo3w.mv_bus.isin(opened_buses_mv) &
-            in_service_constr3w])
-        lvb_trafos3w = set(net.trafo3w.index[
+            in_service_constr3w]
+        lvb_trafos3w = net.trafo3w.index[
             net.trafo3w.lv_bus.isin(buses) & ~net.trafo3w.lv_bus.isin(opened_buses_lv) &
-            in_service_constr3w])
+            in_service_constr3w]
 
         cb |= (set(net.trafo3w.loc[hvb_trafos3w].mv_bus) | set(
             net.trafo3w.loc[hvb_trafos3w].lv_bus) - opened_buses_mv - opened_buses_lv)


Test patch:
diff --git a/pandapower/test/api/test_toolbox.py b/pandapower/test/api/test_toolbox.py
--- a/pandapower/test/api/test_toolbox.py
+++ b/pandapower/test/api/test_toolbox.py
@@ -1193,6 +1193,20 @@ def test_get_connected_elements_dict():
     assert conn == {'line': [1, 3], 'switch': [1, 2, 7], 'trafo': [0], 'bus': [2, 5, 6]}
 
 
+def test_get_connected_elements_empty_in_service():
+    # would cause an error with respect_in_service=True for the case of:
+    #  - empty element tables
+    #  - element tables without in_service column (e.g. measurement)
+    #  - element_table was unbound for the element table measurement
+    #  see #1592
+    net = nw.example_simple()
+    net.bus.in_service.at[6] = False
+    conn = pp.get_connected_elements_dict(net, [0], respect_switches=False, respect_in_service=True)
+    assert conn == {"line": [0], 'ext_grid': [0], 'bus': [1]}
+    conn = pp.get_connected_elements_dict(net, [3, 4], respect_switches=False, respect_in_service=True)
+    assert conn == {'line': [1, 3], 'switch': [1, 2, 7], 'trafo': [0], 'bus': [2, 5]}
+
+
 def test_replace_ward_by_internal_elements():
     net = nw.example_simple()
     pp.create_ward(net, 1, 10, 5, -20, -10, name="ward_1")