diff --git a/pandapower/timeseries/output_writer.py b/pandapower/timeseries/output_writer.py
index 487dfed3..d7908d10 100644
--- a/pandapower/timeseries/output_writer.py
+++ b/pandapower/timeseries/output_writer.py
@@ -323,9 +323,9 @@ class OutputWriter(JSONSerializableClass):
         **eval_function** (function, None) - A function to be applied on the table / variable / index combination.
         example: pd.min or pd.mean
 
-        **eval_name** (str, None) - The name for an applied function. If None the name consists of the table, variable,
-        index and eval function
-        example: "Sir_Lancelot"
+        **eval_name** (str, None) - The name for an applied function. It *must* be unique.
+                                    If the name is None the name consists of the table, variable, index and eval function
+                                    example: "max_load_p_mw_values"
 
         EXAMPLE:
             >>> ow.log_variable('res_bus', 'vm_pu') # add logging for bus voltage magnitudes
@@ -338,6 +338,11 @@ class OutputWriter(JSONSerializableClass):
         append = True
         # check if new log_variable is already in log_variables. If so either append or delete
         for i, log_args in enumerate(self.log_variables):
+            if len(log_args) > 4 and eval_name is not None and log_args[4] == eval_name:
+                logger.warning("eval_name '{}' already exists for table '{}' and variable '{}'. "
+                                 "Please choose a unique eval_name. "
+                               "I'll use the default instead.".format(eval_name, log_args[0], log_args[1]))
+                eval_name = None
             if log_args[0] == table and log_args[1] == variable:
                 # table and variable exist in log_variables
                 if eval_function is not None or eval_name is not None:

log variable with specific name in outputwriter
I just came across a peculiarity of the outputwriter. When adding an eval_name to a log variable (e.g. "maximum" for the minimum of a variable in some table), it is precisely stored as "maximum" globally in the numpy-output. As I am just a user and mainly working with the file output, this comes a little unexpected, as I thought that it just influences the name of the column that is stored in the file. The behavior is now that when adding "maximum" to res_line.loading_percent and to res_bus.vm_pu, csv-files are written for both, but they show the same values (which one depends on which "maximum" log variable was defined first).

Does it make sense to you to change this kind of behavior (i.e. in `_get_np_name` the name should be formed from table.value.eval_name instead of eval_name only)? Otherwise we should definitely add warnings here, in the documentation and upon adding a log variable. If the values are just overwritten, that is totally confusing.
diff --git a/pandapower/test/timeseries/test_output_writer.py b/pandapower/test/timeseries/test_output_writer.py
index 1e4fe201..18346e3e 100644
--- a/pandapower/test/timeseries/test_output_writer.py
+++ b/pandapower/test/timeseries/test_output_writer.py
@@ -15,11 +15,14 @@ import pytest
 
 import pandapower as pp
 import pandapower.control as ct
+import pandapower.networks as nw
+import pandapower.timeseries as ts
 from pandapower.control import ConstControl
+from pandapower.networks import simple_four_bus_system
 from pandapower.test.timeseries.test_timeseries import create_data_source, simple_test_net
 from pandapower.timeseries import DFData, OutputWriter
 from pandapower.timeseries.run_time_series import run_timeseries
-from pandapower.networks import simple_four_bus_system
+
 logger = logging.getLogger(__name__)
 ow_logger = logging.getLogger("hp.control.output_writer")
 logger.setLevel(logging.ERROR)
@@ -272,30 +275,50 @@ def test_ppc_log(simple_test_net):
 
 def test_ow_index():
     net = simple_four_bus_system()
-    steps = [3,5,7]
-    p_data = pd.DataFrame(index=steps, columns=["0", "1"], data=[[0.01, 0.02], 
+    steps = [3, 5, 7]
+    p_data = pd.DataFrame(index=steps, columns=["0", "1"], data=[[0.01, 0.02],
                                                                  [0.03, 0.04],
                                                                  [0.05, 0.06],
                                                                  ])
     v_data = pd.DataFrame(index=steps, columns=["0"], data=[1.01, 1.03, 1.02])
-        
+
     ds_p = DFData(p_data)
     ds_v = DFData(v_data)
-    
+
     ct.ConstControl(net, element='load', variable='p_mw',
-                 element_index=net.load.index.tolist(), data_source=ds_p,
-                 profile_name=p_data.columns)
-    ct.ConstControl(net, element='ext_grid', variable='vm_pu', 
-                 element_index=0, data_source=ds_v, 
-                 profile_name='0')
-    
+                    element_index=net.load.index.tolist(), data_source=ds_p,
+                    profile_name=p_data.columns)
+    ct.ConstControl(net, element='ext_grid', variable='vm_pu',
+                    element_index=0, data_source=ds_v,
+                    profile_name='0')
+
     ow = OutputWriter(net)
     ow.log_variable('res_bus', 'vm_pu')
     ow.log_variable('res_line', 'loading_percent')
-    
+
     run_timeseries(net, time_steps=p_data.index, verbose=False)
-    
+
     assert np.all(ow.output["res_line.loading_percent"].index == p_data.index)
-    
+
+
+def test_equal_eval_name_warning():
+    net = nw.case5()
+    df = pd.DataFrame({0: [200, 300, 400, 500], 1: [400, 300, 100, 50], 2: [100, 300, 200, 100]})
+    ds = ts.DFData(df.astype(np.float64))
+    _ = ct.ConstControl(net, "load", "p_mw", net.load.index, profile_name=net.load.index,
+                           data_source=ds)
+    ow = ts.OutputWriter(net, output_path=None)
+    ow.log_variable("res_sgen", "p_mw", None, np.max, 'warnme')
+    ow.log_variable("res_load", "p_mw", None, np.max, 'warnme')
+    ow.remove_log_variable("res_bus", "vm_pu")
+    ow.remove_log_variable("res_line", "loading_percent")
+    ts.run_timeseries(net, verbose=False)
+
+    p_sgen = ow.output["res_sgen.p_mw"]
+    p_load = ow.output["res_load.p_mw"]
+    assert not np.all(p_sgen.values == p_load.values)
+    assert len(ow.np_results) == 2
+
+
 if __name__ == '__main__':
-    pytest.main(['-s', __file__])
\ No newline at end of file
+    pytest.main(['-s', __file__])

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-xdist
3.6
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
attrs==22.2.0
certifi==2021.5.30
decorator==4.4.2
execnet==1.9.0
importlib-metadata==4.8.3
iniconfig==1.1.1
networkx==2.5.1
numpy==1.19.5
packaging==21.3
-e git+https://github.com/e2nIEE/pandapower.git@eb8f45f03588d13d6f4947436af268b27fb47572#egg=pandapower
pandas==0.25.3
pluggy==1.0.0
py==1.11.0
pyparsing==3.1.4
pytest==7.0.1
pytest-xdist==3.0.2
python-dateutil==2.9.0.post0
pytz==2025.2
scipy==1.5.4
six==1.17.0
tomli==1.2.3
typing_extensions==4.1.1
zipp==3.6.0

name: pandapower
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - attrs==22.2.0
      - decorator==4.4.2
      - execnet==1.9.0
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - networkx==2.5.1
      - numpy==1.19.5
      - packaging==21.3
      - pandas==0.25.3
      - pluggy==1.0.0
      - py==1.11.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytest-xdist==3.0.2
      - python-dateutil==2.9.0.post0
      - pytz==2025.2
      - scipy==1.5.4
      - six==1.17.0
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - zipp==3.6.0
prefix: /opt/conda/envs/pandapower

pandapower/test/timeseries/test_output_writer.py::test_equal_eval_name_warning
pandapower/test/timeseries/test_output_writer.py::test_output_writer_log pandapower/test/timeseries/test_output_writer.py::test_output_writer_with_timesteps_set pandapower/test/timeseries/test_output_writer.py::test_output_writer_without_timesteps_set pandapower/test/timeseries/test_output_writer.py::test_output_writer_without_timesteps_set_repeat pandapower/test/timeseries/test_output_writer.py::test_output_writer_short_data_source pandapower/test/timeseries/test_output_writer.py::test_default_output_writer pandapower/test/timeseries/test_output_writer.py::test_output_writer_eval_simple pandapower/test/timeseries/test_output_writer.py::test_output_writer_multiple_index_definition pandapower/test/timeseries/test_output_writer.py::test_remove_variable pandapower/test/timeseries/test_output_writer.py::test_store_and_load pandapower/test/timeseries/test_output_writer.py::test_ppc_log pandapower/test/timeseries/test_output_writer.py::test_ow_index
pandapower/timeseries/output_writer.py
pandapower/timeseries/output_writer.py