tplinkrouterc6u 5.12.3__py3-none-any.whl → 5.13.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.
@@ -376,7 +376,8 @@ class TplinkBaseRouter(AbstractRouter, TplinkRequest):
376
376
  pass
377
377
 
378
378
  status.devices = list(devices.values())
379
- status.clients_total = status.wired_total + status.wifi_clients_total + status.guest_clients_total
379
+ status.clients_total = (status.wired_total + status.wifi_clients_total + status.guest_clients_total
380
+ + (status.iot_clients_total or 0))
380
381
 
381
382
  return status
382
383
 
@@ -489,3 +490,100 @@ class TplinkRouter(TplinkEncryption, TplinkBaseRouter):
489
490
  self._url_pptpd = 'admin/pptpd?form=config'
490
491
  self._url_vpnconn_openvpn = 'admin/vpnconn?form=config'
491
492
  self._url_vpnconn_pptpd = 'admin/vpnconn?form=config'
493
+
494
+
495
+ class TplinkRouterV1_11(TplinkBaseRouter):
496
+ """
497
+ Router client for newer TP-Link firmware (1.11.0+) that uses simplified
498
+ RSA-only authentication without AES encryption wrapper.
499
+
500
+ Based on fix from: https://github.com/AlexandrErohin/TP-Link-Archer-C6U/issues/90
501
+ """
502
+
503
+ def __init__(self, host: str, password: str, username: str = 'admin', logger: Logger = None,
504
+ verify_ssl: bool = True, timeout: int = 30) -> None:
505
+ super().__init__(host, password, username, logger, verify_ssl, timeout)
506
+ self._pwdNN = ''
507
+ self._pwdEE = ''
508
+
509
+ def supports(self) -> bool:
510
+ """Check if this client can handle the router (new firmware with RSA-only auth)."""
511
+ if len(self.password) > 125:
512
+ return False
513
+
514
+ try:
515
+ self._request_pwd()
516
+ # V1_11 uses 2048-bit RSA = 512 hex chars, older firmware uses 1024-bit = 256 chars
517
+ return len(self._pwdNN) >= 512
518
+ except Exception:
519
+ return False
520
+
521
+ def _request_pwd(self) -> None:
522
+ """Get RSA public key for password encryption."""
523
+ url = '{}/cgi-bin/luci/;stok=/login?form=keys'.format(self.host)
524
+
525
+ response = post(
526
+ url,
527
+ params={'operation': 'read'},
528
+ timeout=self.timeout,
529
+ verify=self._verify_ssl,
530
+ )
531
+
532
+ try:
533
+ data = response.json()
534
+ self._pwdNN = data[self._data_block]['password'][0]
535
+ self._pwdEE = data[self._data_block]['password'][1]
536
+ except Exception as e:
537
+ error = ('TplinkRouter - {} - Failed to get encryption keys! Error - {}; Response - {}'
538
+ .format(self.__class__.__name__, e, response.text))
539
+ if self._logger:
540
+ self._logger.debug(error)
541
+ raise ClientException(error)
542
+
543
+ def authorize(self) -> None:
544
+ """Authorize using simplified RSA-only authentication (no AES encryption)."""
545
+ if self._pwdNN == '':
546
+ self._request_pwd()
547
+
548
+ # RSA encrypt password using existing utility
549
+ encrypted_pwd = EncryptionWrapper.rsa_encrypt(self.password, self._pwdNN, self._pwdEE)
550
+
551
+ # Simple login - just operation=login&password=<HEX>
552
+ url = '{}/cgi-bin/luci/;stok=/login?form=login'.format(self.host)
553
+ response = post(
554
+ url,
555
+ data='operation=login&password={}'.format(encrypted_pwd),
556
+ headers=self._headers_login,
557
+ timeout=self.timeout,
558
+ verify=self._verify_ssl,
559
+ )
560
+
561
+ try:
562
+ data = response.json()
563
+ if not data.get('success'):
564
+ error_info = data.get(self._data_block, {})
565
+ raise ClientException(
566
+ 'TplinkRouter - {} - Login failed: {}'.format(
567
+ self.__class__.__name__,
568
+ error_info.get('errorcode', 'unknown error')
569
+ )
570
+ )
571
+
572
+ self._stok = data[self._data_block]['stok']
573
+
574
+ # Get sysauth cookie
575
+ if 'set-cookie' in response.headers:
576
+ regex_result = search(r'sysauth=([^;]+)', response.headers['set-cookie'])
577
+ if regex_result:
578
+ self._sysauth = regex_result.group(1)
579
+
580
+ self._logged = True
581
+
582
+ except ClientException:
583
+ raise
584
+ except Exception as e:
585
+ error = ('TplinkRouter - {} - Cannot authorize! Error - {}; Response - {}'
586
+ .format(self.__class__.__name__, e, response.text))
587
+ if self._logger:
588
+ self._logger.debug(error)
589
+ raise ClientException(error)
@@ -114,17 +114,15 @@ class TPLinkEXClient(TPLinkMRClientBase):
114
114
  status._wan_ipv4_addr = IPv4Address(item['connIPv4Address']) if item.get('connIPv4Address') else None
115
115
  status._wan_ipv4_gateway = IPv4Address(item['connIPv4Gateway']) if item.get('connIPv4Address') else None
116
116
 
117
- if values[2].__class__ != list:
118
- status.wifi_2g_enable = bool(int(values[2]['primaryEnable']))
119
- else:
120
- status.wifi_2g_enable = bool(int(values[2][0]['primaryEnable']))
121
- status.wifi_5g_enable = bool(int(values[2][1]['primaryEnable']))
122
-
123
- if values[2].__class__ != list:
124
- status.guest_2g_enable = bool(int(values[2]['guestEnable']))
125
- else:
126
- status.guest_2g_enable = bool(int(values[2][0]['guestEnable']))
127
- status.guest_5g_enable = bool(int(values[2][1]['guestEnable']))
117
+ if values[2]:
118
+ if values[2].__class__ != list:
119
+ status.wifi_2g_enable = bool(int(values[2]['primaryEnable']))
120
+ status.guest_2g_enable = bool(int(values[2]['guestEnable']))
121
+ else:
122
+ status.wifi_2g_enable = bool(int(values[2][0]['primaryEnable']))
123
+ status.wifi_5g_enable = bool(int(values[2][1]['primaryEnable']))
124
+ status.guest_2g_enable = bool(int(values[2][0]['guestEnable']))
125
+ status.guest_5g_enable = bool(int(values[2][1]['guestEnable']))
128
126
 
129
127
  devices = {}
130
128
  for val in self._to_list(values[3]):
@@ -141,7 +139,7 @@ class TPLinkEXClient(TPLinkMRClientBase):
141
139
  status.wifi_clients_total += 1
142
140
  devices[val['physAddress']] = Device(conn,
143
141
  EUI48(val['physAddress']),
144
- IPv4Address(val['IPAddress']),
142
+ get_ip(val['IPAddress']),
145
143
  val['hostName'])
146
144
 
147
145
  total = int(values[4]['total'])
@@ -371,7 +371,7 @@ class TPLinkMRClientBase(AbstractRouter):
371
371
  lines = response.split('\n')
372
372
  for line in lines:
373
373
  if line.startswith('['):
374
- regexp = search(r'\[\d,\d,\d,\d,\d,\d\](\d)', line)
374
+ regexp = search(r'\[\d+,\d+,\d+,\d+,\d+,\d+](\d+)', line)
375
375
  if regexp is not None:
376
376
  obj = {}
377
377
  index = regexp.group(1)
@@ -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,7 +2,7 @@ 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
@@ -13,6 +13,7 @@ from tplinkrouterc6u.client.c1200 import TplinkC1200Router
13
13
  from tplinkrouterc6u.client.c80 import TplinkC80Router
14
14
  from tplinkrouterc6u.client.vr import TPLinkVRClient
15
15
  from tplinkrouterc6u.client.vr400v2 import TPLinkVR400v2Client
16
+ from tplinkrouterc6u.client.r import TPLinkRClient
16
17
  from tplinkrouterc6u.client.wdr import TplinkWDRRouter
17
18
  from tplinkrouterc6u.client.re330 import TplinkRE330Router
18
19
 
@@ -32,6 +33,8 @@ class TplinkRouterProvider:
32
33
  TPLinkVR400v2Client,
33
34
  TPLinkDecoClient,
34
35
  TPLinkXDRClient,
36
+ TPLinkRClient,
37
+ TplinkRouterV1_11,
35
38
  TplinkRouter,
36
39
  TplinkC80Router,
37
40
  TplinkWDRRouter,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tplinkrouterc6u
3
- Version: 5.12.3
3
+ Version: 5.13.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,6 +56,7 @@ 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,
@@ -66,6 +67,7 @@ from tplinkrouterc6u import (
66
67
  TPLinkVR400v2Client,
67
68
  TPLinkEXClient, # Class for EX series routers which supports old firmwares with AES cipher CBC mode
68
69
  TPLinkEXClientGCM, # Class for EX series routers which supports AES cipher GCM mode
70
+ TPLinkRClient,
69
71
  TPLinkXDRClient,
70
72
  TPLinkDecoClient,
71
73
  TplinkC80Router,
@@ -83,7 +85,7 @@ router = TplinkRouterProvider.get_client('http://192.168.0.1', 'password')
83
85
  # If you have the TP-link C5400X or similar, you can use the TplinkC5400XRouter class instead of the TplinkRouter class.
84
86
  # Remember that the password for this router is different, here you need to use the web encrypted password.
85
87
  # To get web encrypted password, read Web Encrypted Password section
86
- # router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', Logger('test'))
88
+ # router = TplinkC5400XRouter('http://192.168.0.1','WebEncryptedPassword', logger: Logger('test'))
87
89
 
88
90
  try:
89
91
  router.authorize() # authorizing
@@ -372,6 +374,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
372
374
  - Deco P7
373
375
  - Deco X20
374
376
  - Deco X50 v1.3
377
+ - Deco X50-5G 1.20
375
378
  - Deco X55 1.0
376
379
  - Deco X60 V3
377
380
  - Deco X90
@@ -379,7 +382,10 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
379
382
  - Deco XE75PRO (v3.0)
380
383
  - EX511 v2.0
381
384
  - HX510 v1.0
385
+ - M8550 v1
386
+ - NE200-Outdoor v1.0
382
387
  - NX510v v1.0
388
+ - NX600 v2.0
383
389
  - TD-W9960 (v1, V1.20)
384
390
  - TL-MR100 v2.0
385
391
  - TL-MR105
@@ -388,10 +394,13 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
388
394
  - TL-MR150 v2
389
395
  - TL-MR6400 (v5, v5.3)
390
396
  - TL-MR6500v
397
+ - TL-R470GP-AC 4.0
398
+ - TL-R488GPM-AC 2.0
391
399
  - TL-WA1201 3.0
392
400
  - TL-WA3001 v1.0
393
401
  - TL-XDR3010 V2
394
402
  - TL-WDR3600 V1
403
+ - TL-XDR5410 1.0
395
404
  - TL-XDR6088 v1.0.30
396
405
  - VX420-G2h v1.1
397
406
  - VX800v v1
@@ -403,6 +412,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
403
412
  - AC10 1.20
404
413
  - MR47BE v1.0
405
414
  - MR50G 1.0
415
+ - ME30 1.0
406
416
  - H60XR 1.0
407
417
  - H47BE 2.0
408
418
  - Halo H80X 1.0
@@ -1,40 +1,43 @@
1
1
  test/__init__.py,sha256=McQmUjeN3AwmwdS6QNfwGXXE77OKoPK852I2BM9XsrU,210
2
2
  test/test_client_c1200.py,sha256=Sl-85JGqINNg-ckBZCIVqY0CC-V1UOc-yiIUljtePRM,7582
3
- test/test_client_c6u.py,sha256=j9IpkZaWAedqkSktIGhjK8YZMhCkQhHnhqAmAWzEAYc,40399
3
+ test/test_client_c6u.py,sha256=GGYReY9RmnkJDgcaWtzbti-hTkab2D8JXxZCPt0wTfk,41662
4
+ test/test_client_c6u_v1_11.py,sha256=FkpDRYk-LKC_YFNyrDUZUm7_x89REMnl4zquiEtyFB4,3343
4
5
  test/test_client_c80.py,sha256=RY_1SgRVcQQdN9h0_IXA0YW4_0flEB_uel05QvDDfws,42359
5
6
  test/test_client_deco.py,sha256=YPLKRD8GoyDYHfRgdXvCk8iVNw8zdMJW-AHVnNbpdTM,31719
6
- test/test_client_ex.py,sha256=Kg6svEKtyGAfyF9yrLh2qZa2tK1mlEBJJwXRsq1MAjo,26591
7
+ test/test_client_ex.py,sha256=ny7ube06QbI1h_UT0bAUllhLK2sqQ4Mb3WwtY8kDoRY,31374
7
8
  test/test_client_mr.py,sha256=lePxkmjcPzcrSFcaT8bT67L154cVJIOWrFlXMDOa8oY,33423
8
9
  test/test_client_mr_200.py,sha256=86yANn5SUhVW6Uc5q5s_aTNL7tDnREeXk378G61v_TM,1186
10
+ test/test_client_r.py,sha256=AMZklBTLDmnlluNu8hyJfty-1lnN9YReIT522D2Bf9c,20565
9
11
  test/test_client_re330.py,sha256=MgefuvOzfZtZOujrcOsjiTDiGEAujfeFXshcq7gn32Q,17044
10
12
  test/test_client_vr400v2.py,sha256=J1MFUQKGX0czhYS2s8q1Fa8-aKAZ9RfWb0rE_yAxXmg,1813
11
13
  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
14
+ test/test_client_xdr.py,sha256=o0d1mq5ev1wWcs7FvwYGMUKDSVZJREETZk__7Al5EtI,23640
15
+ tplinkrouterc6u/__init__.py,sha256=1L-1-RMN0M9JoF2PhKuE-sKa5qdsU5Mw0JfjkE6kXrs,1295
14
16
  tplinkrouterc6u/client_abstract.py,sha256=3UYzmll774S_Gb5E0FTVO_rI3-XFM7PSklg1-V-2jls,1419
15
- tplinkrouterc6u/provider.py,sha256=gzsWGgkxqOSxxLcCjx3eHVkTQteE6DG1XuYziBp6C6s,2863
17
+ tplinkrouterc6u/provider.py,sha256=VhMqts5OPDvFIScuDoGGqU5_PtNBTtqisi_QVfNvpaE,3013
16
18
  tplinkrouterc6u/client/__init__.py,sha256=KBy3fmtA9wgyFrb0Urh2x4CkKtWVnESdp-vxmuOvq0k,27
17
19
  tplinkrouterc6u/client/c1200.py,sha256=4XEYidEGmVIJk0YQLvmTnd0Gqa7glH2gUWvjreHpWrk,3178
18
20
  tplinkrouterc6u/client/c5400x.py,sha256=ID9jC-kLUBBeETvOh8cxyQpKmJBIzdwNYR03DmvMN0s,4289
19
- tplinkrouterc6u/client/c6u.py,sha256=Lh0YktqD4mRdQ_Q6b-fy_s_bgLx3cEdyoD5doOIbOzI,19851
21
+ tplinkrouterc6u/client/c6u.py,sha256=7OGRnAfc9S7-v2-CrM0rayqesYkhIPouK7LJUV2opno,23574
20
22
  tplinkrouterc6u/client/c80.py,sha256=efE0DEjEfzRFr35fjKA_hsv9YaWy_2dgLAaurDM-WQk,17665
21
23
  tplinkrouterc6u/client/deco.py,sha256=cpKRggKD2RvSmMZuD6tzsZmehAUCU9oLiTTHcZBW81Y,8898
22
- tplinkrouterc6u/client/ex.py,sha256=tOcMugCViAcISULg8otp3NjdkPyuUXihcoe_0lql3AQ,14886
23
- tplinkrouterc6u/client/mr.py,sha256=7MtnKqmtbggWBx6RIiJzlGuSyVDbC8MFynPrc34bSd0,28948
24
+ tplinkrouterc6u/client/ex.py,sha256=YzuKOkzCIXFhe1ggD8FP5d1fq1z2iWSmnXh0NTRiuy0,14880
25
+ tplinkrouterc6u/client/mr.py,sha256=kNXk0bzBIIIM-4jMZOFp370vDPMJKwt2HmWGMjktguk,28954
24
26
  tplinkrouterc6u/client/mr200.py,sha256=febM1Eoc2_8NGJu-NrrAdj9zrlP_n7dOU6EVKktzMnw,5801
27
+ tplinkrouterc6u/client/r.py,sha256=H-qArD60gasT07pEeY48n0_c6-yUbAKL7IRmQtr6jXk,7632
25
28
  tplinkrouterc6u/client/re330.py,sha256=9Wj4VpYJbVwZJUh9s3magdeL3Jl-B7qyrWfrVBxRk4A,17465
26
29
  tplinkrouterc6u/client/vr.py,sha256=7Tbu0IrWtr4HHtyrnLFXEJi1QctzhilciL7agtwQ0R8,5025
27
30
  tplinkrouterc6u/client/vr400v2.py,sha256=ZgQ3w4s9cqhAYgq-xr7l64v1pCT3izdw6amG9XfM0cA,4208
28
31
  tplinkrouterc6u/client/wdr.py,sha256=i54PEifjhfOScDpgNBXygw9U4bfsVtle846_YjnDoBs,21679
29
- tplinkrouterc6u/client/xdr.py,sha256=jdDhQZgJjReN3wMWKch4VHEun2OzUFyzmOWyY5-1IP8,10490
32
+ tplinkrouterc6u/client/xdr.py,sha256=CQN5h2f2oUuwjbtUeOjisBT8K1a72snIDxsWMc_qGik,10917
30
33
  tplinkrouterc6u/common/__init__.py,sha256=pCTvVZ9CAwgb7MxRnLx0y1rI0sTKSwT24FfxWfQXeTM,33
31
34
  tplinkrouterc6u/common/dataclass.py,sha256=NmwN6Iqpd9Ne7Zr-R0J1OZQz28NRp5Qzh6NjVFZV_DA,7749
32
35
  tplinkrouterc6u/common/encryption.py,sha256=EWfgGafOz0YgPilBndVaupnjw6JrzhVBdZkBy3oWhj0,10229
33
36
  tplinkrouterc6u/common/exception.py,sha256=_0G8ZvW5__CsGifHrsZeULdl8c6EUD071sDCQsQgrHY,140
34
37
  tplinkrouterc6u/common/helper.py,sha256=23b04fk9HuVinrZXMCS5R1rmF8uZ7eM-Cdnp7Br9NR0,572
35
38
  tplinkrouterc6u/common/package_enum.py,sha256=CMHVSgk4RSZyFoPi3499-sJDYg-nfnyJbz1iArFU9Hw,1644
36
- tplinkrouterc6u-5.12.3.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
37
- tplinkrouterc6u-5.12.3.dist-info/METADATA,sha256=rkchRBKj215L408MdAzr8nHC67LtBQxEzHDzTnAU734,17604
38
- tplinkrouterc6u-5.12.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
39
- tplinkrouterc6u-5.12.3.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
40
- tplinkrouterc6u-5.12.3.dist-info/RECORD,,
39
+ tplinkrouterc6u-5.13.0.dist-info/licenses/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
40
+ tplinkrouterc6u-5.13.0.dist-info/METADATA,sha256=nPa1F-ywVtgS8vH5U6y5WL7-Mxa1l3cgaEbsg7nTxA0,17785
41
+ tplinkrouterc6u-5.13.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
42
+ tplinkrouterc6u-5.13.0.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
43
+ tplinkrouterc6u-5.13.0.dist-info/RECORD,,