prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  pymodbus.simulator fails with no running event loop
  ### Versions
  
  * Python: 3.9.2
  * OS: Debian Bullseye
  * Pymodbus: 3.1.3 latest dev branch
  * Modbus Hardware (if used):
  
  ### Pymodbus Specific
  * Server: tcp - sync/async
  * Client: tcp - sync/async
  
  ### Description
  
  Executing pymodbus.simulator from the commandline results in the following error:
  
  ```
  $ pymodbus.simulator
  10:39:28 INFO  logging:74 Start simulator
  Traceback (most recent call last):
    File "/usr/local/bin/pymodbus.simulator", line 33, in <module>
      sys.exit(load_entry_point('pymodbus===3.1.x', 'console_scripts', 'pymodbus.simulator')())
    File "/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/main.py", line 112, in main
      task = ModbusSimulatorServer(**cmd_args)
    File "/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/http_server.py", line 134, in __init__
      server["loop"] = asyncio.get_running_loop()
  RuntimeError: no running event loop
  ```
  NOTE: I am running this from the pymodbus/server/simulator/ folder, so it picks up the example [setup.json](https://github.com/pymodbus-dev/pymodbus/blob/dev/pymodbus/server/simulator/setup.json) file.
  
  Manually specifying available options from the commandline results in the same error as well:
  ```
  $ pymodbus.simulator \
    --http_host 0.0.0.0 \
    --http_port 8080 \
    --modbus_server server \
    --modbus_device device \
    --json_file ~/git/pymodbus/pymodbus/server/simulator/setup.json
  
  11:24:07 INFO  logging:74 Start simulator
  Traceback (most recent call last):
    File "/usr/local/bin/pymodbus.simulator", line 33, in <module>
      sys.exit(load_entry_point('pymodbus===3.1.x', 'console_scripts', 'pymodbus.simulator')())
    File "/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/main.py", line 112, in main
      task = ModbusSimulatorServer(**cmd_args)
    File "/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/http_server.py", line 134, in __init__
      server["loop"] = asyncio.get_running_loop()
  RuntimeError: no running event loop
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `pymodbus/server/simulator/main.py`
  Content:
  ```
  1 #!/usr/bin/env python3
  2 """HTTP server for modbus simulator.
  3 
  4 The modbus simulator contain 3 distint parts:
  5 
  6 - Datastore simulator, to define registers and their behaviour including actions: (simulator)(../../datastore/simulator.py)
  7 - Modbus server: (server)(./http_server.py)
  8 - HTTP server with REST API and web pages providing an online console in your browser
  9 
  10 Multiple setups for different server types and/or devices are prepared in a (json file)(./setup.json), the detailed configuration is explained in (doc)(README.md)
  11 
  12 The command line parameters are kept to a minimum:
  13 
  14 usage: main.py [-h] [--modbus_server MODBUS_SERVER]
  15                [--modbus_device MODBUS_DEVICE] [--http_host HTTP_HOST]
  16                [--http_port HTTP_PORT]
  17                [--log {critical,error,warning,info,debug}]
  18                [--json_file JSON_FILE]
  19                [--custom_actions_module CUSTOM_ACTIONS_MODULE]
  20 
  21 Modbus server with REST-API and web server
  22 
  23 options:
  24   -h, --help            show this help message and exit
  25   --modbus_server MODBUS_SERVER
  26                         use <modbus_server> from server_list in json file
  27   --modbus_device MODBUS_DEVICE
  28                         use <modbus_device> from device_list in json file
  29   --http_host HTTP_HOST
  30                         use <http_host> as host to bind http listen
  31   --http_port HTTP_PORT
  32                         use <http_port> as port to bind http listen
  33   --log {critical,error,warning,info,debug}
  34                         set log level, default is info
  35   --log_file LOG_FILE
  36                         name of server log file, default is "server.log"
  37   --json_file JSON_FILE
  38                         name of json_file, default is "setup.json"
  39   --custom_actions_module CUSTOM_ACTIONS_MODULE
  40                         python file with custom actions, default is none
  41 """
  42 import argparse
  43 import asyncio
  44 
  45 from pymodbus import pymodbus_apply_logging_config
  46 from pymodbus.logging import Log
  47 from pymodbus.server.simulator.http_server import ModbusSimulatorServer
  48 
  49 
  50 def get_commandline():
  51     """Get command line arguments."""
  52     parser = argparse.ArgumentParser(
  53         description="Modbus server with REST-API and web server"
  54     )
  55     parser.add_argument(
  56         "--modbus_server",
  57         help="use <modbus_server> from server_list in json file",
  58         type=str,
  59     )
  60     parser.add_argument(
  61         "--modbus_device",
  62         help="use <modbus_device> from device_list in json file",
  63         type=str,
  64     )
  65     parser.add_argument(
  66         "--http_host",
  67         help="use <http_host> as host to bind http listen",
  68         type=str,
  69     )
  70     parser.add_argument(
  71         "--http_port",
  72         help="use <http_port> as port to bind http listen",
  73         type=str,
  74     )
  75     parser.add_argument(
  76         "--log",
  77         choices=["critical", "error", "warning", "info", "debug"],
  78         help="set log level, default is info",
  79         default="info",
  80         type=str,
  81     )
  82     parser.add_argument(
  83         "--json_file",
  84         help='name of json file, default is "setup.json"',
  85         type=str,
  86     )
  87     parser.add_argument(
  88         "--log_file",
  89         help='name of server log file, default is "server.log"',
  90         type=str,
  91     )
  92     parser.add_argument(
  93         "--custom_actions_module",
  94         help="python file with custom actions, default is none",
  95         type=str,
  96     )
  97     args = parser.parse_args()
  98     pymodbus_apply_logging_config(args.log.upper())
  99     Log.info("Start simulator")
  100     cmd_args = {}
  101     for argument in args.__dict__:
  102         if argument == "log":
  103             continue
  104         if args.__dict__[argument] is not None:
  105             cmd_args[argument] = args.__dict__[argument]
  106     return cmd_args
  107 
  108 
  109 def main():
  110     """Run server."""
  111     cmd_args = get_commandline()
  112     task = ModbusSimulatorServer(**cmd_args)
  113     asyncio.run(task.run_forever(), debug=True)
  114 
  115 
  116 if __name__ == "__main__":
  117     main()
  118
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/pymodbus/server/simulator/main.py b/pymodbus/server/simulator/main.py
  --- a/pymodbus/server/simulator/main.py
  +++ b/pymodbus/server/simulator/main.py
  @@ -106,11 +106,16 @@
       return cmd_args
   
   
  -def main():
  -    """Run server."""
  +async def run_main():
  +    """Run server async."""
       cmd_args = get_commandline()
       task = ModbusSimulatorServer(**cmd_args)
  -    asyncio.run(task.run_forever(), debug=True)
  +    await task.run_forever()
  +
  +
  +def main():
  +    """Run server."""
  +    asyncio.run(run_main(), debug=True)
   
   
   if __name__ == "__main__":
  
verification_info: {"golden_diff": "diff --git a/pymodbus/server/simulator/main.py b/pymodbus/server/simulator/main.py\n--- a/pymodbus/server/simulator/main.py\n+++ b/pymodbus/server/simulator/main.py\n@@ -106,11 +106,16 @@\n     return cmd_args\n \n \n-def main():\n-    \"\"\"Run server.\"\"\"\n+async def run_main():\n+    \"\"\"Run server async.\"\"\"\n     cmd_args = get_commandline()\n     task = ModbusSimulatorServer(**cmd_args)\n-    asyncio.run(task.run_forever(), debug=True)\n+    await task.run_forever()\n+\n+\n+def main():\n+    \"\"\"Run server.\"\"\"\n+    asyncio.run(run_main(), debug=True)\n \n \n if __name__ == \"__main__\":\n", "issue": "pymodbus.simulator fails with no running event loop\n### Versions\r\n\r\n* Python: 3.9.2\r\n* OS: Debian Bullseye\r\n* Pymodbus: 3.1.3 latest dev branch\r\n* Modbus Hardware (if used):\r\n\r\n### Pymodbus Specific\r\n* Server: tcp - sync/async\r\n* Client: tcp - sync/async\r\n\r\n### Description\r\n\r\nExecuting pymodbus.simulator from the commandline results in the following error:\r\n\r\n```\r\n$ pymodbus.simulator\r\n10:39:28 INFO  logging:74 Start simulator\r\nTraceback (most recent call last):\r\n  File \"/usr/local/bin/pymodbus.simulator\", line 33, in <module>\r\n    sys.exit(load_entry_point('pymodbus===3.1.x', 'console_scripts', 'pymodbus.simulator')())\r\n  File \"/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/main.py\", line 112, in main\r\n    task = ModbusSimulatorServer(**cmd_args)\r\n  File \"/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/http_server.py\", line 134, in __init__\r\n    server[\"loop\"] = asyncio.get_running_loop()\r\nRuntimeError: no running event loop\r\n```\r\nNOTE: I am running this from the pymodbus/server/simulator/ folder, so it picks up the example [setup.json](https://github.com/pymodbus-dev/pymodbus/blob/dev/pymodbus/server/simulator/setup.json) file.\r\n\r\nManually specifying available options from the commandline results in the same error as well:\r\n```\r\n$ pymodbus.simulator \\\r\n  --http_host 0.0.0.0 \\\r\n  --http_port 8080 \\\r\n  --modbus_server server \\\r\n  --modbus_device device \\\r\n  --json_file ~/git/pymodbus/pymodbus/server/simulator/setup.json\r\n\r\n11:24:07 INFO  logging:74 Start simulator\r\nTraceback (most recent call last):\r\n  File \"/usr/local/bin/pymodbus.simulator\", line 33, in <module>\r\n    sys.exit(load_entry_point('pymodbus===3.1.x', 'console_scripts', 'pymodbus.simulator')())\r\n  File \"/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/main.py\", line 112, in main\r\n    task = ModbusSimulatorServer(**cmd_args)\r\n  File \"/usr/local/lib/python3.9/dist-packages/pymodbus/server/simulator/http_server.py\", line 134, in __init__\r\n    server[\"loop\"] = asyncio.get_running_loop()\r\nRuntimeError: no running event loop\r\n```\r\n\n", "before_files": [{"content": "#!/usr/bin/env python3\n\"\"\"HTTP server for modbus simulator.\n\nThe modbus simulator contain 3 distint parts:\n\n- Datastore simulator, to define registers and their behaviour including actions: (simulator)(../../datastore/simulator.py)\n- Modbus server: (server)(./http_server.py)\n- HTTP server with REST API and web pages providing an online console in your browser\n\nMultiple setups for different server types and/or devices are prepared in a (json file)(./setup.json), the detailed configuration is explained in (doc)(README.md)\n\nThe command line parameters are kept to a minimum:\n\nusage: main.py [-h] [--modbus_server MODBUS_SERVER]\n               [--modbus_device MODBUS_DEVICE] [--http_host HTTP_HOST]\n               [--http_port HTTP_PORT]\n               [--log {critical,error,warning,info,debug}]\n               [--json_file JSON_FILE]\n               [--custom_actions_module CUSTOM_ACTIONS_MODULE]\n\nModbus server with REST-API and web server\n\noptions:\n  -h, --help            show this help message and exit\n  --modbus_server MODBUS_SERVER\n                        use <modbus_server> from server_list in json file\n  --modbus_device MODBUS_DEVICE\n                        use <modbus_device> from device_list in json file\n  --http_host HTTP_HOST\n                        use <http_host> as host to bind http listen\n  --http_port HTTP_PORT\n                        use <http_port> as port to bind http listen\n  --log {critical,error,warning,info,debug}\n                        set log level, default is info\n  --log_file LOG_FILE\n                        name of server log file, default is \"server.log\"\n  --json_file JSON_FILE\n                        name of json_file, default is \"setup.json\"\n  --custom_actions_module CUSTOM_ACTIONS_MODULE\n                        python file with custom actions, default is none\n\"\"\"\nimport argparse\nimport asyncio\n\nfrom pymodbus import pymodbus_apply_logging_config\nfrom pymodbus.logging import Log\nfrom pymodbus.server.simulator.http_server import ModbusSimulatorServer\n\n\ndef get_commandline():\n    \"\"\"Get command line arguments.\"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Modbus server with REST-API and web server\"\n    )\n    parser.add_argument(\n        \"--modbus_server\",\n        help=\"use <modbus_server> from server_list in json file\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--modbus_device\",\n        help=\"use <modbus_device> from device_list in json file\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--http_host\",\n        help=\"use <http_host> as host to bind http listen\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--http_port\",\n        help=\"use <http_port> as port to bind http listen\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--log\",\n        choices=[\"critical\", \"error\", \"warning\", \"info\", \"debug\"],\n        help=\"set log level, default is info\",\n        default=\"info\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--json_file\",\n        help='name of json file, default is \"setup.json\"',\n        type=str,\n    )\n    parser.add_argument(\n        \"--log_file\",\n        help='name of server log file, default is \"server.log\"',\n        type=str,\n    )\n    parser.add_argument(\n        \"--custom_actions_module\",\n        help=\"python file with custom actions, default is none\",\n        type=str,\n    )\n    args = parser.parse_args()\n    pymodbus_apply_logging_config(args.log.upper())\n    Log.info(\"Start simulator\")\n    cmd_args = {}\n    for argument in args.__dict__:\n        if argument == \"log\":\n            continue\n        if args.__dict__[argument] is not None:\n            cmd_args[argument] = args.__dict__[argument]\n    return cmd_args\n\n\ndef main():\n    \"\"\"Run server.\"\"\"\n    cmd_args = get_commandline()\n    task = ModbusSimulatorServer(**cmd_args)\n    asyncio.run(task.run_forever(), debug=True)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "pymodbus/server/simulator/main.py"}], "after_files": [{"content": "#!/usr/bin/env python3\n\"\"\"HTTP server for modbus simulator.\n\nThe modbus simulator contain 3 distint parts:\n\n- Datastore simulator, to define registers and their behaviour including actions: (simulator)(../../datastore/simulator.py)\n- Modbus server: (server)(./http_server.py)\n- HTTP server with REST API and web pages providing an online console in your browser\n\nMultiple setups for different server types and/or devices are prepared in a (json file)(./setup.json), the detailed configuration is explained in (doc)(README.md)\n\nThe command line parameters are kept to a minimum:\n\nusage: main.py [-h] [--modbus_server MODBUS_SERVER]\n               [--modbus_device MODBUS_DEVICE] [--http_host HTTP_HOST]\n               [--http_port HTTP_PORT]\n               [--log {critical,error,warning,info,debug}]\n               [--json_file JSON_FILE]\n               [--custom_actions_module CUSTOM_ACTIONS_MODULE]\n\nModbus server with REST-API and web server\n\noptions:\n  -h, --help            show this help message and exit\n  --modbus_server MODBUS_SERVER\n                        use <modbus_server> from server_list in json file\n  --modbus_device MODBUS_DEVICE\n                        use <modbus_device> from device_list in json file\n  --http_host HTTP_HOST\n                        use <http_host> as host to bind http listen\n  --http_port HTTP_PORT\n                        use <http_port> as port to bind http listen\n  --log {critical,error,warning,info,debug}\n                        set log level, default is info\n  --log_file LOG_FILE\n                        name of server log file, default is \"server.log\"\n  --json_file JSON_FILE\n                        name of json_file, default is \"setup.json\"\n  --custom_actions_module CUSTOM_ACTIONS_MODULE\n                        python file with custom actions, default is none\n\"\"\"\nimport argparse\nimport asyncio\n\nfrom pymodbus import pymodbus_apply_logging_config\nfrom pymodbus.logging import Log\nfrom pymodbus.server.simulator.http_server import ModbusSimulatorServer\n\n\ndef get_commandline():\n    \"\"\"Get command line arguments.\"\"\"\n    parser = argparse.ArgumentParser(\n        description=\"Modbus server with REST-API and web server\"\n    )\n    parser.add_argument(\n        \"--modbus_server\",\n        help=\"use <modbus_server> from server_list in json file\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--modbus_device\",\n        help=\"use <modbus_device> from device_list in json file\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--http_host\",\n        help=\"use <http_host> as host to bind http listen\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--http_port\",\n        help=\"use <http_port> as port to bind http listen\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--log\",\n        choices=[\"critical\", \"error\", \"warning\", \"info\", \"debug\"],\n        help=\"set log level, default is info\",\n        default=\"info\",\n        type=str,\n    )\n    parser.add_argument(\n        \"--json_file\",\n        help='name of json file, default is \"setup.json\"',\n        type=str,\n    )\n    parser.add_argument(\n        \"--log_file\",\n        help='name of server log file, default is \"server.log\"',\n        type=str,\n    )\n    parser.add_argument(\n        \"--custom_actions_module\",\n        help=\"python file with custom actions, default is none\",\n        type=str,\n    )\n    args = parser.parse_args()\n    pymodbus_apply_logging_config(args.log.upper())\n    Log.info(\"Start simulator\")\n    cmd_args = {}\n    for argument in args.__dict__:\n        if argument == \"log\":\n            continue\n        if args.__dict__[argument] is not None:\n            cmd_args[argument] = args.__dict__[argument]\n    return cmd_args\n\n\nasync def run_main():\n    \"\"\"Run server async.\"\"\"\n    cmd_args = get_commandline()\n    task = ModbusSimulatorServer(**cmd_args)\n    await task.run_forever()\n\n\ndef main():\n    \"\"\"Run server.\"\"\"\n    asyncio.run(run_main(), debug=True)\n\n\nif __name__ == \"__main__\":\n    main()\n", "path": "pymodbus/server/simulator/main.py"}]}