Repository: pymodbus-dev/pymodbus

Issue:
Simulator server cannot start in current dev branch
<!--
Before opening a new issue, make sure you do the following:

- Check that your issue isn't already filed: https://github.com/pymodbus-dev/pymodbus/issues
- Check the discussions forum https://github.com/pymodbus-dev/pymodbus/discussions
- Prepare a short, runnable example that reproduce the issue with the latest development version of Pymodbus
-->

### Versions

- Python: 3.9
- OS: macos 13.4
- Pymodbus: dev-3.4.0
- Modbus Hardware (if used): None

### Pymodbus Specific

- Server: tcp, simulator
- Client: None

### Description

<!-- What were you trying, what has happened, what went wrong, and what did you expect? -->

When I was trying to start a simulator by running main.py in server/simulator/, python complained with error logs below:

```bash
pymodbus $ PYTHONPATH=. python server/simulator/main.py
2023-07-18 09:23:23,159 INFO  logging:96 Start simulator
Executing <Task finished name='Task-1' coro=<run_main() done, defined at /Users/hydra/Documents/coding/pymodbus/pymodbus/server/simulator/main.py:112> exception=TypeError("__init__() got an unexpected keyword argument 'loop'") created at /Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py:621> took 0.118 seconds
Traceback (most recent call last):
  File "xxx/pymodbus/server/simulator/main.py", line 125, in <module>
    main()
  File "xxx/pymodbus/server/simulator/main.py", line 121, in main
    asyncio.run(run_main(), debug=True)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/Library/Frameworks/Python.framework/Versions/3.9/lib/python3.9/asyncio/base_events.py", line 642, in run_until_complete
    return future.result()
  File "xxx/pymodbus/server/simulator/main.py", line 115, in run_main
    task = ModbusSimulatorServer(**cmd_args)
  File "xxx/pymodbus/server/simulator/http_server.py", line 168, in __init__
    self.modbus_server = comm(framer=framer, context=datastore, **server)
TypeError: __init__() got an unexpected keyword argument 'loop'
```

I've digged into the commit logs of pymodbus and found that class ModbusTcpServer in pymodbus/server/async_io.py was originally accepting a **kwargs value in __init__ which is removed in current dev branch. If I'm right I think **kwargs should be added back, or the "loop" args in http_server.py L152 `server["loop"] = asyncio.get_running_loop()` should be removed.



Discussion:

Resolving patch:
diff --git a/pymodbus/server/simulator/http_server.py b/pymodbus/server/simulator/http_server.py
--- a/pymodbus/server/simulator/http_server.py
+++ b/pymodbus/server/simulator/http_server.py
@@ -149,7 +149,6 @@ def __init__(
         else:
             custom_actions_dict = None
         server = setup["server_list"][modbus_server]
-        server["loop"] = asyncio.get_running_loop()
         if server["comm"] != "serial":
             server["address"] = (server["host"], server["port"])
             del server["host"]


Test patch:
diff --git a/test/test_simulator.py b/test/test_simulator.py
--- a/test/test_simulator.py
+++ b/test/test_simulator.py
@@ -1,10 +1,13 @@
 """Test datastore."""
 import copy
+import json
+from unittest.mock import mock_open, patch
 
 import pytest
 
 from pymodbus.datastore import ModbusSimulatorContext
 from pymodbus.datastore.simulator import Cell, CellType, Label
+from pymodbus.server import ModbusSimulatorServer
 
 
 FX_READ_BIT = 1
@@ -94,6 +97,24 @@ class TestSimulator:
         "repeat": [{"addr": [0, 48], "to": [49, 147]}],
     }
 
+    default_server_config = {
+        "server": {
+            "comm": "tcp",
+            "host": "0.0.0.0",
+            "port": 5020,
+            "ignore_missing_slaves": False,
+            "framer": "socket",
+            "identity": {
+                "VendorName": "pymodbus",
+                "ProductCode": "PM",
+                "VendorUrl": "https://github.com/pymodbus-dev/pymodbus/",
+                "ProductName": "pymodbus Server",
+                "ModelName": "pymodbus Server",
+                "MajorMinorRevision": "3.1.0",
+            },
+        },
+    }
+
     test_registers = [
         Cell(),
         Cell(),
@@ -539,3 +560,18 @@ def test_simulator_action_random(self, celltype, minval, maxval):
                     regs, is_int
                 )
             assert minval <= new_value <= maxval
+
+    async def test_init_simulator_server_tcp(self):
+        """Test init simulator server"""
+        with patch(
+            "builtins.open",
+            mock_open(
+                read_data=json.dumps(
+                    {
+                        "server_list": self.default_server_config,
+                        "device_list": {"device": self.default_config},
+                    }
+                )
+            ),
+        ):
+            ModbusSimulatorServer()