prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Can't run pymodbus.simulator --help
  <!--
  
  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
  
      Before opening a new issue, make sure you do the following
  -->
  
  ### Versions
  
  * Python: 3.10.6
  * OS: Linux
  * Pymodbus: 3.1.3
  * Modbus Hardware (if used):
  
  ### Description
  
  Trying to run `pymodbus.simulator --help` fails:
  
  ```
  <coroutine object main at 0x7efcc073cf90>
  sys:1: RuntimeWarning: coroutine 'main' was never awaited
  RuntimeWarning: Enable tracemalloc to get the object allocation traceback
  ```
  
  The `main` function used as entry point for the simulator is an async function: https://github.com/pymodbus-dev/pymodbus/blob/12859d0b82cc215a18ac757fe9319cdf1f9ec890/pymodbus/server/simulator/main.py#L113
  
  It can't be used directly as an entry point. The entry point should be a function using `asyncio.run`.
  
  
  --- 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 async def run():
  51     """Run simulator."""
  52 
  53 
  54 def get_commandline():
  55     """Get command line arguments."""
  56     parser = argparse.ArgumentParser(
  57         description="Modbus server with REST-API and web server"
  58     )
  59     parser.add_argument(
  60         "--modbus_server",
  61         help="use <modbus_server> from server_list in json file",
  62         type=str,
  63     )
  64     parser.add_argument(
  65         "--modbus_device",
  66         help="use <modbus_device> from device_list in json file",
  67         type=str,
  68     )
  69     parser.add_argument(
  70         "--http_host",
  71         help="use <http_host> as host to bind http listen",
  72         type=str,
  73     )
  74     parser.add_argument(
  75         "--http_port",
  76         help="use <http_port> as port to bind http listen",
  77         type=str,
  78     )
  79     parser.add_argument(
  80         "--log",
  81         choices=["critical", "error", "warning", "info", "debug"],
  82         help="set log level, default is info",
  83         default="info",
  84         type=str,
  85     )
  86     parser.add_argument(
  87         "--json_file",
  88         help='name of json file, default is "setup.json"',
  89         type=str,
  90     )
  91     parser.add_argument(
  92         "--log_file",
  93         help='name of server log file, default is "server.log"',
  94         type=str,
  95     )
  96     parser.add_argument(
  97         "--custom_actions_module",
  98         help="python file with custom actions, default is none",
  99         type=str,
  100     )
  101     args = parser.parse_args()
  102     pymodbus_apply_logging_config(args.log.upper())
  103     Log.info("Start simulator")
  104     cmd_args = {}
  105     for argument in args.__dict__:
  106         if argument == "log":
  107             continue
  108         if args.__dict__[argument] is not None:
  109             cmd_args[argument] = args.__dict__[argument]
  110     return cmd_args
  111 
  112 
  113 async def main():
  114     """Run server."""
  115     cmd_args = get_commandline()
  116     task = ModbusSimulatorServer(**cmd_args)
  117 
  118     await task.run_forever()
  119 
  120 
  121 if __name__ == "__main__":
  122     asyncio.run(main(), debug=True)
  123
  ```
  --- 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
  @@ -47,10 +47,6 @@
   from pymodbus.server.simulator.http_server import ModbusSimulatorServer
   
   
  -async def run():
  -    """Run simulator."""
  -
  -
   def get_commandline():
       """Get command line arguments."""
       parser = argparse.ArgumentParser(
  @@ -110,13 +106,12 @@
       return cmd_args
   
   
  -async def main():
  +def main():
       """Run server."""
       cmd_args = get_commandline()
       task = ModbusSimulatorServer(**cmd_args)
  -
  -    await task.run_forever()
  +    asyncio.run(task.run_forever(), debug=True)
   
   
   if __name__ == "__main__":
  -    asyncio.run(main(), debug=True)
  +    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@@ -47,10 +47,6 @@\n from pymodbus.server.simulator.http_server import ModbusSimulatorServer\n \n \n-async def run():\n-    \"\"\"Run simulator.\"\"\"\n-\n-\n def get_commandline():\n     \"\"\"Get command line arguments.\"\"\"\n     parser = argparse.ArgumentParser(\n@@ -110,13 +106,12 @@\n     return cmd_args\n \n \n-async def main():\n+def main():\n     \"\"\"Run server.\"\"\"\n     cmd_args = get_commandline()\n     task = ModbusSimulatorServer(**cmd_args)\n-\n-    await task.run_forever()\n+    asyncio.run(task.run_forever(), debug=True)\n \n \n if __name__ == \"__main__\":\n-    asyncio.run(main(), debug=True)\n+    main()\n", "issue": "Can't run pymodbus.simulator --help\n<!--\r\n\r\nBefore opening a new issue, make sure you do the following:\r\n    * check that your issue isn't already filed: https://github.com/pymodbus-dev/pymodbus/issues\r\n    * check the discussions forum https://github.com/pymodbus-dev/pymodbus/discussions\r\n    * prepare a short, runnable example that reproduce the issue with the latest development version of Pymodbus\r\n\r\n    Before opening a new issue, make sure you do the following\r\n-->\r\n\r\n### Versions\r\n\r\n* Python: 3.10.6\r\n* OS: Linux\r\n* Pymodbus: 3.1.3\r\n* Modbus Hardware (if used):\r\n\r\n### Description\r\n\r\nTrying to run `pymodbus.simulator --help` fails:\r\n\r\n```\r\n<coroutine object main at 0x7efcc073cf90>\r\nsys:1: RuntimeWarning: coroutine 'main' was never awaited\r\nRuntimeWarning: Enable tracemalloc to get the object allocation traceback\r\n```\r\n\r\nThe `main` function used as entry point for the simulator is an async function: https://github.com/pymodbus-dev/pymodbus/blob/12859d0b82cc215a18ac757fe9319cdf1f9ec890/pymodbus/server/simulator/main.py#L113\r\n\r\nIt can't be used directly as an entry point. The entry point should be a function using `asyncio.run`.\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\nasync def run():\n    \"\"\"Run simulator.\"\"\"\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 main():\n    \"\"\"Run server.\"\"\"\n    cmd_args = get_commandline()\n    task = ModbusSimulatorServer(**cmd_args)\n\n    await task.run_forever()\n\n\nif __name__ == \"__main__\":\n    asyncio.run(main(), debug=True)\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\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"}]}