tplinkrouterc6u 4.1.1__tar.gz → 4.2.1__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.
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/PKG-INFO +25 -21
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/README.md +23 -20
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/setup.py +3 -2
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/test/test_client.py +57 -51
- tplinkrouterc6u-4.2.1/test/test_client_c1200.py +142 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/test/test_client_deco.py +52 -51
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/test/test_client_mr.py +21 -21
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u/client.py +195 -116
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u/dataclass.py +24 -24
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u/encryption.py +15 -15
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u.egg-info/PKG-INFO +25 -21
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u.egg-info/SOURCES.txt +1 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/LICENSE +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/setup.cfg +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/test/__init__.py +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u/__init__.py +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u/enum.py +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u/exception.py +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u.egg-info/dependency_links.txt +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u.egg-info/requires.txt +0 -0
- {tplinkrouterc6u-4.1.1 → tplinkrouterc6u-4.2.1}/tplinkrouterc6u.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: tplinkrouterc6u
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.2.1
|
|
4
4
|
Summary: TP-Link Router API
|
|
5
5
|
Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
|
|
6
6
|
Author: Alex Erohin
|
|
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3
|
|
|
11
11
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
12
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
13
|
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
15
|
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
15
16
|
Requires-Python: >=3.10
|
|
16
17
|
Description-Content-Type: text/markdown
|
|
@@ -227,44 +228,49 @@ or you have TP-link C1200 V2 or similar router you need to get web encrypted pas
|
|
|
227
228
|
- Archer AX10 v1.0
|
|
228
229
|
- Archer AX12 v1.0
|
|
229
230
|
- Archer AX20 v1.0
|
|
230
|
-
- Archer
|
|
231
|
+
- Archer AX20 v3.0
|
|
232
|
+
- Archer AX21 (v1.20, v3.0)
|
|
231
233
|
- Archer AX23 v1.0
|
|
232
234
|
- Archer AX50 v1.0
|
|
233
235
|
- Archer AX53 v2
|
|
234
|
-
- Archer AX55 v1.0
|
|
235
|
-
- Archer AX55 V1.60
|
|
236
|
+
- Archer AX55 (v1.0, V1.60, v4.0)
|
|
236
237
|
- Archer AX72 V1
|
|
237
238
|
- Archer AX73 V1
|
|
238
239
|
- Archer AX75 V1
|
|
239
240
|
- Archer AXE75 V1
|
|
241
|
+
- Archer AXE16000
|
|
240
242
|
- Archer AX3000 V1
|
|
241
243
|
- Archer AX6000 V1
|
|
242
244
|
- Archer AX11000 V1
|
|
245
|
+
- Archer BE800 v1.0
|
|
243
246
|
- Archer BE805 v1.0
|
|
244
247
|
- Archer C1200 v2.0 (You need to use [web encrypted password](#encrypted_pass))
|
|
245
248
|
- Archer C2300 v1.0 (You need to use [web encrypted password](#encrypted_pass))
|
|
246
|
-
- Archer C6 v2.0
|
|
247
|
-
- Archer C6 v3.0
|
|
249
|
+
- Archer C6 (v2.0, v3.0)
|
|
248
250
|
- Archer C6U v1.0
|
|
249
|
-
- Archer C7 v5.0
|
|
250
|
-
- Archer
|
|
251
|
-
- Archer
|
|
252
|
-
- Archer
|
|
253
|
-
- Archer MR600 v3
|
|
251
|
+
- Archer C7 (v4.0, v5.0)
|
|
252
|
+
- Archer C5400X V1
|
|
253
|
+
- Archer GX90 v1.0
|
|
254
|
+
- Archer MR200 (v5, v5.3)
|
|
255
|
+
- Archer MR600 (v1, v3)
|
|
256
|
+
- Archer VR2100v v1
|
|
254
257
|
- Archer VR900v
|
|
255
258
|
- Deco M4 2.0
|
|
256
259
|
- Deco M4R 2.0
|
|
257
|
-
- Deco M5
|
|
260
|
+
- Deco M5 v3
|
|
258
261
|
- Deco M9 Pro
|
|
262
|
+
- Deco M9 Plus 1.0
|
|
259
263
|
- Deco P7
|
|
260
|
-
- Deco X20
|
|
261
|
-
- Deco
|
|
264
|
+
- Deco X20
|
|
265
|
+
- Deco X50 v1.3
|
|
266
|
+
- Deco X60 V3
|
|
262
267
|
- Deco X90
|
|
263
|
-
- Deco XE75
|
|
264
|
-
-
|
|
268
|
+
- Deco XE75 (v1.0, v2.0)
|
|
269
|
+
- TD-W9960 (v1, V1.20)
|
|
270
|
+
- TL-MR100 v2.0
|
|
265
271
|
- TL-MR105
|
|
266
|
-
- TL-MR6400 v5
|
|
267
|
-
- TL-
|
|
272
|
+
- TL-MR6400 (v5, v5.3)
|
|
273
|
+
- TL-WA3001 v1.0
|
|
268
274
|
|
|
269
275
|
### Not fully tested Hardware Versions
|
|
270
276
|
- AD7200 V2
|
|
@@ -280,11 +286,9 @@ or you have TP-link C1200 V2 or similar router you need to get web encrypted pas
|
|
|
280
286
|
- Archer C900 V1
|
|
281
287
|
- Archer C1200 V3
|
|
282
288
|
- Archer C1900 V2
|
|
283
|
-
- Archer C2300
|
|
289
|
+
- Archer C2300 V2
|
|
284
290
|
- Archer C4000 (V2 and V3)
|
|
285
291
|
- Archer C5400 V2
|
|
286
|
-
- Archer C5400X V1
|
|
287
|
-
- TD-W9960 v1
|
|
288
292
|
- TL-WR1043N V5
|
|
289
293
|
|
|
290
294
|
Please let me know if you have tested integration with one of this or other model. Open an issue with info about router's model, hardware and firmware versions.
|
|
@@ -206,44 +206,49 @@ or you have TP-link C1200 V2 or similar router you need to get web encrypted pas
|
|
|
206
206
|
- Archer AX10 v1.0
|
|
207
207
|
- Archer AX12 v1.0
|
|
208
208
|
- Archer AX20 v1.0
|
|
209
|
-
- Archer
|
|
209
|
+
- Archer AX20 v3.0
|
|
210
|
+
- Archer AX21 (v1.20, v3.0)
|
|
210
211
|
- Archer AX23 v1.0
|
|
211
212
|
- Archer AX50 v1.0
|
|
212
213
|
- Archer AX53 v2
|
|
213
|
-
- Archer AX55 v1.0
|
|
214
|
-
- Archer AX55 V1.60
|
|
214
|
+
- Archer AX55 (v1.0, V1.60, v4.0)
|
|
215
215
|
- Archer AX72 V1
|
|
216
216
|
- Archer AX73 V1
|
|
217
217
|
- Archer AX75 V1
|
|
218
218
|
- Archer AXE75 V1
|
|
219
|
+
- Archer AXE16000
|
|
219
220
|
- Archer AX3000 V1
|
|
220
221
|
- Archer AX6000 V1
|
|
221
222
|
- Archer AX11000 V1
|
|
223
|
+
- Archer BE800 v1.0
|
|
222
224
|
- Archer BE805 v1.0
|
|
223
225
|
- Archer C1200 v2.0 (You need to use [web encrypted password](#encrypted_pass))
|
|
224
226
|
- Archer C2300 v1.0 (You need to use [web encrypted password](#encrypted_pass))
|
|
225
|
-
- Archer C6 v2.0
|
|
226
|
-
- Archer C6 v3.0
|
|
227
|
+
- Archer C6 (v2.0, v3.0)
|
|
227
228
|
- Archer C6U v1.0
|
|
228
|
-
- Archer C7 v5.0
|
|
229
|
-
- Archer
|
|
230
|
-
- Archer
|
|
231
|
-
- Archer
|
|
232
|
-
- Archer MR600 v3
|
|
229
|
+
- Archer C7 (v4.0, v5.0)
|
|
230
|
+
- Archer C5400X V1
|
|
231
|
+
- Archer GX90 v1.0
|
|
232
|
+
- Archer MR200 (v5, v5.3)
|
|
233
|
+
- Archer MR600 (v1, v3)
|
|
234
|
+
- Archer VR2100v v1
|
|
233
235
|
- Archer VR900v
|
|
234
236
|
- Deco M4 2.0
|
|
235
237
|
- Deco M4R 2.0
|
|
236
|
-
- Deco M5
|
|
238
|
+
- Deco M5 v3
|
|
237
239
|
- Deco M9 Pro
|
|
240
|
+
- Deco M9 Plus 1.0
|
|
238
241
|
- Deco P7
|
|
239
|
-
- Deco X20
|
|
240
|
-
- Deco
|
|
242
|
+
- Deco X20
|
|
243
|
+
- Deco X50 v1.3
|
|
244
|
+
- Deco X60 V3
|
|
241
245
|
- Deco X90
|
|
242
|
-
- Deco XE75
|
|
243
|
-
-
|
|
246
|
+
- Deco XE75 (v1.0, v2.0)
|
|
247
|
+
- TD-W9960 (v1, V1.20)
|
|
248
|
+
- TL-MR100 v2.0
|
|
244
249
|
- TL-MR105
|
|
245
|
-
- TL-MR6400 v5
|
|
246
|
-
- TL-
|
|
250
|
+
- TL-MR6400 (v5, v5.3)
|
|
251
|
+
- TL-WA3001 v1.0
|
|
247
252
|
|
|
248
253
|
### Not fully tested Hardware Versions
|
|
249
254
|
- AD7200 V2
|
|
@@ -259,11 +264,9 @@ or you have TP-link C1200 V2 or similar router you need to get web encrypted pas
|
|
|
259
264
|
- Archer C900 V1
|
|
260
265
|
- Archer C1200 V3
|
|
261
266
|
- Archer C1900 V2
|
|
262
|
-
- Archer C2300
|
|
267
|
+
- Archer C2300 V2
|
|
263
268
|
- Archer C4000 (V2 and V3)
|
|
264
269
|
- Archer C5400 V2
|
|
265
|
-
- Archer C5400X V1
|
|
266
|
-
- TD-W9960 v1
|
|
267
270
|
- TL-WR1043N V5
|
|
268
271
|
|
|
269
272
|
Please let me know if you have tested integration with one of this or other model. Open an issue with info about router's model, hardware and firmware versions.
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name="tplinkrouterc6u",
|
|
8
|
-
version="4.
|
|
8
|
+
version="4.2.1",
|
|
9
9
|
author="Alex Erohin",
|
|
10
10
|
author_email="alexanderErohin@yandex.ru",
|
|
11
11
|
description="TP-Link Router API",
|
|
@@ -20,8 +20,9 @@ setuptools.setup(
|
|
|
20
20
|
"Programming Language :: Python :: 3.10",
|
|
21
21
|
"Programming Language :: Python :: 3.11",
|
|
22
22
|
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
23
24
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
24
25
|
],
|
|
25
26
|
install_requires=['requests', 'pycryptodome', 'macaddress'],
|
|
26
27
|
python_requires='>=3.10',
|
|
27
|
-
)
|
|
28
|
+
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
from unittest import main, TestCase
|
|
2
|
+
from macaddress import EUI48
|
|
3
|
+
from ipaddress import IPv4Address
|
|
4
|
+
from json import loads
|
|
5
5
|
from tplinkrouterc6u import (
|
|
6
6
|
TplinkRouter,
|
|
7
7
|
Connection,
|
|
@@ -11,7 +11,7 @@ from tplinkrouterc6u import (
|
|
|
11
11
|
)
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
class TestTPLinkClient(
|
|
14
|
+
class TestTPLinkClient(TestCase):
|
|
15
15
|
def test_get_status(self) -> None:
|
|
16
16
|
response_status = '''
|
|
17
17
|
{
|
|
@@ -206,9 +206,9 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
206
206
|
def request(self, path: str, data: str,
|
|
207
207
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
208
208
|
if path == 'admin/status?form=all&operation=read':
|
|
209
|
-
return
|
|
209
|
+
return loads(response_status)['data']
|
|
210
210
|
elif path == 'admin/wireless?form=statistics':
|
|
211
|
-
return
|
|
211
|
+
return loads(response_stats)['data']
|
|
212
212
|
raise ClientException()
|
|
213
213
|
|
|
214
214
|
client = TPLinkRouterTest('', '')
|
|
@@ -216,14 +216,14 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
216
216
|
|
|
217
217
|
self.assertIsInstance(status, Status)
|
|
218
218
|
self.assertEqual(status.wan_macaddr, 'D6-0B-40-57-DA-60')
|
|
219
|
-
self.assertIsInstance(status.wan_macaddress,
|
|
219
|
+
self.assertIsInstance(status.wan_macaddress, EUI48)
|
|
220
220
|
self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
|
|
221
|
-
self.assertIsInstance(status.lan_macaddress,
|
|
221
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
222
222
|
self.assertEqual(status.wan_ipv4_addr, '192.168.1.100')
|
|
223
|
-
self.assertIsInstance(status.lan_ipv4_address,
|
|
223
|
+
self.assertIsInstance(status.lan_ipv4_address, IPv4Address)
|
|
224
224
|
self.assertEqual(status.lan_ipv4_addr, '192.168.1.100')
|
|
225
225
|
self.assertEqual(status.wan_ipv4_gateway, '192.168.1.254')
|
|
226
|
-
self.assertIsInstance(status.wan_ipv4_address,
|
|
226
|
+
self.assertIsInstance(status.wan_ipv4_address, IPv4Address)
|
|
227
227
|
self.assertEqual(status.wired_total, 2)
|
|
228
228
|
self.assertEqual(status.wifi_clients_total, 2)
|
|
229
229
|
self.assertEqual(status.guest_clients_total, 0)
|
|
@@ -242,18 +242,18 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
242
242
|
self.assertIsInstance(status.devices[0], Device)
|
|
243
243
|
self.assertEqual(status.devices[0].type, Connection.WIRED)
|
|
244
244
|
self.assertEqual(status.devices[0].macaddr, '3D-24-25-24-30-79')
|
|
245
|
-
self.assertIsInstance(status.devices[0].macaddress,
|
|
245
|
+
self.assertIsInstance(status.devices[0].macaddress, EUI48)
|
|
246
246
|
self.assertEqual(status.devices[0].ipaddr, '192.168.1.228')
|
|
247
|
-
self.assertIsInstance(status.devices[0].ipaddress,
|
|
247
|
+
self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
|
|
248
248
|
self.assertEqual(status.devices[0].hostname, 'SERVER')
|
|
249
249
|
self.assertEqual(status.devices[0].packets_sent, None)
|
|
250
250
|
self.assertEqual(status.devices[0].packets_received, None)
|
|
251
251
|
self.assertIsInstance(status.devices[0], Device)
|
|
252
252
|
self.assertEqual(status.devices[1].type, Connection.WIRED)
|
|
253
253
|
self.assertEqual(status.devices[1].macaddr, 'AC-04-D6-25-2A-96')
|
|
254
|
-
self.assertIsInstance(status.devices[1].macaddress,
|
|
254
|
+
self.assertIsInstance(status.devices[1].macaddress, EUI48)
|
|
255
255
|
self.assertEqual(status.devices[1].ipaddr, '192.168.1.254')
|
|
256
|
-
self.assertIsInstance(status.devices[1].ipaddress,
|
|
256
|
+
self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
|
|
257
257
|
self.assertEqual(status.devices[1].hostname, 'UNKNOWN')
|
|
258
258
|
self.assertEqual(status.devices[1].packets_sent, None)
|
|
259
259
|
self.assertEqual(status.devices[1].packets_received, None)
|
|
@@ -321,9 +321,9 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
321
321
|
def request(self, path: str, data: str,
|
|
322
322
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
323
323
|
if path == 'admin/status?form=all&operation=read':
|
|
324
|
-
return
|
|
324
|
+
return loads(response_status)['data']
|
|
325
325
|
elif path == 'admin/wireless?form=statistics':
|
|
326
|
-
return
|
|
326
|
+
return loads(response_stats)['data']
|
|
327
327
|
raise ClientException()
|
|
328
328
|
|
|
329
329
|
client = TPLinkRouterTest('', '')
|
|
@@ -332,7 +332,7 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
332
332
|
self.assertIsInstance(status, Status)
|
|
333
333
|
self.assertEqual(status.wan_macaddr, None)
|
|
334
334
|
self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
|
|
335
|
-
self.assertIsInstance(status.lan_macaddress,
|
|
335
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
336
336
|
self.assertEqual(status.wan_ipv4_addr, None)
|
|
337
337
|
self.assertEqual(status.lan_ipv4_addr, None)
|
|
338
338
|
self.assertEqual(status.wan_ipv4_gateway, None)
|
|
@@ -357,27 +357,27 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
357
357
|
self.assertIsInstance(status.devices[0], Device)
|
|
358
358
|
self.assertEqual(status.devices[0].type, Connection.WIRED)
|
|
359
359
|
self.assertEqual(status.devices[0].macaddr, '3D-24-25-24-30-79')
|
|
360
|
-
self.assertIsInstance(status.devices[0].macaddress,
|
|
360
|
+
self.assertIsInstance(status.devices[0].macaddress, EUI48)
|
|
361
361
|
self.assertEqual(status.devices[0].ipaddr, '192.168.1.228')
|
|
362
|
-
self.assertIsInstance(status.devices[0].ipaddress,
|
|
362
|
+
self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
|
|
363
363
|
self.assertEqual(status.devices[0].hostname, 'SERVER')
|
|
364
364
|
self.assertEqual(status.devices[0].packets_sent, None)
|
|
365
365
|
self.assertEqual(status.devices[0].packets_received, None)
|
|
366
366
|
self.assertIsInstance(status.devices[1], Device)
|
|
367
367
|
self.assertEqual(status.devices[1].type, Connection.WIRED)
|
|
368
368
|
self.assertEqual(status.devices[1].macaddr, 'AC-04-D6-25-2A-96')
|
|
369
|
-
self.assertIsInstance(status.devices[1].macaddress,
|
|
369
|
+
self.assertIsInstance(status.devices[1].macaddress, EUI48)
|
|
370
370
|
self.assertEqual(status.devices[1].ipaddr, '192.168.1.254')
|
|
371
|
-
self.assertIsInstance(status.devices[1].ipaddress,
|
|
371
|
+
self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
|
|
372
372
|
self.assertEqual(status.devices[1].hostname, 'UNKNOWN')
|
|
373
373
|
self.assertEqual(status.devices[1].packets_sent, None)
|
|
374
374
|
self.assertEqual(status.devices[1].packets_received, None)
|
|
375
375
|
self.assertIsInstance(status.devices[2], Device)
|
|
376
376
|
self.assertEqual(status.devices[2].type, Connection.HOST_2G)
|
|
377
377
|
self.assertEqual(status.devices[2].macaddr, '06-82-9D-2B-8F-C6')
|
|
378
|
-
self.assertIsInstance(status.devices[2].macaddress,
|
|
378
|
+
self.assertIsInstance(status.devices[2].macaddress, EUI48)
|
|
379
379
|
self.assertEqual(status.devices[2].ipaddr, '192.168.1.186')
|
|
380
|
-
self.assertIsInstance(status.devices[2].ipaddress,
|
|
380
|
+
self.assertIsInstance(status.devices[2].ipaddress, IPv4Address)
|
|
381
381
|
self.assertEqual(status.devices[2].hostname, 'UNKNOWN')
|
|
382
382
|
self.assertEqual(status.devices[2].packets_sent, None)
|
|
383
383
|
self.assertEqual(status.devices[2].packets_received, None)
|
|
@@ -425,10 +425,14 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
425
425
|
response_game_accelerator = '''
|
|
426
426
|
{
|
|
427
427
|
"data": [
|
|
428
|
-
{"mac": "06:82:9d:2b:8f:c6", "deviceTag":"2.4G", "isGuest":false, "ip":"192.168.1.186",
|
|
429
|
-
|
|
430
|
-
{"mac": "
|
|
431
|
-
|
|
428
|
+
{"mac": "06:82:9d:2b:8f:c6", "deviceTag":"2.4G", "isGuest":false, "ip":"192.168.1.186",
|
|
429
|
+
"deviceName":"name1", "uploadSpeed":12, "downloadSpeed":77},
|
|
430
|
+
{"mac": "fb:90:b8:2a:8a:b1", "deviceTag":"iot_2.4G", "isGuest":false, "ip":"192.168.1.187",
|
|
431
|
+
"deviceName":"name2"},
|
|
432
|
+
{"mac": "54:b3:a2:f7:be:ea", "deviceTag":"iot_5G", "isGuest":false, "ip":"192.168.1.188",
|
|
433
|
+
"deviceName":"name3"},
|
|
434
|
+
{"mac": "3c:ae:e1:83:94:9d", "deviceTag":"iot_6G", "isGuest":false, "ip":"192.168.1.189",
|
|
435
|
+
"deviceName":"name4"}
|
|
432
436
|
],
|
|
433
437
|
"timeout": false,
|
|
434
438
|
"success": true
|
|
@@ -462,11 +466,11 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
462
466
|
def request(self, path: str, data: str,
|
|
463
467
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
464
468
|
if path == 'admin/status?form=all&operation=read':
|
|
465
|
-
return
|
|
469
|
+
return loads(response_status)['data']
|
|
466
470
|
elif path == 'admin/smart_network?form=game_accelerator':
|
|
467
|
-
return
|
|
471
|
+
return loads(response_game_accelerator)['data']
|
|
468
472
|
elif path == 'admin/wireless?form=statistics':
|
|
469
|
-
return
|
|
473
|
+
return loads(response_stats)['data']
|
|
470
474
|
raise ClientException()
|
|
471
475
|
|
|
472
476
|
client = TPLinkRouterTest('', '')
|
|
@@ -475,7 +479,7 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
475
479
|
self.assertIsInstance(status, Status)
|
|
476
480
|
self.assertEqual(status.wan_macaddr, None)
|
|
477
481
|
self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
|
|
478
|
-
self.assertIsInstance(status.lan_macaddress,
|
|
482
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
479
483
|
self.assertEqual(status.wan_ipv4_addr, None)
|
|
480
484
|
self.assertEqual(status.lan_ipv4_addr, None)
|
|
481
485
|
self.assertEqual(status.wan_ipv4_gateway, None)
|
|
@@ -500,63 +504,65 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
500
504
|
self.assertIsInstance(status.devices[0], Device)
|
|
501
505
|
self.assertEqual(status.devices[0].type, Connection.WIRED)
|
|
502
506
|
self.assertEqual(status.devices[0].macaddr, '3D-24-25-24-30-79')
|
|
503
|
-
self.assertIsInstance(status.devices[0].macaddress,
|
|
507
|
+
self.assertIsInstance(status.devices[0].macaddress, EUI48)
|
|
504
508
|
self.assertEqual(status.devices[0].ipaddr, '192.168.1.228')
|
|
505
|
-
self.assertIsInstance(status.devices[0].ipaddress,
|
|
509
|
+
self.assertIsInstance(status.devices[0].ipaddress, IPv4Address)
|
|
506
510
|
self.assertEqual(status.devices[0].hostname, 'SERVER')
|
|
507
511
|
self.assertEqual(status.devices[0].packets_sent, None)
|
|
508
512
|
self.assertEqual(status.devices[0].packets_received, None)
|
|
509
513
|
self.assertIsInstance(status.devices[1], Device)
|
|
510
514
|
self.assertEqual(status.devices[1].type, Connection.WIRED)
|
|
511
515
|
self.assertEqual(status.devices[1].macaddr, 'AC-04-D6-25-2A-96')
|
|
512
|
-
self.assertIsInstance(status.devices[1].macaddress,
|
|
516
|
+
self.assertIsInstance(status.devices[1].macaddress, EUI48)
|
|
513
517
|
self.assertEqual(status.devices[1].ipaddr, '192.168.1.254')
|
|
514
|
-
self.assertIsInstance(status.devices[1].ipaddress,
|
|
518
|
+
self.assertIsInstance(status.devices[1].ipaddress, IPv4Address)
|
|
515
519
|
self.assertEqual(status.devices[1].hostname, 'UNKNOWN')
|
|
516
520
|
self.assertEqual(status.devices[1].packets_sent, None)
|
|
517
521
|
self.assertEqual(status.devices[1].packets_received, None)
|
|
518
522
|
self.assertIsInstance(status.devices[2], Device)
|
|
519
523
|
self.assertEqual(status.devices[2].type, Connection.HOST_2G)
|
|
520
524
|
self.assertEqual(status.devices[2].macaddr, '06-82-9D-2B-8F-C6')
|
|
521
|
-
self.assertIsInstance(status.devices[2].macaddress,
|
|
525
|
+
self.assertIsInstance(status.devices[2].macaddress, EUI48)
|
|
522
526
|
self.assertEqual(status.devices[2].ipaddr, '192.168.1.186')
|
|
523
|
-
self.assertIsInstance(status.devices[2].ipaddress,
|
|
527
|
+
self.assertIsInstance(status.devices[2].ipaddress, IPv4Address)
|
|
524
528
|
self.assertEqual(status.devices[2].hostname, 'UNKNOWN')
|
|
525
529
|
self.assertEqual(status.devices[2].packets_sent, 450333)
|
|
526
530
|
self.assertEqual(status.devices[2].packets_received, 4867482)
|
|
531
|
+
self.assertEqual(status.devices[2].up_speed, 12)
|
|
532
|
+
self.assertEqual(status.devices[2].down_speed, 77)
|
|
527
533
|
self.assertIsInstance(status.devices[3], Device)
|
|
528
534
|
self.assertEqual(status.devices[3].type, Connection.IOT_2G)
|
|
529
535
|
self.assertEqual(status.devices[3].macaddr, 'FB-90-B8-2A-8A-B1')
|
|
530
|
-
self.assertIsInstance(status.devices[3].macaddress,
|
|
536
|
+
self.assertIsInstance(status.devices[3].macaddress, EUI48)
|
|
531
537
|
self.assertEqual(status.devices[3].ipaddr, '192.168.1.187')
|
|
532
|
-
self.assertIsInstance(status.devices[3].ipaddress,
|
|
538
|
+
self.assertIsInstance(status.devices[3].ipaddress, IPv4Address)
|
|
533
539
|
self.assertEqual(status.devices[3].hostname, 'name2')
|
|
534
540
|
self.assertEqual(status.devices[3].packets_sent, None)
|
|
535
541
|
self.assertEqual(status.devices[3].packets_received, None)
|
|
536
542
|
self.assertIsInstance(status.devices[4], Device)
|
|
537
543
|
self.assertEqual(status.devices[4].type, Connection.IOT_5G)
|
|
538
544
|
self.assertEqual(status.devices[4].macaddr, '54-B3-A2-F7-BE-EA')
|
|
539
|
-
self.assertIsInstance(status.devices[4].macaddress,
|
|
545
|
+
self.assertIsInstance(status.devices[4].macaddress, EUI48)
|
|
540
546
|
self.assertEqual(status.devices[4].ipaddr, '192.168.1.188')
|
|
541
|
-
self.assertIsInstance(status.devices[4].ipaddress,
|
|
547
|
+
self.assertIsInstance(status.devices[4].ipaddress, IPv4Address)
|
|
542
548
|
self.assertEqual(status.devices[4].hostname, 'name3')
|
|
543
549
|
self.assertEqual(status.devices[4].packets_sent, None)
|
|
544
550
|
self.assertEqual(status.devices[4].packets_received, None)
|
|
545
551
|
self.assertIsInstance(status.devices[5], Device)
|
|
546
552
|
self.assertEqual(status.devices[5].type, Connection.IOT_6G)
|
|
547
553
|
self.assertEqual(status.devices[5].macaddr, '3C-AE-E1-83-94-9D')
|
|
548
|
-
self.assertIsInstance(status.devices[5].macaddress,
|
|
554
|
+
self.assertIsInstance(status.devices[5].macaddress, EUI48)
|
|
549
555
|
self.assertEqual(status.devices[5].ipaddr, '192.168.1.189')
|
|
550
|
-
self.assertIsInstance(status.devices[5].ipaddress,
|
|
556
|
+
self.assertIsInstance(status.devices[5].ipaddress, IPv4Address)
|
|
551
557
|
self.assertEqual(status.devices[5].hostname, 'name4')
|
|
552
558
|
self.assertEqual(status.devices[5].packets_sent, None)
|
|
553
559
|
self.assertEqual(status.devices[5].packets_received, None)
|
|
554
560
|
self.assertIsInstance(status.devices[6], Device)
|
|
555
561
|
self.assertEqual(status.devices[6].type, Connection.HOST_5G)
|
|
556
562
|
self.assertEqual(status.devices[6].macaddr, '1F-7A-BD-F7-20-0D')
|
|
557
|
-
self.assertIsInstance(status.devices[6].macaddress,
|
|
563
|
+
self.assertIsInstance(status.devices[6].macaddress, EUI48)
|
|
558
564
|
self.assertEqual(status.devices[6].ipaddr, '0.0.0.0')
|
|
559
|
-
self.assertIsInstance(status.devices[6].ipaddress,
|
|
565
|
+
self.assertIsInstance(status.devices[6].ipaddress, IPv4Address)
|
|
560
566
|
self.assertEqual(status.devices[6].hostname, '')
|
|
561
567
|
self.assertEqual(status.devices[6].packets_sent, 134815)
|
|
562
568
|
self.assertEqual(status.devices[6].packets_received, 2953078)
|
|
@@ -593,11 +599,11 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
593
599
|
def request(self, path: str, data: str,
|
|
594
600
|
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
595
601
|
if path == 'admin/status?form=all&operation=read':
|
|
596
|
-
return
|
|
602
|
+
return loads(response_status)['data']
|
|
597
603
|
elif path == 'admin/status?form=perf&operation=read':
|
|
598
|
-
return
|
|
604
|
+
return loads(perf_stats)['data']
|
|
599
605
|
elif path == 'admin/wireless?form=statistics':
|
|
600
|
-
return
|
|
606
|
+
return loads(response_stats)['data']
|
|
601
607
|
raise ClientException()
|
|
602
608
|
|
|
603
609
|
client = TPLinkRouterTest('', '')
|
|
@@ -606,7 +612,7 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
606
612
|
self.assertIsInstance(status, Status)
|
|
607
613
|
self.assertEqual(status.wan_macaddr, None)
|
|
608
614
|
self.assertEqual(status.lan_macaddr, '06-E6-97-9E-23-F5')
|
|
609
|
-
self.assertIsInstance(status.lan_macaddress,
|
|
615
|
+
self.assertIsInstance(status.lan_macaddress, EUI48)
|
|
610
616
|
self.assertEqual(status.wan_ipv4_addr, None)
|
|
611
617
|
self.assertEqual(status.lan_ipv4_addr, None)
|
|
612
618
|
self.assertEqual(status.wan_ipv4_gateway, None)
|
|
@@ -676,4 +682,4 @@ class TestTPLinkClient(unittest.TestCase):
|
|
|
676
682
|
|
|
677
683
|
|
|
678
684
|
if __name__ == '__main__':
|
|
679
|
-
|
|
685
|
+
main()
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
from unittest import main, TestCase
|
|
2
|
+
from json import loads
|
|
3
|
+
from tplinkrouterc6u import (
|
|
4
|
+
TplinkC1200Router,
|
|
5
|
+
Connection,
|
|
6
|
+
ClientException
|
|
7
|
+
)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class TestTPLinkC1200Client(TestCase):
|
|
11
|
+
|
|
12
|
+
def test_set_led_on(self) -> None:
|
|
13
|
+
|
|
14
|
+
response_led_general_read = '''
|
|
15
|
+
{
|
|
16
|
+
"enable": "off",
|
|
17
|
+
"time_set": "yes",
|
|
18
|
+
"ledpm_support": "yes"
|
|
19
|
+
}
|
|
20
|
+
'''
|
|
21
|
+
|
|
22
|
+
response_led_general_write = '''
|
|
23
|
+
{
|
|
24
|
+
"enable": "on",
|
|
25
|
+
"time_set": "yes",
|
|
26
|
+
"ledpm_support": "yes"
|
|
27
|
+
}
|
|
28
|
+
'''
|
|
29
|
+
|
|
30
|
+
class TPLinkRouterTest(TplinkC1200Router):
|
|
31
|
+
def request(self, path: str, data: str,
|
|
32
|
+
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
33
|
+
if path == 'admin/ledgeneral?form=setting&operation=read':
|
|
34
|
+
return loads(response_led_general_read)
|
|
35
|
+
if path == 'admin/ledgeneral?form=setting&operation=write':
|
|
36
|
+
self.captured_path = path
|
|
37
|
+
return loads(response_led_general_write)
|
|
38
|
+
raise ClientException()
|
|
39
|
+
|
|
40
|
+
client = TPLinkRouterTest('', '')
|
|
41
|
+
|
|
42
|
+
client.set_led(True)
|
|
43
|
+
|
|
44
|
+
expected_path = "admin/ledgeneral?form=setting&operation=write"
|
|
45
|
+
|
|
46
|
+
self.assertEqual(client.captured_path, expected_path)
|
|
47
|
+
|
|
48
|
+
def test_set_led_off(self) -> None:
|
|
49
|
+
|
|
50
|
+
response_led_general_read = '''
|
|
51
|
+
{
|
|
52
|
+
"enable": "on",
|
|
53
|
+
"time_set": "yes",
|
|
54
|
+
"ledpm_support": "yes"
|
|
55
|
+
}
|
|
56
|
+
'''
|
|
57
|
+
|
|
58
|
+
response_led_general_write = '''
|
|
59
|
+
{
|
|
60
|
+
"enable": "off",
|
|
61
|
+
"time_set": "yes",
|
|
62
|
+
"ledpm_support": "yes"
|
|
63
|
+
}
|
|
64
|
+
'''
|
|
65
|
+
|
|
66
|
+
class TPLinkRouterTest(TplinkC1200Router):
|
|
67
|
+
def request(self, path: str, data: str,
|
|
68
|
+
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
69
|
+
if path == 'admin/ledgeneral?form=setting&operation=read':
|
|
70
|
+
return loads(response_led_general_read)
|
|
71
|
+
elif path == 'admin/ledgeneral?form=setting&operation=write':
|
|
72
|
+
self.captured_path = path
|
|
73
|
+
return loads(response_led_general_write)
|
|
74
|
+
raise ClientException()
|
|
75
|
+
|
|
76
|
+
client = TPLinkRouterTest('', '')
|
|
77
|
+
|
|
78
|
+
client.set_led(False)
|
|
79
|
+
|
|
80
|
+
expected_path = "admin/ledgeneral?form=setting&operation=write"
|
|
81
|
+
|
|
82
|
+
self.assertEqual(client.captured_path, expected_path)
|
|
83
|
+
|
|
84
|
+
def test_led_status(self) -> None:
|
|
85
|
+
|
|
86
|
+
response_led_general_read = '''
|
|
87
|
+
{
|
|
88
|
+
"enable": "on",
|
|
89
|
+
"time_set": "yes",
|
|
90
|
+
"ledpm_support": "yes"
|
|
91
|
+
}
|
|
92
|
+
'''
|
|
93
|
+
|
|
94
|
+
class TPLinkRouterTest(TplinkC1200Router):
|
|
95
|
+
def request(self, path: str, data: str,
|
|
96
|
+
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
97
|
+
if path == 'admin/ledgeneral?form=setting&operation=read':
|
|
98
|
+
return loads(response_led_general_read)
|
|
99
|
+
raise ClientException()
|
|
100
|
+
|
|
101
|
+
client = TPLinkRouterTest('', '')
|
|
102
|
+
|
|
103
|
+
led_status = client.get_led()
|
|
104
|
+
self.assertTrue(led_status)
|
|
105
|
+
|
|
106
|
+
def test_set_wifi(self) -> None:
|
|
107
|
+
|
|
108
|
+
class TPLinkRouterTest(TplinkC1200Router):
|
|
109
|
+
def request(self, path: str, data: str,
|
|
110
|
+
ignore_response: bool = False, ignore_errors: bool = False) -> dict | None:
|
|
111
|
+
|
|
112
|
+
self.captured_path = path
|
|
113
|
+
self.captured_data = data
|
|
114
|
+
|
|
115
|
+
client = TPLinkRouterTest('', '')
|
|
116
|
+
client.set_wifi(
|
|
117
|
+
Connection.HOST_5G,
|
|
118
|
+
enable=True,
|
|
119
|
+
ssid="TestSSID",
|
|
120
|
+
hidden="no",
|
|
121
|
+
encryption="WPA3-PSK",
|
|
122
|
+
psk_version="2",
|
|
123
|
+
psk_cipher="AES",
|
|
124
|
+
psk_key="testkey123",
|
|
125
|
+
hwmode="11ac",
|
|
126
|
+
htmode="VHT20",
|
|
127
|
+
channel=36,
|
|
128
|
+
txpower="20",
|
|
129
|
+
disabled_all="no"
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
expected_data = ("operation=write&enable=on&ssid=TestSSID&hidden=no&encryption=WPA3-PSK&"
|
|
133
|
+
"psk_version=2&psk_cipher=AES&psk_key=testkey123&hwmode=11ac&"
|
|
134
|
+
"htmode=VHT20&channel=36&txpower=20&disabled_all=no")
|
|
135
|
+
expected_path = f"admin/wireless?form=wireless_5g&{expected_data}"
|
|
136
|
+
|
|
137
|
+
self.assertEqual(client.captured_path, expected_path)
|
|
138
|
+
self.assertEqual(client.captured_data, expected_data)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if __name__ == '__main__':
|
|
142
|
+
main()
|