tplinkrouterc6u 5.12.4__py3-none-any.whl → 5.14.0__py3-none-any.whl

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.
@@ -0,0 +1,80 @@
1
+ """
2
+ TP-Link TL-MR6400 v7 Client
3
+
4
+ Based on reverse-engineering of network traffic.
5
+ Protocol is similar to MR series but with differences in:
6
+ 1. Login: Uses RSA encryption (PKCS1 v1.5) for both Username and Password
7
+ 2. Password must be Base64 encoded before encryption
8
+ 3. Actions: Uses /cgi endpoint with types in query string and plain text body
9
+ """
10
+
11
+ from logging import Logger
12
+
13
+ from tplinkrouterc6u.client.mr import TPLinkMRClient
14
+ from tplinkrouterc6u.common.exception import ClientException, ClientError
15
+
16
+ from json import loads
17
+
18
+
19
+ class TPLinkMR6400v7Client(TPLinkMRClient):
20
+ """Client for TP-Link MR6400 v7"""
21
+
22
+ def __init__(self, host: str, password: str, username: str = '', logger: Logger = None,
23
+ verify_ssl: bool = True, timeout: int = 30):
24
+ super().__init__(host, password, username, logger, verify_ssl, timeout)
25
+
26
+ def _req_rsa_key(self):
27
+ """
28
+ Requests the RSA public key from the host
29
+
30
+ Return value:
31
+ ((n, e), seq) tuple
32
+ """
33
+ response = ''
34
+ try:
35
+ url = self._get_url(self._url_rsa_key)
36
+ (code, response) = self._request(url)
37
+ assert code == 200
38
+
39
+ # assert return code
40
+ assert self._parse_ret_val(response) == self.HTTP_RET_OK
41
+
42
+ json_data = loads(response)
43
+
44
+ ee = json_data['ee']
45
+ nn = json_data['nn']
46
+ seq = json_data['seq']
47
+
48
+ assert ee and nn and seq
49
+ assert len(ee) == 6
50
+ assert len(nn) == 128
51
+
52
+ except Exception as e:
53
+ error = (self.ROUTER_NAME + '- {} - Unknown error rsa_key! Error - {}; Response - {}'
54
+ .format(self.__class__.__name__, e, response))
55
+ if self._logger:
56
+ self._logger.debug(error)
57
+ raise ClientException(error)
58
+
59
+ return nn, ee, int(seq)
60
+
61
+ def _parse_ret_val(self, response_text):
62
+ """
63
+ Parses $.ret value from the response text
64
+
65
+ Return value:
66
+ return code (int)
67
+ """
68
+ if '[error]0' in response_text or 'errorcode=0' in response_text:
69
+ return 0
70
+
71
+ try:
72
+ result = loads(response_text)
73
+
74
+ result = result['ret']
75
+ result = int(result)
76
+
77
+ return result
78
+
79
+ except ValueError:
80
+ raise ClientError(f"Error trying to convert response to JSON: {response_text}")
@@ -0,0 +1,198 @@
1
+ import math
2
+ from datetime import timedelta
3
+ from ipaddress import IPv4Address
4
+ from urllib.parse import unquote
5
+
6
+ from macaddress import EUI48
7
+
8
+ from tplinkrouterc6u.client.xdr import TPLinkXDRClient
9
+ from tplinkrouterc6u.common.dataclass import (Device, IPv4DHCPLease,
10
+ IPv4Reservation,
11
+ Status)
12
+ from tplinkrouterc6u.common.exception import ClientException
13
+ from tplinkrouterc6u.common.helper import get_ip, get_mac
14
+ from tplinkrouterc6u.common.package_enum import Connection
15
+
16
+
17
+ class TPLinkRClient(TPLinkXDRClient):
18
+ _serv_id_map = {
19
+ Connection.HOST_2G: '',
20
+ Connection.HOST_5G: '',
21
+ Connection.GUEST_2G: '',
22
+ Connection.GUEST_5G: '',
23
+ }
24
+
25
+ def supports(self) -> bool:
26
+ try:
27
+ response = self._session.get('{}/login.htm'.format(self.host),
28
+ timeout=self.timeout,
29
+ verify=self._verify_ssl)
30
+ return 'TL-R' in response.text
31
+ except Exception:
32
+ return False
33
+
34
+ def authorize(self) -> None:
35
+ response = self._session.post(self.host, json={
36
+ 'method': 'do',
37
+ 'login': {
38
+ 'username': self.username,
39
+ 'password': self._encode_password(self.password),
40
+ }
41
+ }, timeout=self.timeout, verify=self._verify_ssl)
42
+ try:
43
+ data = response.json()
44
+ self._stok = data['stok']
45
+ except Exception as e:
46
+ error = ('TplinkRouter - {} - Cannot authorize! Error - {}; Response - {}'.
47
+ format(self.__class__.__name__, e, response))
48
+ raise ClientException(error)
49
+
50
+ def get_status(self) -> Status:
51
+ data = self._request({
52
+ 'method': 'get',
53
+ 'host_management': {
54
+ 'table': ["host_info"],
55
+ },
56
+ 'network': {
57
+ 'name': [
58
+ 'wan_status',
59
+ 'lan',
60
+ ],
61
+ },
62
+ 'apmng_wserv': {
63
+ 'table': ['wlan_serv'],
64
+ }
65
+ })
66
+
67
+ status = Status()
68
+ status._wan_ipv4_addr = get_ip(data['network']['wan_status']['ipaddr'])
69
+ status._wan_ipv4_gateway = get_ip(data['network']['wan_status']['gateway'])
70
+ status.wan_ipv4_uptime = data['network']['wan_status']['up_time']
71
+ status._lan_ipv4_addr = get_ip(data['network']['lan']['ipaddr'])
72
+ status._lan_macaddr = get_mac(data['network']['lan']['macaddr'])
73
+
74
+ for item_map in data['apmng_wserv']['wlan_serv']:
75
+ item = item_map[next(iter(item_map))]
76
+ bind_freq = self._bindFreq(item['default_bind_freq'])
77
+ enable = item['enable'] == 'on'
78
+ if item['network_type'] == '1' and bind_freq['2g']:
79
+ status.wifi_2g_enable = enable
80
+ self._serv_id_map[Connection.HOST_2G] = item['serv_id']
81
+ elif item['network_type'] == '1' and bind_freq['5g']:
82
+ status.wifi_5g_enable = enable
83
+ self._serv_id_map[Connection.HOST_5G] = item['serv_id']
84
+ elif item['network_type'] == '2' and bind_freq['2g']:
85
+ status.guest_2g_enable = enable
86
+ self._serv_id_map[Connection.GUEST_2G] = item['serv_id']
87
+ elif item['network_type'] == '2' and bind_freq['5g']:
88
+ status.guest_5g_enable = enable
89
+ self._serv_id_map[Connection.GUEST_5G] = item['serv_id']
90
+
91
+ status.clients_total += len(data['host_management']['host_info'])
92
+ for item_map in data['host_management']['host_info']:
93
+ item = item_map[next(iter(item_map))]
94
+ conn_type = Connection.UNKNOWN
95
+ if item['type'] == 'wired':
96
+ conn_type = Connection.WIRED
97
+ status.wired_total += 1
98
+ elif item['type'] == 'wireless' and item.get('freq_name') == '2.4GHz':
99
+ conn_type = Connection.HOST_2G
100
+ status.wifi_clients_total += 1
101
+ elif item['type'] == 'wireless' and item.get('freq_name') == '5GHz':
102
+ conn_type = Connection.HOST_5G
103
+ status.wifi_clients_total += 1
104
+
105
+ dev = Device(conn_type, get_mac(item['mac']), get_ip(item['ip']), unquote(item['hostname']))
106
+ if 'up_speed' in item:
107
+ dev.up_speed = int(item['up_speed'])
108
+ if 'down_speed' in item:
109
+ dev.down_speed = int(item['down_speed'])
110
+ if 'signal' in item:
111
+ dev.signal = int(item['rssi'])
112
+ if 'state' in item:
113
+ dev.active = item['state'] == 'online'
114
+ status.devices.append(dev)
115
+ return status
116
+
117
+ def get_ipv4_reservations(self) -> [IPv4Reservation]:
118
+ data = self._request({
119
+ 'method': 'get',
120
+ 'dhcpd': {
121
+ 'table': 'dhcp_static',
122
+ },
123
+ })
124
+
125
+ ipv4_reservations = []
126
+ for item_map in data['dhcpd']['dhcp_static']:
127
+ item = item_map[next(iter(item_map))]
128
+ ipv4_reservations.append(IPv4Reservation(
129
+ EUI48(item['mac']),
130
+ IPv4Address(item['ip']),
131
+ item['note'],
132
+ item['enable'] == 'on',
133
+ ))
134
+ return ipv4_reservations
135
+
136
+ def get_ipv4_dhcp_leases(self) -> [IPv4DHCPLease]:
137
+ data = self._request({
138
+ 'method': 'get',
139
+ 'dhcpd': {
140
+ 'table': 'dhcp_clients',
141
+ },
142
+ })
143
+
144
+ dhcp_leases = []
145
+ for item_map in data['dhcpd']['dhcp_clients']:
146
+ item = item_map[next(iter(item_map))]
147
+ dhcp_leases.append(IPv4DHCPLease(
148
+ get_mac(item['macaddr']),
149
+ get_ip(item['ipaddr']),
150
+ item['hostname'],
151
+ str(timedelta(seconds=int(item['expires']))) if item['expires'] != 'PERMANENT' else 'Permanent',
152
+ ))
153
+ return dhcp_leases
154
+
155
+ def set_wifi(self, wifi: Connection, enable: bool) -> None:
156
+ if wifi not in self._serv_id_map:
157
+ raise ClientException('Not supported')
158
+ if self._serv_id_map[wifi] == '':
159
+ self.get_status()
160
+ if self._serv_id_map[wifi] == '':
161
+ raise ClientException('TplinkRouter - {} - set wifi failed, unable to get serv_id for {}'.
162
+ format(self.__class__, wifi.__class__))
163
+
164
+ payload = {
165
+ 'method': 'set',
166
+ 'apmng_wserv': {
167
+ 'table': 'wlan_serv',
168
+ 'filter': [{'serv_id': self._serv_id_map[wifi]}],
169
+ 'para': {'enable': 'on' if enable else 'off'},
170
+ },
171
+ }
172
+
173
+ data = self._request(payload)
174
+ if data['error_code'] != 0:
175
+ raise ClientException('TplinkRouter - {} - set wifi failed, code - {}'.
176
+ format(self.__class__, data['error_code']))
177
+
178
+ @staticmethod
179
+ def _bindFreq(default_bind_freq: str) -> dict:
180
+ bind_freq = int(default_bind_freq)
181
+ result = {
182
+ '2g': False,
183
+ '5g': False,
184
+ }
185
+
186
+ if bind_freq % 2 == 1: # 2.4G1
187
+ result['2g'] = True
188
+ elif math.floor(bind_freq / 2) % 2 == 1: # 2.4G2
189
+ result['2g'] = True
190
+ elif math.floor(bind_freq / 256) % 2 == 1: # 5G1
191
+ result['5g'] = True
192
+ elif math.floor(bind_freq / 512) % 2 == 1: # 5G2
193
+ result['5g'] = True
194
+ elif bind_freq == 771: # all
195
+ result['2g'] = True
196
+ result['5g'] = True
197
+
198
+ return result
@@ -64,7 +64,10 @@ class TPLinkXDRClient(AbstractRouter):
64
64
  },
65
65
  })
66
66
  dev_info = data['device_info']['info']
67
- return Firmware(dev_info['hw_version'], dev_info['device_model'], dev_info['sw_version'])
67
+ return Firmware(
68
+ unquote(dev_info['hw_version']),
69
+ unquote(dev_info['device_model']),
70
+ unquote((dev_info['sw_version'])))
68
71
 
69
72
  def get_status(self) -> Status:
70
73
  data = self._request({
@@ -96,6 +99,8 @@ class TPLinkXDRClient(AbstractRouter):
96
99
 
97
100
  status = Status()
98
101
  status._wan_ipv4_addr = get_ip(data['network']['wan_status']['ipaddr'])
102
+ status._wan_ipv4_gateway = get_ip(data['network']['wan_status']['gateway'])
103
+ status.wan_ipv4_uptime = data['network']['wan_status']['up_time']
99
104
  status._lan_ipv4_addr = get_ip(data['network']['lan']['ipaddr'])
100
105
  status._lan_macaddr = get_mac(data['network']['lan']['macaddr'])
101
106
  status.wifi_2g_enable = data['wireless']['wlan_host_2g']['enable'] == '1'
@@ -103,15 +108,19 @@ class TPLinkXDRClient(AbstractRouter):
103
108
  data['wireless']['wlan_bs']['bs_enable'] == '1')
104
109
  status.guest_2g_enable = data['guest_network']['guest_2g']['enable'] == '1'
105
110
 
111
+ status.clients_total += len(data['hosts_info']['host_info'])
106
112
  for item_map in data['hosts_info']['host_info']:
107
113
  item = item_map[next(iter(item_map))]
108
114
  conn_type = Connection.UNKNOWN
109
115
  if item['type'] == '0':
110
116
  conn_type = Connection.WIRED
117
+ status.wired_total += 1
111
118
  elif item['type'] == '1' and item['wifi_mode'] == '0':
112
119
  conn_type = Connection.HOST_2G
120
+ status.wifi_clients_total += 1
113
121
  elif item['type'] == '1' and item['wifi_mode'] == '1':
114
122
  conn_type = Connection.HOST_5G
123
+ status.wifi_clients_total += 1
115
124
 
116
125
  dev = Device(conn_type, get_mac(item['mac']), get_ip(item['ip']), unquote(item['hostname']))
117
126
  dev.up_speed = item['up_speed']
@@ -2,17 +2,20 @@ from logging import Logger
2
2
 
3
3
  from tplinkrouterc6u import TPLinkXDRClient
4
4
  from tplinkrouterc6u.common.exception import ClientException
5
- from tplinkrouterc6u.client.c6u import TplinkRouter
5
+ from tplinkrouterc6u.client.c6u import TplinkRouter, TplinkRouterV1_11
6
6
  from tplinkrouterc6u.client.deco import TPLinkDecoClient
7
7
  from tplinkrouterc6u.client_abstract import AbstractRouter
8
8
  from tplinkrouterc6u.client.mr import TPLinkMRClient, TPLinkMRClientGCM
9
9
  from tplinkrouterc6u.client.mr200 import TPLinkMR200Client
10
+ from tplinkrouterc6u.client.mr6400v7 import TPLinkMR6400v7Client
10
11
  from tplinkrouterc6u.client.ex import TPLinkEXClient, TPLinkEXClientGCM
11
12
  from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
13
+ from tplinkrouterc6u.client.c3200 import TplinkC3200Router
12
14
  from tplinkrouterc6u.client.c1200 import TplinkC1200Router
13
15
  from tplinkrouterc6u.client.c80 import TplinkC80Router
14
16
  from tplinkrouterc6u.client.vr import TPLinkVRClient
15
17
  from tplinkrouterc6u.client.vr400v2 import TPLinkVR400v2Client
18
+ from tplinkrouterc6u.client.r import TPLinkRClient
16
19
  from tplinkrouterc6u.client.wdr import TplinkWDRRouter
17
20
  from tplinkrouterc6u.client.re330 import TplinkRE330Router
18
21
 
@@ -29,13 +32,17 @@ class TplinkRouterProvider:
29
32
  TPLinkMRClientGCM,
30
33
  TPLinkMRClient,
31
34
  TPLinkMR200Client,
35
+ TPLinkMR6400v7Client,
32
36
  TPLinkVR400v2Client,
33
37
  TPLinkDecoClient,
34
38
  TPLinkXDRClient,
39
+ TPLinkRClient,
40
+ TplinkRouterV1_11,
35
41
  TplinkRouter,
36
42
  TplinkC80Router,
37
43
  TplinkWDRRouter,
38
44
  TplinkRE330Router,
45
+ TplinkC3200Router,
39
46
  ]:
40
47
  router = client(host, password, username, logger, verify_ssl, timeout)
41
48
  if router.supports():
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tplinkrouterc6u
3
- Version: 5.12.4
3
+ Version: 5.14.0
4
4
  Summary: TP-Link Router API (supports also Mercusys Router)
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -56,21 +56,25 @@ Python package for API access and management for TP-Link and Mercusys Routers. S
56
56
  ```python
57
57
  from tplinkrouterc6u import (
58
58
  TplinkRouterProvider,
59
+ TplinkRouterV1_11,
59
60
  TplinkRouter,
60
61
  TplinkC1200Router,
61
62
  TplinkC5400XRouter,
62
63
  TPLinkMRClient, # Class for MR series routers which supports old firmwares with AES cipher CBC mode
63
64
  TPLinkMRClientGCM, # Class for MR series routers which supports AES cipher GCM mode
64
65
  TPLinkMR200Client,
66
+ TPLinkMR6400v7Client,
65
67
  TPLinkVRClient,
66
68
  TPLinkVR400v2Client,
67
69
  TPLinkEXClient, # Class for EX series routers which supports old firmwares with AES cipher CBC mode
68
70
  TPLinkEXClientGCM, # Class for EX series routers which supports AES cipher GCM mode
71
+ TPLinkRClient,
69
72
  TPLinkXDRClient,
70
73
  TPLinkDecoClient,
71
74
  TplinkC80Router,
72
75
  TplinkWDRRouter,
73
76
  TplinkRE330Router,
77
+ TplinkC3200Router,
74
78
  Connection
75
79
  )
76
80
  from logging import Logger
@@ -83,7 +87,7 @@ router = TplinkRouterProvider.get_client('http://192.168.0.1', 'password')
83
87
  # If you have the TP-link C5400X or similar, you can use the TplinkC5400XRouter class instead of the TplinkRouter class.
84
88
  # Remember that the password for this router is different, here you need to use the web encrypted password.
85
89
  # To get web encrypted password, read Web Encrypted Password section
86
- # router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', Logger('test'))
90
+ # router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', logger: Logger('test'))
87
91
 
88
92
  try:
89
93
  router.authorize() # authorizing
@@ -343,6 +347,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
343
347
  - Archer BE3600 1.6
344
348
  - Archer C1200 (v1.0, v2.0)
345
349
  - Archer C2300 (v1.0, v2.0)
350
+ - Archer C3200
346
351
  - Archer C6 (v2.0, v3.0, v3.20, 4.0)
347
352
  - Archer C6U v1.0
348
353
  - Archer C7 (v4.0, v5.0)
@@ -380,19 +385,25 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
380
385
  - Deco XE75PRO (v3.0)
381
386
  - EX511 v2.0
382
387
  - HX510 v1.0
388
+ - M8550 v1
389
+ - NE200-Outdoor v1.0
383
390
  - NX510v v1.0
391
+ - NX600 v2.0
384
392
  - TD-W9960 (v1, V1.20)
385
393
  - TL-MR100 v2.0
386
394
  - TL-MR105
387
395
  - TL-MR100-Outdoor v1.0
388
396
  - TL-MR110-Outdoor v1.0
389
397
  - TL-MR150 v2
390
- - TL-MR6400 (v5, v5.3)
398
+ - TL-MR6400 (v5, v5.3, v7)
391
399
  - TL-MR6500v
400
+ - TL-R470GP-AC 4.0
401
+ - TL-R488GPM-AC 2.0
392
402
  - TL-WA1201 3.0
393
403
  - TL-WA3001 v1.0
394
404
  - TL-XDR3010 V2
395
405
  - TL-WDR3600 V1
406
+ - TL-XDR5410 1.0
396
407
  - TL-XDR6088 v1.0.30
397
408
  - VX420-G2h v1.1
398
409
  - VX800v v1
@@ -1,40 +1,46 @@
1
1
  test/__init__.py,sha256=McQmUjeN3AwmwdS6QNfwGXXE77OKoPK852I2BM9XsrU,210
2
+ test/test_client_C3200.py,sha256=jQoGq3yasoOc2Da37RkZ8uT0uyFrKfX2OGGy7hq02A0,20932
2
3
  test/test_client_c1200.py,sha256=Sl-85JGqINNg-ckBZCIVqY0CC-V1UOc-yiIUljtePRM,7582
3
- test/test_client_c6u.py,sha256=u-8mnPF18RBgU-rx06L_M-RYTXYKZY6B3mmkXgq8mZg,40399
4
+ test/test_client_c6u.py,sha256=GGYReY9RmnkJDgcaWtzbti-hTkab2D8JXxZCPt0wTfk,41662
5
+ test/test_client_c6u_v1_11.py,sha256=FkpDRYk-LKC_YFNyrDUZUm7_x89REMnl4zquiEtyFB4,3343
4
6
  test/test_client_c80.py,sha256=RY_1SgRVcQQdN9h0_IXA0YW4_0flEB_uel05QvDDfws,42359
5
7
  test/test_client_deco.py,sha256=YPLKRD8GoyDYHfRgdXvCk8iVNw8zdMJW-AHVnNbpdTM,31719
6
- test/test_client_ex.py,sha256=Kg6svEKtyGAfyF9yrLh2qZa2tK1mlEBJJwXRsq1MAjo,26591
7
- test/test_client_mr.py,sha256=lePxkmjcPzcrSFcaT8bT67L154cVJIOWrFlXMDOa8oY,33423
8
+ test/test_client_ex.py,sha256=_HvQhT2dG63fg6kJkgnZoPwa9qCgFDjWSAYQfjgVRA4,40480
9
+ test/test_client_mr.py,sha256=HYn39wynxeWKyWLGKpnBrutnb1Yq6k1tp6_vH-L_UKQ,33839
8
10
  test/test_client_mr_200.py,sha256=86yANn5SUhVW6Uc5q5s_aTNL7tDnREeXk378G61v_TM,1186
11
+ test/test_client_r.py,sha256=AMZklBTLDmnlluNu8hyJfty-1lnN9YReIT522D2Bf9c,20565
9
12
  test/test_client_re330.py,sha256=MgefuvOzfZtZOujrcOsjiTDiGEAujfeFXshcq7gn32Q,17044
10
13
  test/test_client_vr400v2.py,sha256=J1MFUQKGX0czhYS2s8q1Fa8-aKAZ9RfWb0rE_yAxXmg,1813
11
14
  test/test_client_wdr.py,sha256=0ZnRNP57MbuMv2cxFS8iIoVyv8Q6gtY0Q03gtHp9AWY,13492
12
- test/test_client_xdr.py,sha256=mgn-xL5mD5sHD8DjTz9vpY7jeh4Ob6Um6Y8v5Qgx2jA,23374
13
- tplinkrouterc6u/__init__.py,sha256=dq5IS4GKagOBm5Hd9YbIfZHLUcfiLZ1O2LwRFAyZoBI,1225
15
+ test/test_client_xdr.py,sha256=o0d1mq5ev1wWcs7FvwYGMUKDSVZJREETZk__7Al5EtI,23640
16
+ tplinkrouterc6u/__init__.py,sha256=K5c8sBDldVKcD_OfMB83U3xfEkLyRfxdE3VAtbsMMAo,1419
14
17
  tplinkrouterc6u/client_abstract.py,sha256=3UYzmll774S_Gb5E0FTVO_rI3-XFM7PSklg1-V-2jls,1419
15
- tplinkrouterc6u/provider.py,sha256=gzsWGgkxqOSxxLcCjx3eHVkTQteE6DG1XuYziBp6C6s,2863
18
+ tplinkrouterc6u/provider.py,sha256=XeUXzrpgo35DhFG7FvgcAtD0oZZlXl8OOyPfNAVfxMI,3224
16
19
  tplinkrouterc6u/client/__init__.py,sha256=KBy3fmtA9wgyFrb0Urh2x4CkKtWVnESdp-vxmuOvq0k,27
17
20
  tplinkrouterc6u/client/c1200.py,sha256=4XEYidEGmVIJk0YQLvmTnd0Gqa7glH2gUWvjreHpWrk,3178
21
+ tplinkrouterc6u/client/c3200.py,sha256=GjaOjcVoKlRiSjn19d1rEIfZbIP_6SWsqDlsd_BbC7I,7057
18
22
  tplinkrouterc6u/client/c5400x.py,sha256=ID9jC-kLUBBeETvOh8cxyQpKmJBIzdwNYR03DmvMN0s,4289
19
- tplinkrouterc6u/client/c6u.py,sha256=wGxqXiqOA6-Vt1shSygYiJAnFgjgx6gPYUuALJ-KO8k,19919
23
+ tplinkrouterc6u/client/c6u.py,sha256=7OGRnAfc9S7-v2-CrM0rayqesYkhIPouK7LJUV2opno,23574
20
24
  tplinkrouterc6u/client/c80.py,sha256=efE0DEjEfzRFr35fjKA_hsv9YaWy_2dgLAaurDM-WQk,17665
21
25
  tplinkrouterc6u/client/deco.py,sha256=cpKRggKD2RvSmMZuD6tzsZmehAUCU9oLiTTHcZBW81Y,8898
22
- tplinkrouterc6u/client/ex.py,sha256=iVLTtLe1uNwNtv43zHzbLJkZL3SHsBllVBM-MVlnseE,14881
23
- tplinkrouterc6u/client/mr.py,sha256=kNXk0bzBIIIM-4jMZOFp370vDPMJKwt2HmWGMjktguk,28954
24
- tplinkrouterc6u/client/mr200.py,sha256=febM1Eoc2_8NGJu-NrrAdj9zrlP_n7dOU6EVKktzMnw,5801
26
+ tplinkrouterc6u/client/ex.py,sha256=qqlVJi2BIlMLjL9A2_Yi-5AFk18A1Ts8zW6qRPQQWQM,15016
27
+ tplinkrouterc6u/client/mr.py,sha256=Yh7U0nWa_l5HKrUM5fDGewQlxHlyK-JcoPFXmSDgog4,29606
28
+ tplinkrouterc6u/client/mr200.py,sha256=Z02ew7ZLCEdNyGB7mcPHPP-oaAUwJyt7euc2ubiuEo4,5891
29
+ tplinkrouterc6u/client/mr6400v7.py,sha256=PR7dk4Q0OMqMwnuExpHFjanCYAcZ2gjnJ0XoMV-ex8I,2407
30
+ tplinkrouterc6u/client/r.py,sha256=H-qArD60gasT07pEeY48n0_c6-yUbAKL7IRmQtr6jXk,7632
25
31
  tplinkrouterc6u/client/re330.py,sha256=9Wj4VpYJbVwZJUh9s3magdeL3Jl-B7qyrWfrVBxRk4A,17465
26
32
  tplinkrouterc6u/client/vr.py,sha256=7Tbu0IrWtr4HHtyrnLFXEJi1QctzhilciL7agtwQ0R8,5025
27
33
  tplinkrouterc6u/client/vr400v2.py,sha256=ZgQ3w4s9cqhAYgq-xr7l64v1pCT3izdw6amG9XfM0cA,4208
28
34
  tplinkrouterc6u/client/wdr.py,sha256=i54PEifjhfOScDpgNBXygw9U4bfsVtle846_YjnDoBs,21679
29
- tplinkrouterc6u/client/xdr.py,sha256=jdDhQZgJjReN3wMWKch4VHEun2OzUFyzmOWyY5-1IP8,10490
35
+ tplinkrouterc6u/client/xdr.py,sha256=CQN5h2f2oUuwjbtUeOjisBT8K1a72snIDxsWMc_qGik,10917
30
36
  tplinkrouterc6u/common/__init__.py,sha256=pCTvVZ9CAwgb7MxRnLx0y1rI0sTKSwT24FfxWfQXeTM,33
31
37
  tplinkrouterc6u/common/dataclass.py,sha256=NmwN6Iqpd9Ne7Zr-R0J1OZQz28NRp5Qzh6NjVFZV_DA,7749
32
38
  tplinkrouterc6u/common/encryption.py,sha256=EWfgGafOz0YgPilBndVaupnjw6JrzhVBdZkBy3oWhj0,10229
33
39
  tplinkrouterc6u/common/exception.py,sha256=_0G8ZvW5__CsGifHrsZeULdl8c6EUD071sDCQsQgrHY,140
34
40
  tplinkrouterc6u/common/helper.py,sha256=23b04fk9HuVinrZXMCS5R1rmF8uZ7eM-Cdnp7Br9NR0,572
35
41
  tplinkrouterc6u/common/package_enum.py,sha256=CMHVSgk4RSZyFoPi3499-sJDYg-nfnyJbz1iArFU9Hw,1644
36
- tplinkrouterc6u-5.12.4.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
37
- tplinkrouterc6u-5.12.4.dist-info/METADATA,sha256=c3pEsJxHJhU-xNBwxD8l8TocAPojogYWBm4-FrqF5Rg,17634
38
- tplinkrouterc6u-5.12.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
- tplinkrouterc6u-5.12.4.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
40
- tplinkrouterc6u-5.12.4.dist-info/RECORD,,
42
+ tplinkrouterc6u-5.14.0.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
43
+ tplinkrouterc6u-5.14.0.dist-info/METADATA,sha256=9FKClNuCn3ur3yEcnUmUZ5G7eBBN-j1aCyfBQZGtxmY,17853
44
+ tplinkrouterc6u-5.14.0.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
45
+ tplinkrouterc6u-5.14.0.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
46
+ tplinkrouterc6u-5.14.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5