tplinkrouterc6u 5.4.0__tar.gz → 5.4.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/PKG-INFO +17 -5
  2. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/README.md +6 -3
  3. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/setup.py +1 -1
  4. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/test_client_c6u.py +28 -0
  5. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/test_client_deco.py +26 -0
  6. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/test_client_ex.py +29 -0
  7. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/test_client_mr.py +24 -0
  8. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/test_client_xdr.py +46 -0
  9. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/c6u.py +12 -12
  10. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/c6v4.py +4 -1
  11. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/deco.py +30 -34
  12. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/ex.py +14 -13
  13. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/mr.py +14 -13
  14. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/xdr.py +18 -10
  15. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client_abstract.py +5 -1
  16. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/common/dataclass.py +5 -1
  17. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/common/helper.py +11 -0
  18. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u.egg-info/PKG-INFO +17 -5
  19. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/LICENSE +0 -0
  20. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/setup.cfg +0 -0
  21. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/__init__.py +0 -0
  22. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/test/test_client_c1200.py +0 -0
  23. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/__init__.py +0 -0
  24. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/__init__.py +0 -0
  25. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/c1200.py +0 -0
  26. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/client/c5400x.py +0 -0
  27. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/common/__init__.py +0 -0
  28. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/common/encryption.py +0 -0
  29. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/common/exception.py +0 -0
  30. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/common/package_enum.py +0 -0
  31. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u/provider.py +0 -0
  32. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u.egg-info/SOURCES.txt +0 -0
  33. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u.egg-info/dependency_links.txt +0 -0
  34. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u.egg-info/requires.txt +0 -0
  35. {tplinkrouterc6u-5.4.0 → tplinkrouterc6u-5.4.2}/tplinkrouterc6u.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: tplinkrouterc6u
3
- Version: 5.4.0
3
+ Version: 5.4.2
4
4
  Summary: TP-Link Router API
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -19,6 +19,15 @@ License-File: LICENSE
19
19
  Requires-Dist: requests
20
20
  Requires-Dist: pycryptodome
21
21
  Requires-Dist: macaddress
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
22
31
 
23
32
  # TP-Link Router API
24
33
  Python package for API access and management for TP-Link Routers. See [Supported routers](#supports)
@@ -280,7 +289,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
280
289
  - Archer AX20 v1.0
281
290
  - Archer AX20 v3.0
282
291
  - Archer AX21 (v1.20, v3.0)
283
- - Archer AX23 v1.0
292
+ - Archer AX23 (v1.0, v1.2)
284
293
  - Archer AX50 v1.0
285
294
  - Archer AX53 v2
286
295
  - Archer AX55 (v1.0, V1.60, v4.0)
@@ -290,6 +299,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
290
299
  - Archer AX90 V1.20
291
300
  - Archer AXE75 V1
292
301
  - Archer AXE16000
302
+ - Archer AX1800
293
303
  - Archer AX3000 V1
294
304
  - Archer AX6000 V1
295
305
  - Archer AX11000 V1
@@ -309,6 +319,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
309
319
  - Archer VR600 v3
310
320
  - Archer VR900v
311
321
  - Archer VR2100v v1
322
+ - Archer VX1800v v1.0
312
323
  - Deco M4 2.0
313
324
  - Deco M4R 2.0
314
325
  - Deco M5 v3
@@ -321,14 +332,15 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
321
332
  - Deco X90
322
333
  - Deco XE75 (v1.0, v2.0)
323
334
  - EX511 v2.0
335
+ - HX510 v1.0
336
+ - NX510v v1.0
324
337
  - TD-W9960 (v1, V1.20)
325
338
  - TL-MR100 v2.0
326
339
  - TL-MR105
327
340
  - TL-MR6400 (v5, v5.3)
328
341
  - TL-MR6500v
329
- - TL-XDR3010 V2
330
342
  - TL-WA3001 v1.0
331
- - NX510v v1.0
343
+ - TL-XDR3010 V2
332
344
 
333
345
  ### Not fully tested Hardware Versions
334
346
  - AD7200 V2
@@ -258,7 +258,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
258
258
  - Archer AX20 v1.0
259
259
  - Archer AX20 v3.0
260
260
  - Archer AX21 (v1.20, v3.0)
261
- - Archer AX23 v1.0
261
+ - Archer AX23 (v1.0, v1.2)
262
262
  - Archer AX50 v1.0
263
263
  - Archer AX53 v2
264
264
  - Archer AX55 (v1.0, V1.60, v4.0)
@@ -268,6 +268,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
268
268
  - Archer AX90 V1.20
269
269
  - Archer AXE75 V1
270
270
  - Archer AXE16000
271
+ - Archer AX1800
271
272
  - Archer AX3000 V1
272
273
  - Archer AX6000 V1
273
274
  - Archer AX11000 V1
@@ -287,6 +288,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
287
288
  - Archer VR600 v3
288
289
  - Archer VR900v
289
290
  - Archer VR2100v v1
291
+ - Archer VX1800v v1.0
290
292
  - Deco M4 2.0
291
293
  - Deco M4R 2.0
292
294
  - Deco M5 v3
@@ -299,14 +301,15 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
299
301
  - Deco X90
300
302
  - Deco XE75 (v1.0, v2.0)
301
303
  - EX511 v2.0
304
+ - HX510 v1.0
305
+ - NX510v v1.0
302
306
  - TD-W9960 (v1, V1.20)
303
307
  - TL-MR100 v2.0
304
308
  - TL-MR105
305
309
  - TL-MR6400 (v5, v5.3)
306
310
  - TL-MR6500v
307
- - TL-XDR3010 V2
308
311
  - TL-WA3001 v1.0
309
- - NX510v v1.0
312
+ - TL-XDR3010 V2
310
313
 
311
314
  ### Not fully tested Hardware Versions
312
315
  - AD7200 V2
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
5
5
 
6
6
  setuptools.setup(
7
7
  name="tplinkrouterc6u",
8
- version="5.4.0",
8
+ version="5.4.2",
9
9
  author="Alex Erohin",
10
10
  author_email="alexanderErohin@yandex.ru",
11
11
  description="TP-Link Router API",
@@ -6,6 +6,7 @@ from tplinkrouterc6u import (
6
6
  TplinkRouter,
7
7
  Connection,
8
8
  Status,
9
+ IPv4Status,
9
10
  Device,
10
11
  ClientException,
11
12
  )
@@ -694,6 +695,33 @@ class TestTPLinkClient(TestCase):
694
695
  self.assertEqual(check_url, 'admin/wireless?&form=guest&form=iot_6g')
695
696
  self.assertEqual(check_data, 'operation=write&iot_6g_enable=on')
696
697
 
698
+ def test_get_ipv4_status_empty(self) -> None:
699
+ response_network = '{"result": {}, "error_code": 0}'
700
+
701
+ class TPLinkRouterTest(TplinkRouter):
702
+ def request(self, path: str, data: str,
703
+ ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
704
+ if path == 'admin/network?form=status_ipv4&operation=read':
705
+ return loads(response_network)['result']
706
+ raise ClientException()
707
+
708
+ client = TPLinkRouterTest('', '')
709
+ result = client.get_ipv4_status()
710
+
711
+ self.assertIsInstance(result, IPv4Status)
712
+ self.assertEqual(result.wan_macaddr, '00-00-00-00-00-00')
713
+ self.assertEqual(result.wan_ipv4_ipaddr, '0.0.0.0')
714
+ self.assertEqual(result.wan_ipv4_gateway, '0.0.0.0')
715
+ self.assertEqual(result.wan_ipv4_conntype, '')
716
+ self.assertEqual(result.wan_ipv4_netmask, '0.0.0.0')
717
+ self.assertEqual(result.wan_ipv4_pridns, '0.0.0.0')
718
+ self.assertEqual(result.wan_ipv4_snddns, '0.0.0.0')
719
+ self.assertEqual(result.lan_macaddr, '00-00-00-00-00-00')
720
+ self.assertEqual(result.lan_ipv4_ipaddr, '0.0.0.0')
721
+ self.assertEqual(result.lan_ipv4_netmask, '0.0.0.0')
722
+ self.assertEqual(result.lan_ipv4_dhcp_enable, False)
723
+ self.assertEqual(result.remote, None)
724
+
697
725
 
698
726
  if __name__ == '__main__':
699
727
  main()
@@ -365,6 +365,32 @@ class TestTPLinkDecoClient(TestCase):
365
365
  self.assertEqual(result.lan_ipv4_dhcp_enable, False)
366
366
  self.assertEqual(result.remote, None)
367
367
 
368
+ def test_get_ipv4_status_empty(self) -> None:
369
+ response_network = '{"result": {}, "error_code": 0}'
370
+
371
+ class TPLinkRouterTest(TPLinkDecoClient):
372
+ def request(self, path: str, data: str,
373
+ ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
374
+ if path == 'admin/network?form=wan_ipv4':
375
+ return loads(response_network)['result']
376
+
377
+ client = TPLinkRouterTest('', '')
378
+ result = client.get_ipv4_status()
379
+
380
+ self.assertIsInstance(result, IPv4Status)
381
+ self.assertEqual(result.wan_macaddr, '00-00-00-00-00-00')
382
+ self.assertEqual(result.wan_ipv4_ipaddr, None)
383
+ self.assertEqual(result.wan_ipv4_gateway, None)
384
+ self.assertEqual(result.wan_ipv4_conntype, '')
385
+ self.assertEqual(result.wan_ipv4_netmask, None)
386
+ self.assertEqual(result.wan_ipv4_pridns, '0.0.0.0')
387
+ self.assertEqual(result.wan_ipv4_snddns, '0.0.0.0')
388
+ self.assertEqual(result.lan_macaddr, '00-00-00-00-00-00')
389
+ self.assertEqual(result.lan_ipv4_ipaddr, '0.0.0.0')
390
+ self.assertEqual(result.lan_ipv4_netmask, '0.0.0.0')
391
+ self.assertEqual(result.lan_ipv4_dhcp_enable, False)
392
+ self.assertEqual(result.remote, None)
393
+
368
394
  def test_get_ipv4_status_no_internet(self) -> None:
369
395
  response_network = '''
370
396
  {"result": {
@@ -277,6 +277,35 @@ class TestTPLinkEXClient(TestCase):
277
277
  self.assertEqual(result.lan_ipv4_dhcp_enable, True)
278
278
  self.assertEqual(result.remote, None)
279
279
 
280
+ def test_get_ipv4_status_empty(self) -> None:
281
+
282
+ DEV2_ADT_LAN = ('{"data":[],"operation":"gl","oid":"DEV2_ADT_LAN","success":true}')
283
+ DEV2_ADT_WAN = ('{"data":[],"operation":"gl","oid":"DEV2_ADT_WAN","success":true}')
284
+
285
+ class TPLinkEXClientTest(TPLinkEXClient):
286
+ self._token = True
287
+
288
+ def _request(self, url, method='POST', data_str=None, encrypt=False):
289
+ if 'DEV2_ADT_LAN' in data_str:
290
+ return 200, DEV2_ADT_LAN
291
+ elif 'DEV2_ADT_WAN' in data_str:
292
+ return 200, DEV2_ADT_WAN
293
+ raise ClientException()
294
+
295
+ client = TPLinkEXClientTest('', '')
296
+ result = client.get_ipv4_status()
297
+
298
+ self.assertIsInstance(result, IPv4Status)
299
+ self.assertEqual(result.wan_ipv4_ipaddr, None)
300
+ self.assertEqual(result.wan_ipv4_gateway, None)
301
+ self.assertEqual(result.wan_ipv4_netmask, None)
302
+ self.assertEqual(result.wan_ipv4_conntype, '')
303
+ self.assertEqual(result.lan_macaddr, '00-00-00-00-00-00')
304
+ self.assertEqual(result.lan_ipv4_ipaddr, '0.0.0.0')
305
+ self.assertEqual(result.lan_ipv4_netmask, '0.0.0.0')
306
+ self.assertEqual(result.lan_ipv4_dhcp_enable, False)
307
+ self.assertEqual(result.remote, None)
308
+
280
309
  def test_get_ipv4_status_one_wlan(self) -> None:
281
310
 
282
311
  DEV2_ADT_LAN = ('{"data":[{"MACAddress":"bf:75:44:4c:dc:9e","IPAddress":"192.168.5.1",'
@@ -599,6 +599,30 @@ DNSServers=7.7.7.7,2.2.2.2
599
599
  self.assertEqual(result.lan_ipv4_dhcp_enable, True)
600
600
  self.assertEqual(result.remote, None)
601
601
 
602
+ def test_get_ipv4_status_empty(self) -> None:
603
+ response = '''
604
+ [1,1,0,0,0,0]0
605
+ [1,1,0,0,0,0]1
606
+ [1,1,1,0,0,0]2
607
+ [2,1,1,0,0,0]2
608
+ [error]0
609
+
610
+ '''
611
+
612
+ class TPLinkMRClientTest(TPLinkMRClient):
613
+ def _request(self, url, method='POST', data_str=None, encrypt=False):
614
+ return 200, response
615
+
616
+ client = TPLinkMRClientTest('', '')
617
+ result = client.get_ipv4_status()
618
+
619
+ self.assertIsInstance(result, IPv4Status)
620
+ self.assertEqual(result.lan_macaddr, '00-00-00-00-00-00')
621
+ self.assertEqual(result.wan_ipv4_conntype, '')
622
+ self.assertEqual(result.lan_ipv4_ipaddr, '0.0.0.0')
623
+ self.assertEqual(result.lan_ipv4_netmask, '0.0.0.0')
624
+ self.assertEqual(result.lan_ipv4_dhcp_enable, False)
625
+
602
626
  def test_get_ipv4_status_one_wlan(self) -> None:
603
627
  response = '''
604
628
  [1,1,0,0,0,0]0
@@ -579,6 +579,52 @@ maximum-scale=2.0, user-scalable=yes" />
579
579
  self.assertIsInstance(ipv4_status.lan_ipv4_netmask_address, IPv4Address)
580
580
  self.assertEqual(ipv4_status.lan_ipv4_netmask_address, get_ip('255.255.255.0'))
581
581
 
582
+ def test_get_ipv4_status_empty(self):
583
+ mock_data = json.loads('{"error_code": 0}')
584
+ check_payload = {}
585
+
586
+ class TPLinkXDRClientTest(TPLinkXDRClient):
587
+ def _request(self, payload: dict) -> dict:
588
+ nonlocal check_payload
589
+ check_payload = payload
590
+ return mock_data
591
+
592
+ client = TPLinkXDRClientTest('', '')
593
+ ipv4_status = client.get_ipv4_status()
594
+
595
+ self.assertEqual(check_payload['method'], 'get')
596
+ self.assertIsInstance(check_payload['dhcpd'], dict)
597
+ self.assertEqual(check_payload['dhcpd']['name'], 'udhcpd')
598
+ self.assertIsInstance(check_payload['network'], dict)
599
+ self.assertEqual(check_payload['network']['name'], ['lan', 'wan_status'])
600
+
601
+ self.assertIsInstance(ipv4_status, IPv4Status)
602
+ self.assertEqual(ipv4_status.wan_ipv4_ipaddr, '0.0.0.0')
603
+ self.assertIsInstance(ipv4_status.wan_ipv4_ipaddress, IPv4Address)
604
+ self.assertEqual(ipv4_status.wan_ipv4_ipaddress, get_ip('0.0.0.0'))
605
+ self.assertEqual(ipv4_status.wan_ipv4_gateway, '0.0.0.0')
606
+ self.assertIsInstance(ipv4_status.wan_ipv4_gateway_address, IPv4Address)
607
+ self.assertEqual(ipv4_status.wan_ipv4_gateway_address, get_ip('0.0.0.0'))
608
+ self.assertEqual(ipv4_status.wan_ipv4_netmask, '0.0.0.0')
609
+ self.assertIsInstance(ipv4_status.wan_ipv4_netmask_address, IPv4Address)
610
+ self.assertEqual(ipv4_status.wan_ipv4_netmask_address, get_ip('0.0.0.0'))
611
+ self.assertEqual(ipv4_status.wan_ipv4_pridns, '0.0.0.0')
612
+ self.assertIsInstance(ipv4_status.wan_ipv4_pridns_address, IPv4Address)
613
+ self.assertEqual(ipv4_status.wan_ipv4_pridns_address, get_ip('0.0.0.0'))
614
+ self.assertEqual(ipv4_status.wan_ipv4_snddns, '0.0.0.0')
615
+ self.assertIsInstance(ipv4_status.wan_ipv4_snddns_address, IPv4Address)
616
+ self.assertEqual(ipv4_status.wan_ipv4_snddns_address, get_ip('0.0.0.0'))
617
+ self.assertEqual(ipv4_status.lan_macaddr, '00-00-00-00-00-00')
618
+ self.assertIsInstance(ipv4_status.lan_macaddress, EUI48)
619
+ self.assertEqual(ipv4_status.lan_macaddress, get_mac('00-00-00-00-00-00'))
620
+ self.assertEqual(ipv4_status.lan_ipv4_ipaddr, '0.0.0.0')
621
+ self.assertIsInstance(ipv4_status.lan_ipv4_ipaddress, IPv4Address)
622
+ self.assertEqual(ipv4_status.lan_ipv4_ipaddress, get_ip('0.0.0.0'))
623
+ self.assertEqual(ipv4_status.lan_ipv4_dhcp_enable, False)
624
+ self.assertEqual(ipv4_status.lan_ipv4_netmask, '0.0.0.0')
625
+ self.assertIsInstance(ipv4_status.lan_ipv4_netmask_address, IPv4Address)
626
+ self.assertEqual(ipv4_status.lan_ipv4_netmask_address, get_ip('0.0.0.0'))
627
+
582
628
 
583
629
  if __name__ == '__main__':
584
630
  main()
@@ -363,18 +363,18 @@ class TplinkBaseRouter(AbstractRouter, TplinkRequest):
363
363
  def get_ipv4_status(self) -> IPv4Status:
364
364
  ipv4_status = IPv4Status()
365
365
  data = self.request('admin/network?form=status_ipv4&operation=read', 'operation=read')
366
- ipv4_status._wan_macaddr = EUI48(data['wan_macaddr'])
367
- ipv4_status._wan_ipv4_ipaddr = IPv4Address(data['wan_ipv4_ipaddr'])
368
- ipv4_status._wan_ipv4_gateway = IPv4Address(data['wan_ipv4_gateway'])
369
- ipv4_status.wan_ipv4_conntype = data['wan_ipv4_conntype']
370
- ipv4_status._wan_ipv4_netmask = IPv4Address(data['wan_ipv4_netmask'])
371
- ipv4_status._wan_ipv4_pridns = IPv4Address(data['wan_ipv4_pridns'])
372
- ipv4_status._wan_ipv4_snddns = IPv4Address(data['wan_ipv4_snddns'])
373
- ipv4_status._lan_macaddr = EUI48(data['lan_macaddr'])
374
- ipv4_status._lan_ipv4_ipaddr = IPv4Address(data['lan_ipv4_ipaddr'])
375
- ipv4_status.lan_ipv4_dhcp_enable = self._str2bool(data['lan_ipv4_dhcp_enable'])
376
- ipv4_status._lan_ipv4_netmask = IPv4Address(data['lan_ipv4_netmask'])
377
- ipv4_status.remote = self._str2bool(data.get('remote'))
366
+ ipv4_status._wan_macaddr = get_mac(data.get('wan_macaddr', '00:00:00:00:00:00'))
367
+ ipv4_status._wan_ipv4_ipaddr = get_ip(data.get('wan_ipv4_ipaddr', '0.0.0.0'))
368
+ ipv4_status._wan_ipv4_gateway = get_ip(data.get('wan_ipv4_gateway', '0.0.0.0'))
369
+ ipv4_status._wan_ipv4_conntype = data.get('wan_ipv4_conntype', '')
370
+ ipv4_status._wan_ipv4_netmask = get_ip(data.get('wan_ipv4_netmask', '0.0.0.0'))
371
+ ipv4_status._wan_ipv4_pridns = get_ip(data.get('wan_ipv4_pridns', '0.0.0.0'))
372
+ ipv4_status._wan_ipv4_snddns = get_ip(data.get('wan_ipv4_snddns', '0.0.0.0'))
373
+ ipv4_status._lan_macaddr = get_mac(data.get('lan_macaddr', '00:00:00:00:00:00'))
374
+ ipv4_status._lan_ipv4_ipaddr = get_ip(data.get('lan_ipv4_ipaddr', '0.0.0.0'))
375
+ ipv4_status.lan_ipv4_dhcp_enable = self._str2bool(data.get('lan_ipv4_dhcp_enable', ''))
376
+ ipv4_status._lan_ipv4_netmask = get_ip(data.get('lan_ipv4_netmask', '0.0.0.0'))
377
+ ipv4_status.remote = self._str2bool(data.get('remote', '')) if data.get('remote') else None
378
378
 
379
379
  return ipv4_status
380
380
 
@@ -1,6 +1,6 @@
1
1
  from requests import post
2
2
  from tplinkrouterc6u.common.package_enum import Connection
3
- from tplinkrouterc6u.common.dataclass import Firmware, Status
3
+ from tplinkrouterc6u.common.dataclass import Firmware, Status, IPv4Status
4
4
  from tplinkrouterc6u.common.exception import ClientException
5
5
  from tplinkrouterc6u.client_abstract import AbstractRouter
6
6
 
@@ -31,6 +31,9 @@ class TplinkC6V4Router(AbstractRouter):
31
31
  def get_status(self) -> Status:
32
32
  raise ClientException('Not Implemented')
33
33
 
34
+ def get_ipv4_status(self) -> IPv4Status:
35
+ raise ClientException('Not Implemented')
36
+
34
37
  def reboot(self) -> None:
35
38
  raise ClientException('Not Implemented')
36
39
 
@@ -3,7 +3,7 @@ from json import dumps
3
3
  from macaddress import EUI48
4
4
  from ipaddress import IPv4Address
5
5
  from logging import Logger
6
- from tplinkrouterc6u.common.helper import get_ip, get_mac
6
+ from tplinkrouterc6u.common.helper import get_ip, get_mac, get_value
7
7
  from tplinkrouterc6u.common.package_enum import Connection
8
8
  from tplinkrouterc6u.common.dataclass import Firmware, Status, Device, IPv4Status
9
9
  from tplinkrouterc6u.client_abstract import AbstractRouter
@@ -67,14 +67,14 @@ class TPLinkDecoClient(TplinkEncryption, AbstractRouter):
67
67
  data = self.request('admin/network?form=wan_ipv4', dumps({'operation': 'read'}))
68
68
 
69
69
  status = Status()
70
- element = self._get_value(data, ['wan', 'ip_info', 'mac'])
70
+ element = get_value(data, ['wan', 'ip_info', 'mac'])
71
71
  status._wan_macaddr = EUI48(element) if element else None
72
- status._lan_macaddr = EUI48(self._get_value(data, ['lan', 'ip_info', 'mac']))
73
- element = self._get_value(data, ['wan', 'ip_info', 'ip'])
72
+ status._lan_macaddr = EUI48(get_value(data, ['lan', 'ip_info', 'mac']))
73
+ element = get_value(data, ['wan', 'ip_info', 'ip'])
74
74
  status._wan_ipv4_addr = IPv4Address(element) if element else None
75
- element = self._get_value(data, ['lan', 'ip_info', 'ip'])
75
+ element = get_value(data, ['lan', 'ip_info', 'ip'])
76
76
  status._lan_ipv4_addr = IPv4Address(element) if element else None
77
- element = self._get_value(data, ['wan', 'ip_info', 'gateway'])
77
+ element = get_value(data, ['wan', 'ip_info', 'gateway'])
78
78
  status._wan_ipv4_gateway = IPv4Address(element) if element else None
79
79
 
80
80
  data = self.request('admin/network?form=performance', dumps({"operation": "read"}))
@@ -82,12 +82,12 @@ class TPLinkDecoClient(TplinkEncryption, AbstractRouter):
82
82
  status.cpu_usage = data.get('cpu_usage')
83
83
 
84
84
  data = self.request('admin/wireless?form=wlan', dumps({'operation': 'read'}))
85
- status.wifi_2g_enable = self._get_value(data, ['band2_4', 'host', 'enable'])
86
- status.guest_2g_enable = self._get_value(data, ['band2_4', 'guest', 'enable'])
87
- status.wifi_5g_enable = self._get_value(data, ['band5_1', 'host', 'enable'])
88
- status.guest_5g_enable = self._get_value(data, ['band5_1', 'guest', 'enable'])
89
- status.wifi_6g_enable = self._get_value(data, ['band6', 'host', 'enable'])
90
- status.guest_6g_enable = self._get_value(data, ['band6', 'guest', 'enable'])
85
+ status.wifi_2g_enable = get_value(data, ['band2_4', 'host', 'enable'])
86
+ status.guest_2g_enable = get_value(data, ['band2_4', 'guest', 'enable'])
87
+ status.wifi_5g_enable = get_value(data, ['band5_1', 'host', 'enable'])
88
+ status.guest_5g_enable = get_value(data, ['band5_1', 'guest', 'enable'])
89
+ status.wifi_6g_enable = get_value(data, ['band6', 'host', 'enable'])
90
+ status.guest_6g_enable = get_value(data, ['band6', 'guest', 'enable'])
91
91
 
92
92
  devices = []
93
93
  data = self.request('admin/client?form=client_list', dumps(
@@ -125,34 +125,30 @@ class TPLinkDecoClient(TplinkEncryption, AbstractRouter):
125
125
  def get_ipv4_status(self) -> IPv4Status:
126
126
  ipv4_status = IPv4Status()
127
127
  data = self.request('admin/network?form=wan_ipv4', dumps({'operation': 'read'}))
128
- ipv4_status._wan_macaddr = EUI48(self._get_value(data, ['wan', 'ip_info', 'mac']))
129
- element = self._get_value(data, ['wan', 'ip_info', 'ip'])
128
+ element = get_value(data, ['wan', 'ip_info', 'mac'])
129
+ ipv4_status._wan_macaddr = get_mac(element if element else '00:00:00:00:00:00')
130
+ element = get_value(data, ['wan', 'ip_info', 'ip'])
130
131
  ipv4_status._wan_ipv4_ipaddr = IPv4Address(element) if element else None
131
- element = self._get_value(data, ['wan', 'ip_info', 'gateway'])
132
+ element = get_value(data, ['wan', 'ip_info', 'gateway'])
132
133
  ipv4_status._wan_ipv4_gateway = IPv4Address(element) if element else None
133
- ipv4_status.wan_ipv4_conntype = self._get_value(data, ['wan', 'dial_type'])
134
- element = self._get_value(data, ['wan', 'ip_info', 'mask'])
134
+ element = get_value(data, ['wan', 'dial_type'])
135
+ ipv4_status._wan_ipv4_conntype = element if element else ''
136
+ element = get_value(data, ['wan', 'ip_info', 'mask'])
135
137
  ipv4_status._wan_ipv4_netmask = IPv4Address(element) if element else None
136
- ipv4_status._wan_ipv4_pridns = IPv4Address(self._get_value(data, ['wan', 'ip_info', 'dns1']))
137
- ipv4_status._wan_ipv4_snddns = IPv4Address(self._get_value(data, ['wan', 'ip_info', 'dns2']))
138
- ipv4_status._lan_macaddr = EUI48(self._get_value(data, ['lan', 'ip_info', 'mac']))
139
- ipv4_status._lan_ipv4_ipaddr = IPv4Address(self._get_value(data, ['lan', 'ip_info', 'ip']))
138
+ element = get_value(data, ['wan', 'ip_info', 'dns1'])
139
+ ipv4_status._wan_ipv4_pridns = get_ip(element if element else '0.0.0.0')
140
+ element = get_value(data, ['wan', 'ip_info', 'dns2'])
141
+ ipv4_status._wan_ipv4_snddns = get_ip(element if element else '0.0.0.0')
142
+ element = get_value(data, ['lan', 'ip_info', 'mac'])
143
+ ipv4_status._lan_macaddr = get_mac(element if element else '00:00:00:00:00:00')
144
+ element = get_value(data, ['lan', 'ip_info', 'ip'])
145
+ ipv4_status._lan_ipv4_ipaddr = get_ip(element if element else '0.0.0.0')
140
146
  ipv4_status.lan_ipv4_dhcp_enable = False
141
- ipv4_status._lan_ipv4_netmask = IPv4Address(self._get_value(data, ['lan', 'ip_info', 'mask']))
147
+ element = get_value(data, ['lan', 'ip_info', 'mask'])
148
+ ipv4_status._lan_ipv4_netmask = get_ip(element if element else '0.0.0.0')
142
149
 
143
150
  return ipv4_status
144
151
 
145
- @staticmethod
146
- def _get_value(dictionary: dict, keys: list):
147
- nested_dict = dictionary
148
-
149
- for key in keys:
150
- try:
151
- nested_dict = nested_dict[key]
152
- except Exception:
153
- return None
154
- return nested_dict
155
-
156
152
  def _map_wire_type(self, data: dict) -> Connection:
157
153
  if data.get('wire_type') == 'wired':
158
154
  return Connection.WIRED
@@ -160,7 +156,7 @@ class TPLinkDecoClient(TplinkEncryption, AbstractRouter):
160
156
  'band5': {'main': Connection.HOST_5G, 'guest': Connection.GUEST_5G, 'iot': Connection.IOT_5G},
161
157
  'band6': {'main': Connection.HOST_6G, 'guest': Connection.GUEST_6G, 'iot': Connection.IOT_6G}
162
158
  }
163
- result = self._get_value(mapping, [data.get('connection_type'), data.get('interface')])
159
+ result = get_value(mapping, [data.get('connection_type'), data.get('interface')])
164
160
 
165
161
  return result if result else Connection.UNKNOWN
166
162
 
@@ -5,6 +5,7 @@ from macaddress import EUI48
5
5
  from ipaddress import IPv4Address
6
6
  from logging import Logger
7
7
  from tplinkrouterc6u.common.package_enum import Connection, VPN
8
+ from tplinkrouterc6u.common.helper import get_ip, get_mac, get_value
8
9
  from tplinkrouterc6u.common.dataclass import (
9
10
  Firmware,
10
11
  Status,
@@ -203,26 +204,26 @@ class TPLinkEXClient(TPLinkMRClientBase):
203
204
  ]
204
205
  _, values = self.req_act(acts)
205
206
 
206
- if values[0].__class__ == list:
207
+ if values[0].__class__ == list and len(values[0]) > 0:
207
208
  values[0] = values[0][0]
208
209
 
209
210
  ipv4_status = IPv4Status()
210
- ipv4_status._lan_macaddr = EUI48(values[0]['MACAddress'])
211
- ipv4_status._lan_ipv4_ipaddr = IPv4Address(values[0]['IPAddress'])
212
- ipv4_status._lan_ipv4_netmask = IPv4Address(values[0]['IPSubnetMask'])
213
- ipv4_status.lan_ipv4_dhcp_enable = bool(int(values[0]['DHCPv4Enable']))
211
+ ipv4_status._lan_macaddr = get_mac(get_value(values, [0, 'MACAddress'], '00:00:00:00:00:00'))
212
+ ipv4_status._lan_ipv4_ipaddr = get_ip(get_value(values, [0, 'IPAddress'], '0.0.0.0'))
213
+ ipv4_status._lan_ipv4_netmask = get_ip(get_value(values, [0, 'IPSubnetMask'], '0.0.0.0'))
214
+ ipv4_status.lan_ipv4_dhcp_enable = bool(int(get_value(values, [0, 'DHCPv4Enable'], '0')))
214
215
 
215
216
  for item in values[1]:
216
217
  if int(item['enable']) == 0 and values[1].__class__ == list:
217
218
  continue
218
- ipv4_status._wan_macaddr = EUI48(item['MACAddr'])
219
- ipv4_status._wan_ipv4_ipaddr = IPv4Address(item['connIPv4Address'])
220
- ipv4_status._wan_ipv4_gateway = IPv4Address(item['connIPv4Gateway'])
221
- ipv4_status.wan_ipv4_conntype = item['name']
222
- ipv4_status._wan_ipv4_netmask = IPv4Address(item['connIPv4SubnetMask'])
223
- dns = item['connIPv4DnsServer'].split(',')
224
- ipv4_status._wan_ipv4_pridns = IPv4Address(dns[0])
225
- ipv4_status._wan_ipv4_snddns = IPv4Address(dns[1])
219
+ ipv4_status._wan_macaddr = get_mac(get_value(item, ['MACAddr'], '00:00:00:00:00:00'))
220
+ ipv4_status._wan_ipv4_ipaddr = get_ip(get_value(item, ['connIPv4Address'], '0.0.0.0'))
221
+ ipv4_status._wan_ipv4_gateway = get_ip(get_value(item, ['connIPv4Gateway'], '0.0.0.0'))
222
+ ipv4_status._wan_ipv4_conntype = get_value(item, ['name'], '')
223
+ ipv4_status._wan_ipv4_netmask = get_ip(get_value(item, ['connIPv4SubnetMask'], '0.0.0.0'))
224
+ dns = get_value(item, ['connIPv4DnsServer'], '').split(',')
225
+ ipv4_status._wan_ipv4_pridns = get_ip(dns[0] if len(dns) > 0 else '0.0.0.0')
226
+ ipv4_status._wan_ipv4_snddns = get_ip(dns[1] if len(dns) > 1 else '0.0.0.0')
226
227
 
227
228
  return ipv4_status
228
229
 
@@ -7,6 +7,7 @@ from datetime import timedelta, datetime
7
7
  from macaddress import EUI48
8
8
  from ipaddress import IPv4Address
9
9
  from logging import Logger
10
+ from tplinkrouterc6u.common.helper import get_ip, get_mac, get_value
10
11
  from tplinkrouterc6u.common.encryption import EncryptionWrapperMR
11
12
  from tplinkrouterc6u.common.package_enum import Connection, VPN
12
13
  from tplinkrouterc6u.common.dataclass import (
@@ -542,22 +543,22 @@ class TPLinkMRClient(TPLinkMRClientBase):
542
543
  _, values = self.req_act(acts)
543
544
 
544
545
  ipv4_status = IPv4Status()
545
- ipv4_status._lan_macaddr = EUI48(values['0']['X_TP_MACAddress'])
546
- ipv4_status._lan_ipv4_ipaddr = IPv4Address(values['0']['IPInterfaceIPAddress'])
547
- ipv4_status._lan_ipv4_netmask = IPv4Address(values['0']['IPInterfaceSubnetMask'])
548
- ipv4_status.lan_ipv4_dhcp_enable = bool(int(values['1']['DHCPServerEnable']))
546
+ ipv4_status._lan_macaddr = get_mac(get_value(values, ['0', 'X_TP_MACAddress'], '00:00:00:00:00:00'))
547
+ ipv4_status._lan_ipv4_ipaddr = get_ip(get_value(values, ['0', 'IPInterfaceIPAddress'], '0.0.0.0'))
548
+ ipv4_status._lan_ipv4_netmask = get_ip(get_value(values, ['0', 'IPInterfaceSubnetMask'], '0.0.0.0'))
549
+ ipv4_status.lan_ipv4_dhcp_enable = bool(int(get_value(values, ['1', 'DHCPServerEnable'], '0')))
549
550
 
550
551
  for item in self._to_list(values.get('2')):
551
- if int(item['enable']) == 0 and values.get('2').__class__ == list:
552
+ if int(item.get('enable', '0')) == 0 and values.get('2').__class__ == list:
552
553
  continue
553
- ipv4_status._wan_macaddr = EUI48(item['MACAddress'])
554
- ipv4_status._wan_ipv4_ipaddr = IPv4Address(item['externalIPAddress'])
555
- ipv4_status._wan_ipv4_gateway = IPv4Address(item['defaultGateway'])
556
- ipv4_status.wan_ipv4_conntype = item['name']
557
- ipv4_status._wan_ipv4_netmask = IPv4Address(item['subnetMask'])
558
- dns = item['DNSServers'].split(',')
559
- ipv4_status._wan_ipv4_pridns = IPv4Address(dns[0])
560
- ipv4_status._wan_ipv4_snddns = IPv4Address(dns[1])
554
+ ipv4_status._wan_macaddr = get_mac(item.get('MACAddress', '00:00:00:00:00:00'))
555
+ ipv4_status._wan_ipv4_ipaddr = get_ip(item.get('externalIPAddress', '0.0.0.0'))
556
+ ipv4_status._wan_ipv4_gateway = get_ip(item.get('defaultGateway', '0.0.0.0'))
557
+ ipv4_status._wan_ipv4_conntype = item.get('name', '')
558
+ ipv4_status._wan_ipv4_netmask = get_ip(item.get('subnetMask', '0.0.0.0'))
559
+ dns = item.get('DNSServers', '').split(',')
560
+ ipv4_status._wan_ipv4_pridns = get_ip(dns[0] if len(dns) > 0 else '0.0.0.0')
561
+ ipv4_status._wan_ipv4_snddns = get_ip(dns[1] if len(dns) > 1 else '0.0.0.0')
561
562
 
562
563
  return ipv4_status
563
564
 
@@ -11,7 +11,7 @@ from tplinkrouterc6u.common.dataclass import (Device, Firmware, IPv4DHCPLease,
11
11
  IPv4Reservation, IPv4Status,
12
12
  Status)
13
13
  from tplinkrouterc6u.common.exception import ClientException
14
- from tplinkrouterc6u.common.helper import get_ip, get_mac
14
+ from tplinkrouterc6u.common.helper import get_ip, get_mac, get_value
15
15
  from tplinkrouterc6u.common.package_enum import Connection
16
16
 
17
17
 
@@ -170,15 +170,23 @@ class TPLinkXDRClient(AbstractRouter):
170
170
  })
171
171
 
172
172
  ipv4_status = IPv4Status()
173
- ipv4_status._wan_ipv4_ipaddr = get_ip(data['network']['wan_status']['ipaddr'])
174
- ipv4_status._wan_ipv4_gateway = get_ip(data['network']['wan_status']['gateway'])
175
- ipv4_status._wan_ipv4_netmask = get_ip(data['network']['wan_status']['netmask'])
176
- ipv4_status._wan_ipv4_pridns = get_ip(data['network']['wan_status']['pri_dns'])
177
- ipv4_status._wan_ipv4_snddns = get_ip(data['network']['wan_status']['snd_dns'])
178
- ipv4_status._lan_macaddr = get_mac(data['network']['lan']['macaddr'])
179
- ipv4_status._lan_ipv4_ipaddr = get_ip(data['network']['lan']['ipaddr'])
180
- ipv4_status.lan_ipv4_dhcp_enable = data['dhcpd']['udhcpd']['enable'] == '1'
181
- ipv4_status._lan_ipv4_netmask = get_ip(data['network']['lan']['netmask'])
173
+ element = get_value(data, ['network', 'wan_status', 'ipaddr'])
174
+ ipv4_status._wan_ipv4_ipaddr = get_ip(element if element else '0.0.0.0')
175
+ element = get_value(data, ['network', 'wan_status', 'gateway'])
176
+ ipv4_status._wan_ipv4_gateway = get_ip(element if element else '0.0.0.0')
177
+ element = get_value(data, ['network', 'wan_status', 'netmask'])
178
+ ipv4_status._wan_ipv4_netmask = get_ip(element if element else '0.0.0.0')
179
+ element = get_value(data, ['network', 'wan_status', 'pri_dns'])
180
+ ipv4_status._wan_ipv4_pridns = get_ip(element if element else '0.0.0.0')
181
+ element = get_value(data, ['network', 'wan_status', 'snd_dns'])
182
+ ipv4_status._wan_ipv4_snddns = get_ip(element if element else '0.0.0.0')
183
+ element = get_value(data, ['network', 'lan', 'macaddr'])
184
+ ipv4_status._lan_macaddr = get_mac(element if element else '00:00:00:00:00:00')
185
+ element = get_value(data, ['network', 'lan', 'ipaddr'])
186
+ ipv4_status._lan_ipv4_ipaddr = get_ip(element if element else '0.0.0.0')
187
+ ipv4_status.lan_ipv4_dhcp_enable = get_value(data, ['dhcpd', 'udhcpd', 'enable']) == '1'
188
+ element = get_value(data, ['network', 'lan', 'netmask'])
189
+ ipv4_status._lan_ipv4_netmask = get_ip(element if element else '0.0.0.0')
182
190
  return ipv4_status
183
191
 
184
192
  def reboot(self) -> None:
@@ -1,7 +1,7 @@
1
1
  from requests.packages import urllib3
2
2
  from logging import Logger
3
3
  from tplinkrouterc6u.common.package_enum import Connection
4
- from tplinkrouterc6u.common.dataclass import Firmware, Status
4
+ from tplinkrouterc6u.common.dataclass import Firmware, Status, IPv4Status
5
5
  from abc import ABC, abstractmethod
6
6
 
7
7
 
@@ -39,6 +39,10 @@ class AbstractRouter(ABC):
39
39
  def get_status(self) -> Status:
40
40
  pass
41
41
 
42
+ @abstractmethod
43
+ def get_ipv4_status(self) -> IPv4Status:
44
+ pass
45
+
42
46
  @abstractmethod
43
47
  def reboot(self) -> None:
44
48
  pass
@@ -167,7 +167,7 @@ class IPv4Status:
167
167
  self._wan_macaddr: EUI48
168
168
  self._wan_ipv4_ipaddr: IPv4Address | None = None
169
169
  self._wan_ipv4_gateway: IPv4Address | None = None
170
- self.wan_ipv4_conntype: str
170
+ self._wan_ipv4_conntype: str
171
171
  self._wan_ipv4_netmask: IPv4Address | None = None
172
172
  self._wan_ipv4_pridns: IPv4Address
173
173
  self._wan_ipv4_snddns: IPv4Address
@@ -189,6 +189,10 @@ class IPv4Status:
189
189
  def wan_ipv4_ipaddr(self):
190
190
  return str(self._wan_ipv4_ipaddr) if self._wan_ipv4_ipaddr else None
191
191
 
192
+ @property
193
+ def wan_ipv4_conntype(self):
194
+ return self._wan_ipv4_conntype if hasattr(self, '_wan_ipv4_conntype') else ''
195
+
192
196
  @property
193
197
  def wan_ipv4_ipaddress(self):
194
198
  return self._wan_ipv4_ipaddr
@@ -14,3 +14,14 @@ def get_mac(mac: str) -> EUI48:
14
14
  return EUI48(mac)
15
15
  except Exception:
16
16
  return EUI48('00:00:00:00:00:00')
17
+
18
+
19
+ def get_value(dictionary, keys: list, default=None):
20
+ nested_dict = dictionary
21
+
22
+ for key in keys:
23
+ try:
24
+ nested_dict = nested_dict[key]
25
+ except Exception:
26
+ return default
27
+ return nested_dict
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: tplinkrouterc6u
3
- Version: 5.4.0
3
+ Version: 5.4.2
4
4
  Summary: TP-Link Router API
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -19,6 +19,15 @@ License-File: LICENSE
19
19
  Requires-Dist: requests
20
20
  Requires-Dist: pycryptodome
21
21
  Requires-Dist: macaddress
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: requires-dist
29
+ Dynamic: requires-python
30
+ Dynamic: summary
22
31
 
23
32
  # TP-Link Router API
24
33
  Python package for API access and management for TP-Link Routers. See [Supported routers](#supports)
@@ -280,7 +289,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
280
289
  - Archer AX20 v1.0
281
290
  - Archer AX20 v3.0
282
291
  - Archer AX21 (v1.20, v3.0)
283
- - Archer AX23 v1.0
292
+ - Archer AX23 (v1.0, v1.2)
284
293
  - Archer AX50 v1.0
285
294
  - Archer AX53 v2
286
295
  - Archer AX55 (v1.0, V1.60, v4.0)
@@ -290,6 +299,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
290
299
  - Archer AX90 V1.20
291
300
  - Archer AXE75 V1
292
301
  - Archer AXE16000
302
+ - Archer AX1800
293
303
  - Archer AX3000 V1
294
304
  - Archer AX6000 V1
295
305
  - Archer AX11000 V1
@@ -309,6 +319,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
309
319
  - Archer VR600 v3
310
320
  - Archer VR900v
311
321
  - Archer VR2100v v1
322
+ - Archer VX1800v v1.0
312
323
  - Deco M4 2.0
313
324
  - Deco M4R 2.0
314
325
  - Deco M5 v3
@@ -321,14 +332,15 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
321
332
  - Deco X90
322
333
  - Deco XE75 (v1.0, v2.0)
323
334
  - EX511 v2.0
335
+ - HX510 v1.0
336
+ - NX510v v1.0
324
337
  - TD-W9960 (v1, V1.20)
325
338
  - TL-MR100 v2.0
326
339
  - TL-MR105
327
340
  - TL-MR6400 (v5, v5.3)
328
341
  - TL-MR6500v
329
- - TL-XDR3010 V2
330
342
  - TL-WA3001 v1.0
331
- - NX510v v1.0
343
+ - TL-XDR3010 V2
332
344
 
333
345
  ### Not fully tested Hardware Versions
334
346
  - AD7200 V2
File without changes