tplinkrouterc6u 5.0.3__py3-none-any.whl → 5.2.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,263 @@
1
+ from datetime import timedelta
2
+ from ipaddress import IPv4Address
3
+ from logging import Logger
4
+ from urllib.parse import unquote
5
+
6
+ from macaddress import EUI48
7
+ from requests import Session
8
+
9
+ from tplinkrouterc6u.client_abstract import AbstractRouter
10
+ from tplinkrouterc6u.common.dataclass import (Device, Firmware, IPv4DHCPLease,
11
+ IPv4Reservation, IPv4Status,
12
+ Status)
13
+ from tplinkrouterc6u.common.exception import ClientException
14
+ from tplinkrouterc6u.common.helper import get_ip, get_mac
15
+ from tplinkrouterc6u.common.package_enum import Connection
16
+
17
+
18
+ class TPLinkXDRClient(AbstractRouter):
19
+ _stok = ''
20
+
21
+ def __init__(self, host: str, password: str, username: str = 'admin', logger: Logger = None,
22
+ verify_ssl: bool = True, timeout: int = 30) -> None:
23
+ super().__init__(host, password, username, logger, verify_ssl, timeout)
24
+ self._session = Session()
25
+
26
+ def supports(self) -> bool:
27
+ response = self._session.get(self.host, timeout=self.timeout, verify=self._verify_ssl)
28
+ return response.text.index('TL-XDR') >= 0
29
+
30
+ def authorize(self) -> None:
31
+ response = self._session.post(self.host, json={
32
+ 'method': 'do',
33
+ 'login': {
34
+ 'password': self._encode_password(self.password),
35
+ }
36
+ }, timeout=self.timeout, verify=self._verify_ssl)
37
+ try:
38
+ data = response.json()
39
+ self._stok = data['stok']
40
+ except Exception as e:
41
+ error = ('TplinkRouter - {} - Cannot authorize! Error - {}; Response - {}'.
42
+ format(self.__class__.__name__, e, response))
43
+ raise ClientException(error)
44
+
45
+ def logout(self) -> None:
46
+ data = self._request({
47
+ 'method': 'do',
48
+ 'system': {
49
+ 'logout': None,
50
+ },
51
+ })
52
+ if data['error_code'] != 0:
53
+ raise ClientException('TplinkRouter - {} - logout failed, code - {}'.
54
+ format(self.__class__, data['error_code']))
55
+ self._stok = ''
56
+
57
+ def get_firmware(self) -> Firmware:
58
+ data = self._request({
59
+ 'method': 'get',
60
+ 'device_info': {
61
+ 'name': 'info',
62
+ },
63
+ })
64
+ dev_info = data['device_info']['info']
65
+ return Firmware(dev_info['hw_version'], dev_info['device_model'], dev_info['sw_version'])
66
+
67
+ def get_status(self) -> Status:
68
+ data = self._request({
69
+ 'method': 'get',
70
+ 'hosts_info': {
71
+ 'table': 'host_info',
72
+ },
73
+ 'network': {
74
+ 'name': [
75
+ 'wan_status',
76
+ 'lan',
77
+ ],
78
+ },
79
+ 'wireless': {
80
+ 'name': [
81
+ 'wlan_bs',
82
+ 'wlan_host_2g',
83
+ 'wlan_wds_2g',
84
+ 'wlan_host_5g',
85
+ 'wlan_wds_5g',
86
+ ]
87
+ },
88
+ 'guest_network': {
89
+ 'name': [
90
+ 'guest_2g',
91
+ ]
92
+ }
93
+ })
94
+
95
+ status = Status()
96
+ status._wan_ipv4_addr = get_ip(data['network']['wan_status']['ipaddr'])
97
+ status._lan_ipv4_addr = get_ip(data['network']['lan']['ipaddr'])
98
+ status._lan_macaddr = get_mac(data['network']['lan']['macaddr'])
99
+ status.wifi_2g_enable = data['wireless']['wlan_host_2g']['enable'] == '1'
100
+ status.wifi_5g_enable = (data['wireless']['wlan_host_5g']['enable'] == '1' or
101
+ data['wireless']['wlan_bs']['bs_enable'] == '1')
102
+ status.guest_2g_enable = data['guest_network']['guest_2g']['enable'] == '1'
103
+
104
+ for item_map in data['hosts_info']['host_info']:
105
+ item = item_map[next(iter(item_map))]
106
+ conn_type = Connection.UNKNOWN
107
+ if item['type'] == '0':
108
+ conn_type = Connection.WIRED
109
+ elif item['type'] == '1' and item['wifi_mode'] == '0':
110
+ conn_type = Connection.HOST_2G
111
+ elif item['type'] == '1' and item['wifi_mode'] == '1':
112
+ conn_type = Connection.HOST_5G
113
+
114
+ dev = Device(conn_type, get_mac(item['mac']), get_ip(item['ip']), unquote(item['hostname']))
115
+ dev.up_speed = item['up_speed']
116
+ dev.down_speed = item['down_speed']
117
+ status.devices.append(dev)
118
+ return status
119
+
120
+ def get_ipv4_reservations(self) -> [IPv4Reservation]:
121
+ data = self._request({
122
+ 'method': 'get',
123
+ 'ip_mac_bind': {
124
+ 'table': 'user_bind',
125
+ },
126
+ })
127
+
128
+ ipv4_reservations = []
129
+ for item_map in data['ip_mac_bind']['user_bind']:
130
+ item = item_map[next(iter(item_map))]
131
+ ipv4_reservations.append(IPv4Reservation(
132
+ EUI48(item['mac']),
133
+ IPv4Address(item['ip']),
134
+ item['hostname'],
135
+ True,
136
+ ))
137
+ return ipv4_reservations
138
+
139
+ def get_ipv4_dhcp_leases(self) -> [IPv4DHCPLease]:
140
+ data = self._request({
141
+ 'method': 'get',
142
+ 'dhcpd': {
143
+ 'table': 'dhcp_clients',
144
+ },
145
+ })
146
+
147
+ dhcp_leases = []
148
+ for item_map in data['dhcpd']['dhcp_clients']:
149
+ item = item_map[next(iter(item_map))]
150
+ dhcp_leases.append(IPv4DHCPLease(
151
+ get_mac(item['mac']),
152
+ get_ip(item['ip']),
153
+ item['hostname'],
154
+ str(timedelta(seconds=int(item['expires']))) if item['expires'] != '4294967295' else 'Permanent',
155
+ ))
156
+ return dhcp_leases
157
+
158
+ def get_ipv4_status(self) -> IPv4Status:
159
+ data = self._request({
160
+ 'method': 'get',
161
+ 'dhcpd': {
162
+ 'name': 'udhcpd',
163
+ },
164
+ 'network': {
165
+ 'name': [
166
+ 'lan',
167
+ 'wan_status',
168
+ ],
169
+ },
170
+ })
171
+
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'])
182
+ return ipv4_status
183
+
184
+ def reboot(self) -> None:
185
+ data = self._request({
186
+ 'method': 'do',
187
+ 'system': {
188
+ 'reboot': None,
189
+ },
190
+ })
191
+ self._stok = ''
192
+ if data['error_code'] != 0:
193
+ raise ClientException('TplinkRouter - {} - reboot failed, code - {}'.
194
+ format(self.__class__, data['error_code']))
195
+
196
+ def set_wifi(self, wifi: Connection, enable: bool) -> None:
197
+ payload_map = {
198
+ Connection.HOST_2G: {
199
+ 'method': 'set',
200
+ 'wireless': {
201
+ 'wlan_host_2g': {
202
+ 'enable': 1 if enable else 0,
203
+ },
204
+ },
205
+ },
206
+ Connection.HOST_5G: {
207
+ 'method': 'set',
208
+ 'wireless': {
209
+ 'wlan_host_5g': {
210
+ 'enable': 1 if enable else 0,
211
+ },
212
+ },
213
+ },
214
+ Connection.GUEST_2G: {
215
+ 'method': 'set',
216
+ 'guest_network': {
217
+ 'guest_2g': {
218
+ 'enable': '1' if enable else '0',
219
+ },
220
+ },
221
+ },
222
+ }
223
+ if wifi not in payload_map:
224
+ raise ClientException('Not supported')
225
+ payload = payload_map[wifi]
226
+ data = self._request(payload)
227
+ if data['error_code'] != 0:
228
+ raise ClientException('TplinkRouter - {} - set wifi failed, code - {}'.
229
+ format(self.__class__, data['error_code']))
230
+
231
+ def _request(self, payload: dict) -> dict:
232
+ url = '{}/stok={}/ds'.format(self.host, self._stok)
233
+ response = self._session.post(url, json=payload, timeout=self.timeout, verify=self._verify_ssl)
234
+ return response.json()
235
+
236
+ @staticmethod
237
+ def _encode_password(pwd: str) -> str:
238
+ return TPLinkXDRClient._security_encode(
239
+ pwd,
240
+ 'RDpbLfCPsJZ7fiv',
241
+ ('yLwVl0zKqws7LgKPRQ84Mdt708T1qQ3Ha7xv3H7NyU84p21BriUWBU43odz3iP4rBL3cD'
242
+ '02KZciXTysVXiV8ngg6vL48rPJyAUw0HurW20xqxv9aYb4M9wK1Ae0wlro510qXeU07kV57fQMc8L6aLg'
243
+ 'MLwygtc0F10a0Dg70TOoouyFhdysuRMO51yY5ZlOZZLEal1h0t9YQW0Ko7oBwmCAHoic4HYbUyVeU3sfQ'
244
+ '1xtXcPcf1aT303wAQhv66qzW'),
245
+ )
246
+
247
+ @staticmethod
248
+ def _security_encode(data1: str, data2: str, char_dict: str) -> str:
249
+ data1_len = len(data1)
250
+ data2_len = len(data2)
251
+ dict_len = len(char_dict)
252
+ res = ''
253
+ for c in range(max(data1_len, data2_len)):
254
+ a = b = 187
255
+ if c >= data1_len:
256
+ a = ord(data2[c])
257
+ elif c >= data2_len:
258
+ b = ord(data1[c])
259
+ else:
260
+ b = ord(data1[c])
261
+ a = ord(data2[c])
262
+ res += char_dict[(b ^ a) % dict_len]
263
+ return res
@@ -0,0 +1,48 @@
1
+ from requests.packages import urllib3
2
+ from logging import Logger
3
+ from tplinkrouterc6u.common.package_enum import Connection
4
+ from tplinkrouterc6u.common.dataclass import Firmware, Status
5
+ from abc import ABC, abstractmethod
6
+
7
+
8
+ class AbstractRouter(ABC):
9
+ def __init__(self, host: str, password: str, username: str = 'admin', logger: Logger = None,
10
+ verify_ssl: bool = True, timeout: int = 30) -> None:
11
+ self.username = username
12
+ self.password = password
13
+ self.timeout = timeout
14
+ self._logger = logger
15
+ self.host = host
16
+ if not (self.host.startswith('http://') or self.host.startswith('https://')):
17
+ self.host = "http://{}".format(self.host)
18
+ self._verify_ssl = verify_ssl
19
+ if self._verify_ssl is False:
20
+ urllib3.disable_warnings()
21
+
22
+ @abstractmethod
23
+ def supports(self) -> bool:
24
+ pass
25
+
26
+ @abstractmethod
27
+ def authorize(self) -> None:
28
+ pass
29
+
30
+ @abstractmethod
31
+ def logout(self) -> None:
32
+ pass
33
+
34
+ @abstractmethod
35
+ def get_firmware(self) -> Firmware:
36
+ pass
37
+
38
+ @abstractmethod
39
+ def get_status(self) -> Status:
40
+ pass
41
+
42
+ @abstractmethod
43
+ def reboot(self) -> None:
44
+ pass
45
+
46
+ @abstractmethod
47
+ def set_wifi(self, wifi: Connection, enable: bool) -> None:
48
+ pass
@@ -0,0 +1 @@
1
+ """All extra classes are here"""
@@ -1,7 +1,8 @@
1
1
  from macaddress import EUI48
2
2
  from ipaddress import IPv4Address
3
3
  from dataclasses import dataclass
4
- from tplinkrouterc6u.package_enum import Connection
4
+ from datetime import datetime
5
+ from tplinkrouterc6u.common.package_enum import Connection
5
6
 
6
7
 
7
8
  @dataclass
@@ -23,6 +24,7 @@ class Device:
23
24
  self.packets_received: int | None = None
24
25
  self.down_speed: int | None = None
25
26
  self.up_speed: int | None = None
27
+ self.signal: int | None = None
26
28
 
27
29
  @property
28
30
  def macaddr(self):
@@ -246,3 +248,40 @@ class IPv4Status:
246
248
  @property
247
249
  def lan_ipv4_netmask_address(self):
248
250
  return self._lan_ipv4_netmask
251
+
252
+
253
+ @dataclass
254
+ class SMS:
255
+ def __init__(self, index: int, sender: str, content: str, received_at: datetime, unread: bool) -> None:
256
+ self.id = index
257
+ self.sender = sender
258
+ self.content = content
259
+ self.received_at = received_at
260
+ self.unread = unread
261
+
262
+
263
+ @dataclass
264
+ class LTEStatus:
265
+ def __init__(self) -> None:
266
+ self.enable: int
267
+ self.connect_status: int
268
+ self.network_type: int
269
+ self.sim_status: int
270
+ self.total_statistics: int
271
+ self.cur_rx_speed: int
272
+ self.cur_tx_speed: int
273
+ self.sms_unread_count: int
274
+ self.sig_level: int
275
+ self.rsrp: int
276
+ self.rsrq: int
277
+ self.snr: int
278
+ self.isp_name: str
279
+
280
+
281
+ @dataclass
282
+ class VPNStatus:
283
+ def __init__(self) -> None:
284
+ self.openvpn_enable: bool
285
+ self.pptpvpn_enable: bool
286
+ self.openvpn_clients_total: int = 0
287
+ self.pptpvpn_clients_total: int = 0
@@ -44,3 +44,8 @@ class Connection(Enum):
44
44
  elif self == Connection.WIRED:
45
45
  band = 'wired'
46
46
  return band
47
+
48
+
49
+ class VPN(Enum):
50
+ OPEN_VPN = 'OPENVPN'
51
+ PPTP_VPN = 'PPTPVPN'
@@ -0,0 +1,39 @@
1
+ from logging import Logger
2
+
3
+ from tplinkrouterc6u import TPLinkXDRClient
4
+ from tplinkrouterc6u.common.exception import ClientException, AuthorizeError
5
+ from tplinkrouterc6u.client.c6u import TplinkRouter
6
+ from tplinkrouterc6u.client.deco import TPLinkDecoClient
7
+ from tplinkrouterc6u.client_abstract import AbstractRouter
8
+ from tplinkrouterc6u.client.mr import TPLinkMRClient
9
+ from tplinkrouterc6u.client.ex import TPLinkEXClient
10
+ from tplinkrouterc6u.client.c6v4 import TplinkC6V4Router
11
+ from tplinkrouterc6u.client.c5400x import TplinkC5400XRouter
12
+ from tplinkrouterc6u.client.c1200 import TplinkC1200Router
13
+
14
+
15
+ class TplinkRouterProvider:
16
+ @staticmethod
17
+ def get_client(host: str, password: str, username: str = 'admin', logger: Logger = None,
18
+ verify_ssl: bool = True, timeout: int = 30) -> AbstractRouter:
19
+ for client in [TplinkC5400XRouter, TPLinkEXClient, TPLinkMRClient, TplinkC6V4Router, TPLinkDecoClient,
20
+ TPLinkXDRClient, TplinkRouter]:
21
+ router = client(host, password, username, logger, verify_ssl, timeout)
22
+ if router.supports():
23
+ return router
24
+
25
+ router = TplinkC1200Router(host, password, username, logger, verify_ssl, timeout)
26
+ try:
27
+ router.authorize()
28
+ return router
29
+ except AuthorizeError as e:
30
+ if logger:
31
+ logger.error(e.__str__())
32
+ raise ClientException(('Login failed! Please check if your router local password is correct or '
33
+ 'try to use web encrypted password instead. Check the documentation!'
34
+ ))
35
+ except Exception as e:
36
+ if logger:
37
+ logger.error(e.__str__())
38
+ raise ClientException('Try to use web encrypted password instead. Check the documentation! '
39
+ + e.__str__())
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tplinkrouterc6u
3
- Version: 5.0.3
3
+ Version: 5.2.0
4
4
  Summary: TP-Link Router API
5
5
  Home-page: https://github.com/AlexandrErohin/TP-Link-Archer-C6U
6
6
  Author: Alex Erohin
@@ -44,6 +44,8 @@ from tplinkrouterc6u import (
44
44
  TplinkC1200Router,
45
45
  TplinkC5400XRouter,
46
46
  TPLinkMRClient,
47
+ TPLinkEXClient,
48
+ TPLinkXDRClient,
47
49
  TPLinkDecoClient,
48
50
  Connection
49
51
  )
@@ -106,10 +108,17 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
106
108
  | get_ipv4_reservations | | Gets IPv4 reserved addresses (static) | [[IPv4Reservation]](#IPv4Reservation) |
107
109
  | get_ipv4_dhcp_leases | | Gets IPv4 addresses assigned via DHCP | [[IPv4DHCPLease]](#IPv4DHCPLease) |
108
110
  | set_wifi | wifi: [Connection](#connection), enable: bool | Allow to turn on/of 4 wifi networks | |
109
- | send_sms | phone_number: str, message: str | Send sms for LTE routers | |
110
111
  | reboot | | reboot router |
111
112
  | authorize | | authorize for actions |
112
113
  | logout | | logout after all is done |
114
+ | get_vpn_status | | Gets VPN info for OpenVPN and PPTPVPN and connected clients amount | [VPNStatus](#vpn_status) |
115
+ | set_vpn | vpn: [VPNStatus](#vpn_status), enable: bool | Allow to turn on/of VPN | |
116
+ | send_sms | phone_number: str, message: str | Send sms for LTE routers | |
117
+ | send_ussd | command: str | Send USSD command for LTE routers | str |
118
+ | get_sms | | Get sms messages from the first page for LTE routers | [[SMS]](#sms) |
119
+ | set_sms_read | sms: [SMS](#sms) | Set sms message read from the first page for LTE routers | |
120
+ | delete_sms | sms: [SMS](#sms) | Delete sms message from the first page for LTE routers | |
121
+ | get_lte_status | | Get lte info for LTE routers | [LTEStatus](#lte_status) |
113
122
 
114
123
  ## Dataclass
115
124
  ### <a id="firmware">Firmware</a>
@@ -164,6 +173,7 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
164
173
  | packets_received | total packets received | int, None |
165
174
  | down_speed | download speed | int, None |
166
175
  | up_speed | upload speed | int, None |
176
+ | signal | Signal strength | int, None |
167
177
 
168
178
  ### <a id="IPv4Reservation">IPv4Reservation</a>
169
179
  | Field | Description | Type |
@@ -210,6 +220,40 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
210
220
  | lan_ipv4_netmask_address | router LAN gateway IP netmask | ipaddress |
211
221
  | remote | router remote | bool, None |
212
222
 
223
+ ### <a id="vpn_status">VPNStatus</a>
224
+ | Field | Description | Type |
225
+ | --- |---|---|
226
+ | openvpn_enable | OpenVPN is enabled | bool |
227
+ | pptpvpn_enable | PPTPVPN is enabled | bool |
228
+ | openvpn_clients_total | OpenVPN clients connected | int |
229
+ | pptpvpn_clients_total | PPTPVPN clients connected | int |
230
+
231
+ ### <a id="sms">SMS</a>
232
+ | Field | Description | Type |
233
+ | --- |---|---|
234
+ | id | message index | int |
235
+ | sender| sender | str |
236
+ | content| sms text | str |
237
+ | received_at| received datetime | datetime |
238
+ | unread| is message unread | bool |
239
+
240
+ ### <a id="lte_status">LTEStatus</a>
241
+ | Field | Description | Type |
242
+ | --- |---|---|
243
+ | enable | is enabled | int |
244
+ | connect_status | connect status | int |
245
+ | network_type | network type | int |
246
+ | sim_status | sim status | int |
247
+ | total_statistics | total statistics in bytes | int |
248
+ | cur_rx_speed | current download speed in bytes per second | int |
249
+ | cur_tx_speed | current upload speed in bytes per second | int |
250
+ | sms_unread_count | sms unread amount | int |
251
+ | sig_level | signal level | int |
252
+ | rsrp | RSRP | int |
253
+ | rsrq | RSRQ | int |
254
+ | snr | SNR | int |
255
+ | isp_name | ISP name | str |
256
+
213
257
  ## Enum
214
258
  ### <a id="connection">Connection</a>
215
259
  - Connection.HOST_2G - host wifi 2.4G
@@ -223,6 +267,10 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
223
267
  - Connection.IOT_6G - IoT wifi 6G
224
268
  - Connection.WIRED - Wired
225
269
 
270
+ ### <a id="vpn">VPN</a>
271
+ - VPN.OPEN_VPN
272
+ - VPN.PPTP_VPN
273
+
226
274
  ## <a id="supports">Supported routers</a>
227
275
  ### Fully tested Hardware Versions
228
276
  - Archer A7 V5
@@ -271,11 +319,13 @@ or you have TP-link C5400X or similar router you need to get web encrypted passw
271
319
  - Deco X60 V3
272
320
  - Deco X90
273
321
  - Deco XE75 (v1.0, v2.0)
322
+ - EX511 v2.0
274
323
  - TD-W9960 (v1, V1.20)
275
324
  - TL-MR100 v2.0
276
325
  - TL-MR105
277
326
  - TL-MR6400 (v5, v5.3)
278
327
  - TL-MR6500v
328
+ - TL-XDR3010 V2
279
329
  - TL-WA3001 v1.0
280
330
 
281
331
  ### Not fully tested Hardware Versions
@@ -0,0 +1,30 @@
1
+ test/__init__.py,sha256=McQmUjeN3AwmwdS6QNfwGXXE77OKoPK852I2BM9XsrU,210
2
+ test/test_client_c1200.py,sha256=O6NK9uXIEb_vks6lI3g7j6q8TYJ9MSDFYzGA_wOBhOA,4620
3
+ test/test_client_c6u.py,sha256=qC0PNE-Hz3d8PYIGej4j_M4cLDqffnPiXu_ff7Ft29M,30709
4
+ test/test_client_deco.py,sha256=ur4u-pWB-6WaYW6PSpK9OvCg3rfo2x06V5Cf_eE2UYU,30447
5
+ test/test_client_ex.py,sha256=cSIMh6yjiAknt0mk7u1dCpXVzZTR_Y95XvXRBRusbpg,17092
6
+ test/test_client_mr.py,sha256=Uomg3T_SA5Y1tb4wlniMKQDi_uJ2Vqm30I-GKgOXBRc,32703
7
+ test/test_client_xdr.py,sha256=G64aS5yvjuFMImvTzVTcbI4-FVOJY_hm8d0y69H-1Gc,18965
8
+ tplinkrouterc6u/__init__.py,sha256=bLlCkiL9ycyRVG7VqPOJWPcoPmUfMkdTcUKFYKNP8QI,900
9
+ tplinkrouterc6u/client_abstract.py,sha256=OgftTH6bELzhFWom0MOX4EJe3RNS003ezpHyyRnh2tQ,1328
10
+ tplinkrouterc6u/provider.py,sha256=SsyGu_2SZ-a46ADl9aw_0wx0lgbsJhS6wnwUzb_1qGg,1900
11
+ tplinkrouterc6u/client/__init__.py,sha256=KBy3fmtA9wgyFrb0Urh2x4CkKtWVnESdp-vxmuOvq0k,27
12
+ tplinkrouterc6u/client/c1200.py,sha256=4XEYidEGmVIJk0YQLvmTnd0Gqa7glH2gUWvjreHpWrk,3178
13
+ tplinkrouterc6u/client/c5400x.py,sha256=EhcNcaj2U8OBSv1Bftrg3rH9ylP_73P2VO1JHA9CYO4,4322
14
+ tplinkrouterc6u/client/c6u.py,sha256=8n3nMW20k3SEXamCYzq7-mzBM6wyn5Txl6XxzjHEa6c,17411
15
+ tplinkrouterc6u/client/c6v4.py,sha256=-IF7SqTZx56lRAVmiyxK9VKkrmD7srQSJWFvn2Z0DII,1489
16
+ tplinkrouterc6u/client/deco.py,sha256=0Hwy_kVQshYd-5Oa3mIASaZI_4NUD09NFEdRyPtzjdI,8265
17
+ tplinkrouterc6u/client/ex.py,sha256=jkxCgqbjp-SfjlzgKeNj4WhV3v9gEOzKgrgfVgy9SB4,11604
18
+ tplinkrouterc6u/client/mr.py,sha256=1-aP8xo5JUiFzKmeyOjolzyKR_yIUwTBrRG562tmfAg,25638
19
+ tplinkrouterc6u/client/xdr.py,sha256=1YWM00OSTTj3XCJ2bINf2qU3yQZmORmWzLqFwOVqC_0,9782
20
+ tplinkrouterc6u/common/__init__.py,sha256=pCTvVZ9CAwgb7MxRnLx0y1rI0sTKSwT24FfxWfQXeTM,33
21
+ tplinkrouterc6u/common/dataclass.py,sha256=__u8I8URLk_AdIEN4Jd8Pswh4ujURlJxw8YunuVStwk,7630
22
+ tplinkrouterc6u/common/encryption.py,sha256=4HelTxzN6esMfDZRBt3m8bwB9Nj_biKijnCnrGWPWKg,6228
23
+ tplinkrouterc6u/common/exception.py,sha256=_0G8ZvW5__CsGifHrsZeULdl8c6EUD071sDCQsQgrHY,140
24
+ tplinkrouterc6u/common/helper.py,sha256=phcPUdpY7lJVWF8Ih4KHNdsdem2ed6qFSDXuEAtAgug,334
25
+ tplinkrouterc6u/common/package_enum.py,sha256=py31wF7SntZ0D_o0PS7az29wtsWdp0r0uE7QMmiWigY,1451
26
+ tplinkrouterc6u-5.2.0.dist-info/LICENSE,sha256=YF6QR6Vjxcg5b_sYIyqkME7FZYau5TfEUGTG-0JeRK0,35129
27
+ tplinkrouterc6u-5.2.0.dist-info/METADATA,sha256=yDOAsf0yPwBDG8Xius3t5HpaSkwkxeFUHVdJtVYZSlA,14917
28
+ tplinkrouterc6u-5.2.0.dist-info/WHEEL,sha256=R06PA3UVYHThwHvxuRWMqaGcr-PuniXahwjmQRFMEkY,91
29
+ tplinkrouterc6u-5.2.0.dist-info/top_level.txt,sha256=1iSCCIueqgEkrTxtQ-jiHe99jAB10zqrVdBcwvNfe_M,21
30
+ tplinkrouterc6u-5.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.4.0)
2
+ Generator: setuptools (75.5.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5