diff --git a/Dockerfile b/Dockerfile
index b3377b38..76a9fa13 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -14,7 +14,7 @@ ENV PATH="/opt/venv/bin:$PATH"
COPY . ${INSTALL_DIR}/
-RUN pip install openwrt-luci-rpc graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros git+https://github.com/foreign-sub/aiofreepybox.git \
+RUN pip install openwrt-luci-rpc asusrouter asyncio aiohttp graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros git+https://github.com/foreign-sub/aiofreepybox.git \
&& bash -c "find ${INSTALL_DIR} -type d -exec chmod 750 {} \;" \
&& bash -c "find ${INSTALL_DIR} -type f -exec chmod 640 {} \;" \
&& bash -c "find ${INSTALL_DIR} -type f \( -name '*.sh' -o -name '*.py' -o -name 'speedtest-cli' \) -exec chmod 750 {} \;"
diff --git a/Dockerfile.debian b/Dockerfile.debian
index 193fe796..736b61f5 100755
--- a/Dockerfile.debian
+++ b/Dockerfile.debian
@@ -43,7 +43,7 @@ RUN phpenmod -v 8.2 sqlite3
RUN apt-get install -y python3-venv
RUN python3 -m venv myenv
-RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install openwrt-luci-rpc graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros "
+RUN /bin/bash -c "source myenv/bin/activate && update-alternatives --install /usr/bin/python python /usr/bin/python3 10 && pip3 install openwrt-luci-rpc asusrouter asyncio aiohttp graphene flask netifaces tplink-omada-client wakeonlan pycryptodome requests paho-mqtt scapy cron-converter pytz json2table dhcp-leases pyunifi speedtest-cli chardet python-nmap dnspython librouteros "
# Create a buildtimestamp.txt to later check if a new version was released
RUN date +%s > ${INSTALL_DIR}/front/buildtimestamp.txt
diff --git a/front/plugins/README.md b/front/plugins/README.md
index 693b0255..f917d905 100755
--- a/front/plugins/README.md
+++ b/front/plugins/README.md
@@ -40,6 +40,7 @@ Device-detecting plugins insert values into the `CurrentScan` database table. T
| `INTRSPD` | ♻ | Internet speed test | | | Script | [internet_speedtest](/front/plugins/internet_speedtest/) |
| `IPNEIGH` | 🔍 | Scan ARP (IPv4) and NDP (IPv6) tables | | | Script | [ipneigh](/front/plugins/ipneigh/) |
| `LUCIRPC` | 🔍 | Import connected devices from OpenWRT | | | Script | [luci_import](/front/plugins/luci_import/) |
+| `ASUSWRT` | 🔍 | Import connected devices from AsusWRT | | | Script | [asuswrt_import](/front/plugins/asuswrt_import/) |
| `MAINT` | ⚙ | Maintenance of logs, etc. | | | Script | [maintenance](/front/plugins/maintenance/) |
| `MQTT` | ▶️ | MQTT for synching to Home Assistant | | | Script | [_publisher_mqtt](/front/plugins/_publisher_mqtt/) |
| `NBTSCAN` | 🆎 | Nbtscan (NetBIOS-based) name resolution | | | Script | [nbtscan_scan](/front/plugins/nbtscan_scan/) |
diff --git a/front/plugins/asuswrt_import/README.md b/front/plugins/asuswrt_import/README.md
new file mode 100755
index 00000000..7bcb1b05
--- /dev/null
+++ b/front/plugins/asuswrt_import/README.md
@@ -0,0 +1,14 @@
+## Overview
+
+Plugin that imports device IP, MAC, Name, Vendor and Online status from AsusWRT and AsusWRT-Merlin based routers.
+
+This Plugin is using awesome [asusrouter](https://github.com/Vaskivskyi/asusrouter) library. Please check if your router is supported by it [here](https://github.com/Vaskivskyi/asusrouter?tab=readme-ov-file#supported-devices).
+
+### Usage
+
+- Enable the `ASUSWRT` plugin
+- Head to **Settings** > **AsusWRT device import** to adjust the default values.
+
+### Notes
+
+- In case an existing imported device is renamed in Asus Router it will not be renamed in NetAlertX. In this case it has to be done manually or the device should be removed and it will appear on the next scan.
diff --git a/front/plugins/asuswrt_import/config.json b/front/plugins/asuswrt_import/config.json
new file mode 100755
index 00000000..f25d08df
--- /dev/null
+++ b/front/plugins/asuswrt_import/config.json
@@ -0,0 +1,528 @@
+{
+ "code_name": "asuswrt_import",
+ "show_ui": true,
+ "unique_prefix": "ASUSWRT",
+ "plugin_type": "device_scanner",
+ "execution_order": "Layer_1",
+ "enabled": true,
+ "data_source": "script",
+ "mapped_to_table": "CurrentScan",
+ "data_filters": [
+ {
+ "compare_column": "Object_PrimaryID",
+ "compare_operator": "==",
+ "compare_field_id": "txtMacFilter",
+ "compare_js_template": "'{value}'.toString()",
+ "compare_use_quotes": true
+ }
+ ],
+ "localized": [
+ "display_name",
+ "description",
+ "icon"
+ ],
+ "display_name": [
+ {
+ "language_code": "en_us",
+ "string": "AsusWRT device import"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "The plugin is used to import connected devices from AsusWRT"
+ }
+ ],
+ "icon": [
+ {
+ "language_code": "en_us",
+ "string": ""
+ }
+ ],
+ "params": [],
+ "settings": [
+ {
+ "function": "RUN",
+ "events": [
+ "run"
+ ],
+ "type": {
+ "dataType": "string",
+ "elements": [
+ {
+ "elementType": "select",
+ "elementOptions": [],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": "disabled",
+ "options": [
+ "disabled",
+ "once",
+ "schedule"
+ ],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "When to run"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "When the plugin should run. Good options are schedule"
+ }
+ ]
+ },
+ {
+ "function": "RUN_SCHD",
+ "type": {
+ "dataType": "string",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": "*/5 * * * *",
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Schedule"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Only enabled if you select schedule in the SYNC_RUN setting. Make sure you enter the schedule in the correct cron-like format (e.g. validate at crontab.guru). For example entering 0 4 * * * will run the scan after 4 am in the TIMEZONE you set above. Will be run NEXT time the time passes."
+ }
+ ]
+ },
+ {
+ "function": "CMD",
+ "type": {
+ "dataType": "string",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [
+ {
+ "readonly": "true"
+ }
+ ],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": "python3 /app/front/plugins/asuswrt_import/script.py",
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Command"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Command to run. This can not be changed"
+ }
+ ]
+ },
+ {
+ "function": "RUN_TIMEOUT",
+ "type": {
+ "dataType": "integer",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [
+ {
+ "type": "number"
+ }
+ ],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": 30,
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Run timeout"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted."
+ }
+ ]
+ },
+ {
+ "function": "host",
+ "type": {
+ "dataType": "string",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": "192.168.1.1",
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Router ip"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Router ip(do not include http:// or https://)."
+ }
+ ]
+ },
+ {
+ "function": "user",
+ "type": {
+ "dataType": "string",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": "admin",
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Router user"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "User name used to login into your router."
+ }
+ ]
+ },
+ {
+ "function": "password",
+ "type": {
+ "dataType": "string",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [
+ {
+ "type": "password"
+ }
+ ],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": "",
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Router password"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "Password used to login into your router."
+ }
+ ]
+ },
+ {
+ "function": "ssl",
+ "type": {
+ "dataType": "boolean",
+ "elements": [
+ {
+ "elementType": "input",
+ "elementOptions": [
+ {
+ "type": "checkbox"
+ }
+ ],
+ "transformers": []
+ }
+ ]
+ },
+ "default_value": false,
+ "options": [],
+ "localized": [
+ "name",
+ "description"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Router SSL"
+ }
+ ],
+ "description": [
+ {
+ "language_code": "en_us",
+ "string": "If your router enforces SSL connections."
+ }
+ ]
+ }
+ ],
+ "database_column_definitions": [
+ {
+ "column": "Index",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "none",
+ "default_value": "",
+ "options": [],
+ "localized": [
+ "name"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Index"
+ }
+ ]
+ },
+ {
+ "column": "Object_PrimaryID",
+ "css_classes": "col-sm-2",
+ "default_value": "",
+ "localized": [
+ "name"
+ ],
+ "mapped_to_column": "cur_MAC",
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "MAC address"
+ },
+ {
+ "language_code": "es_es",
+ "string": "Dirección MAC"
+ },
+ {
+ "language_code": "de_de",
+ "string": "MAC Adresse"
+ }
+ ],
+ "options": [],
+ "show": true,
+ "type": "device_mac"
+ },
+ {
+ "column": "Object_SecondaryID",
+ "css_classes": "col-sm-2",
+ "default_value": "",
+ "localized": [
+ "name"
+ ],
+ "mapped_to_column": "cur_IP",
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "IP"
+ },
+ {
+ "language_code": "es_es",
+ "string": "IP"
+ },
+ {
+ "language_code": "de_de",
+ "string": "IP"
+ }
+ ],
+ "options": [],
+ "show": true,
+ "type": "device_ip"
+ },
+ {
+ "column": "Watched_Value1",
+ "css_classes": "col-sm-2",
+ "default_value": "",
+ "localized": [
+ "name"
+ ],
+ "mapped_to_column": "cur_Name",
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Hostname"
+ },
+ {
+ "language_code": "es_es",
+ "string": "Nombre de host"
+ },
+ {
+ "language_code": "de_de",
+ "string": "Name des Hosts"
+ }
+ ],
+ "options": [],
+ "show": true,
+ "type": "label"
+ },
+ {
+ "column": "Watched_Value2",
+ "mapped_to_column": "cur_Vendor",
+ "css_classes": "col-sm-2",
+ "default_value": "",
+ "localized": [
+ "name"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Vendor"
+ },
+ {
+ "language_code": "es_es",
+ "string": "Proveedor"
+ },
+ {
+ "language_code": "de_de",
+ "string": "Hersteller"
+ }
+ ],
+ "options": [],
+ "show": true,
+ "type": "label"
+ },
+ {
+ "column": "Dummy",
+ "mapped_to_column": "cur_ScanMethod",
+ "mapped_to_column_data": {
+ "value": "ASUSWRT"
+ },
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "label",
+ "default_value": "",
+ "options": [],
+ "localized": [
+ "name"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Scan method"
+ }
+ ]
+ },
+ {
+ "column": "DateTimeCreated",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "label",
+ "default_value": "",
+ "options": [],
+ "localized": [
+ "name"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Created"
+ }
+ ]
+ },
+ {
+ "column": "DateTimeChanged",
+ "css_classes": "col-sm-2",
+ "show": true,
+ "type": "label",
+ "default_value": "",
+ "options": [],
+ "localized": [
+ "name"
+ ],
+ "name": [
+ {
+ "language_code": "en_us",
+ "string": "Changed"
+ }
+ ]
+ },
+ {
+ "column": "Status",
+ "css_classes": "col-sm-1",
+ "show": true,
+ "type": "replace",
+ "default_value": "",
+ "options": [
+ {
+ "equals": "watched-not-changed",
+ "replacement": "