solax-py-library 1.0.0.15__py3-none-any.whl → 1.0.0.17__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.
- solax_py_library/__init__.py +1 -1
- solax_py_library/{upload/errors/base.py → exception.py} +10 -10
- solax_py_library/snap_shot/__init__.py +3 -4
- solax_py_library/snap_shot/constant/__init__.py +5 -0
- solax_py_library/snap_shot/constant/crc_table.py +258 -0
- solax_py_library/snap_shot/core/__init__.py +7 -0
- solax_py_library/snap_shot/{base_modbus.py → core/base_modbus.py} +14 -14
- solax_py_library/snap_shot/{core.py → core/snap_shot.py} +249 -219
- solax_py_library/snap_shot/exceptions/__init__.py +3 -0
- solax_py_library/snap_shot/exceptions/snap_shot.py +9 -0
- solax_py_library/snap_shot/test/__init__.py +0 -0
- solax_py_library/snap_shot/types/__init__.py +15 -0
- solax_py_library/snap_shot/types/address.py +39 -0
- solax_py_library/upload/__init__.py +3 -3
- solax_py_library/upload/api/__init__.py +3 -3
- solax_py_library/upload/api/service.py +24 -24
- solax_py_library/upload/core/__init__.py +3 -3
- solax_py_library/upload/core/data_adapter/__init__.py +5 -5
- solax_py_library/upload/core/data_adapter/base.py +9 -9
- solax_py_library/upload/core/data_adapter/csv.py +26 -26
- solax_py_library/upload/core/upload_service/__init__.py +15 -15
- solax_py_library/upload/core/upload_service/base.py +43 -43
- solax_py_library/upload/core/upload_service/ftp.py +97 -86
- solax_py_library/upload/{errors → exceptions}/__init__.py +10 -10
- solax_py_library/upload/{errors → exceptions}/upload_error.py +21 -21
- solax_py_library/upload/test/test_ftp.py +81 -40
- solax_py_library/upload/types/__init__.py +11 -11
- solax_py_library/upload/types/client.py +19 -19
- solax_py_library/upload/types/ftp.py +37 -37
- solax_py_library/utils/__init__.py +0 -0
- solax_py_library/{snap_shot/untils.py → utils/common.py} +19 -17
- solax_py_library/{snap_shot → utils}/parser.py +225 -224
- {solax_py_library-1.0.0.15.dist-info → solax_py_library-1.0.0.17.dist-info}/METADATA +4 -4
- solax_py_library-1.0.0.17.dist-info/RECORD +36 -0
- {solax_py_library-1.0.0.15.dist-info → solax_py_library-1.0.0.17.dist-info}/WHEEL +1 -1
- solax_py_library/snap_shot/address.py +0 -67
- solax_py_library/snap_shot/exceptions.py +0 -4
- solax_py_library-1.0.0.15.dist-info/RECORD +0 -29
@@ -1,37 +1,37 @@
|
|
1
|
-
import os
|
2
|
-
from enum import IntEnum
|
3
|
-
from typing import Any, Optional
|
4
|
-
|
5
|
-
from pydantic import BaseModel
|
6
|
-
|
7
|
-
|
8
|
-
class FTPFileType(IntEnum):
|
9
|
-
CSV = 1
|
10
|
-
|
11
|
-
@classmethod
|
12
|
-
def get_file_suffix(cls, value):
|
13
|
-
return {
|
14
|
-
FTPFileType.CSV: ".csv",
|
15
|
-
}.get(value)
|
16
|
-
|
17
|
-
|
18
|
-
class FTPData(BaseModel):
|
19
|
-
file_type: FTPFileType
|
20
|
-
file_name: str
|
21
|
-
data: Any
|
22
|
-
|
23
|
-
def build_full_path(self, remote_path) -> str:
|
24
|
-
return os.path.join(remote_path, self.file_name)
|
25
|
-
|
26
|
-
|
27
|
-
class FTPServiceConfig(BaseModel):
|
28
|
-
host: str
|
29
|
-
port: int
|
30
|
-
user: Optional[str]
|
31
|
-
password: Optional[str]
|
32
|
-
remote_path: str
|
33
|
-
|
34
|
-
|
35
|
-
class FTPParsedData(BaseModel):
|
36
|
-
file_name: str
|
37
|
-
file_path: str
|
1
|
+
import os
|
2
|
+
from enum import IntEnum
|
3
|
+
from typing import Any, Optional
|
4
|
+
|
5
|
+
from pydantic import BaseModel
|
6
|
+
|
7
|
+
|
8
|
+
class FTPFileType(IntEnum):
|
9
|
+
CSV = 1
|
10
|
+
|
11
|
+
@classmethod
|
12
|
+
def get_file_suffix(cls, value):
|
13
|
+
return {
|
14
|
+
FTPFileType.CSV: ".csv",
|
15
|
+
}.get(value)
|
16
|
+
|
17
|
+
|
18
|
+
class FTPData(BaseModel):
|
19
|
+
file_type: FTPFileType
|
20
|
+
file_name: str
|
21
|
+
data: Any
|
22
|
+
|
23
|
+
def build_full_path(self, remote_path) -> str:
|
24
|
+
return os.path.join(remote_path, self.file_name)
|
25
|
+
|
26
|
+
|
27
|
+
class FTPServiceConfig(BaseModel):
|
28
|
+
host: str
|
29
|
+
port: int
|
30
|
+
user: Optional[str]
|
31
|
+
password: Optional[str]
|
32
|
+
remote_path: str
|
33
|
+
|
34
|
+
|
35
|
+
class FTPParsedData(BaseModel):
|
36
|
+
file_name: str
|
37
|
+
file_path: str
|
File without changes
|
@@ -1,17 +1,19 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
def retry(max_attempts=3, delay=0.5):
|
5
|
-
def decorator(func):
|
6
|
-
async def wrapper(*args, **kwargs):
|
7
|
-
attempts = 0
|
8
|
-
while attempts < max_attempts:
|
9
|
-
try:
|
10
|
-
return await func(*args, **kwargs)
|
11
|
-
except Exception as e:
|
12
|
-
print(f"尝试 {attempts+1} 失败: {e}")
|
13
|
-
await asyncio.sleep(delay)
|
14
|
-
attempts += 1
|
15
|
-
raise SnapshotTimeoutError(f"操作失败 {max_attempts} 次")
|
16
|
-
|
17
|
-
|
1
|
+
import asyncio
|
2
|
+
|
3
|
+
|
4
|
+
def retry(max_attempts=3, delay=0.5):
|
5
|
+
def decorator(func):
|
6
|
+
async def wrapper(*args, **kwargs):
|
7
|
+
attempts = 0
|
8
|
+
while attempts < max_attempts:
|
9
|
+
try:
|
10
|
+
return await func(*args, **kwargs)
|
11
|
+
except Exception as e:
|
12
|
+
print(f"尝试 {attempts+1} 失败: {e}")
|
13
|
+
await asyncio.sleep(delay)
|
14
|
+
attempts += 1
|
15
|
+
raise SnapshotTimeoutError(f"操作失败 {max_attempts} 次")
|
16
|
+
|
17
|
+
return wrapper
|
18
|
+
|
19
|
+
return decorator
|
@@ -1,224 +1,225 @@
|
|
1
|
-
import re
|
2
|
-
import struct
|
3
|
-
|
4
|
-
from .address import
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
"
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
"""
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
) -> bytes:
|
79
|
-
"""
|
80
|
-
构建接收应答帧(指令类型 0x80)
|
81
|
-
:param task_id: 任务ID(32字节)
|
82
|
-
:param business_type: 业务类型(0或1)
|
83
|
-
:param ack_code: 0-成功,1-失败,2-执行中
|
84
|
-
"""
|
85
|
-
# 固定字段
|
86
|
-
header = bytes([0x24, 0x24])
|
87
|
-
func_code = bytes([0x05, 0x07]) # 主功能码5 + 子功能码7
|
88
|
-
|
89
|
-
# 数据域
|
90
|
-
task_bytes = task_id.encode(
|
91
|
-
business_byte = bytes([business_type])
|
92
|
-
cmd_byte = bytes([CommandType.ACK.value])
|
93
|
-
ack_byte = bytes([ack_code])
|
94
|
-
data_part = task_bytes + business_byte + cmd_byte + ack_byte
|
95
|
-
|
96
|
-
# 计算长度(功能码2字节 + 数据域37字节 + CRC2字节 = 41)
|
97
|
-
frame_length = len(func_code) + len(data_part) + 2
|
98
|
-
length_bytes = struct.pack(
|
99
|
-
|
100
|
-
# 构建临时帧并计算CRC
|
101
|
-
temp_frame = header + length_bytes + func_code + data_part
|
102
|
-
crc = self.crc(temp_frame.hex()).upper()
|
103
|
-
full_frame = temp_frame + bytes.fromhex(crc)
|
104
|
-
return full_frame
|
105
|
-
|
106
|
-
def build_total_packets_frame(
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
#
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
)
|
132
|
-
|
133
|
-
# 计算长度
|
134
|
-
frame_length = len(func_code) + len(data_part) + 2
|
135
|
-
length_bytes = struct.pack(
|
136
|
-
|
137
|
-
# 附加CRC
|
138
|
-
temp_frame = header + length_bytes + func_code + data_part
|
139
|
-
crc = self.crc(temp_frame.hex()).upper()
|
140
|
-
return temp_frame + bytes.fromhex(crc)
|
141
|
-
|
142
|
-
def build_data_packet_frame(
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
) -> bytes:
|
151
|
-
"""
|
152
|
-
构建具体分包数据帧(指令类型 0x82)
|
153
|
-
"""
|
154
|
-
header = bytes([0x24, 0x24])
|
155
|
-
func_code = bytes([0x05, 0x07])
|
156
|
-
|
157
|
-
# 数据域
|
158
|
-
task_bytes = task_id.encode(
|
159
|
-
business_byte = bytes([business_type])
|
160
|
-
cmd_byte = bytes([CommandType.DATA_PACKET.value])
|
161
|
-
data_type_byte = bytes([data_type])
|
162
|
-
total_packets_bytes = struct.pack(
|
163
|
-
current_packet_bytes = struct.pack(
|
164
|
-
data_length = struct.pack(
|
165
|
-
|
166
|
-
data_part = (
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
"""
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
da
|
220
|
-
|
221
|
-
crc
|
222
|
-
i
|
223
|
-
|
224
|
-
|
1
|
+
import re
|
2
|
+
import struct
|
3
|
+
|
4
|
+
from solax_py_library.snap_shot.types.address import CommandType
|
5
|
+
from solax_py_library.snap_shot.constant.crc_table import CRC_Table
|
6
|
+
|
7
|
+
|
8
|
+
class Parser:
|
9
|
+
def parse(self, char16):
|
10
|
+
"""
|
11
|
+
:return:
|
12
|
+
"""
|
13
|
+
task_id = self.ascii_to_str(char16[12:76]) # task_id
|
14
|
+
device_type = int(char16[76:78]) # 设备类型
|
15
|
+
device_sn = self.ascii_to_str(char16[78:118]) # 设备SN
|
16
|
+
business_type = int(char16[118:120])
|
17
|
+
data = char16[120:]
|
18
|
+
return {
|
19
|
+
"task_id": task_id,
|
20
|
+
"sn": device_sn,
|
21
|
+
"device_type": device_type,
|
22
|
+
"business_type": business_type,
|
23
|
+
"message": char16,
|
24
|
+
"data": data,
|
25
|
+
}
|
26
|
+
|
27
|
+
def ascii_to_str(self, data: str):
|
28
|
+
"""阿斯科码转字符串"""
|
29
|
+
pattern = re.compile(".{2}")
|
30
|
+
message = "\\u00" + "\\u00".join(pattern.findall(data))
|
31
|
+
message = message.replace("\\u0000", "")
|
32
|
+
message = bytes(message, encoding="utf-8").decode("unicode-escape")
|
33
|
+
return message
|
34
|
+
|
35
|
+
def upload_data(self, big_data: bytes, task_id: str, upload_data):
|
36
|
+
business_type = 1 # 1 代表调试信息
|
37
|
+
data_type = 0 # 0代表故障录波
|
38
|
+
|
39
|
+
# 分片上传(每包1K)
|
40
|
+
chunk_size = 1024
|
41
|
+
total_chunks = (len(big_data) + chunk_size - 1) // chunk_size
|
42
|
+
|
43
|
+
# 遍历分片并构造数据包
|
44
|
+
for chunk_idx, chunk_data in self.data_chunk_generator(big_data, chunk_size):
|
45
|
+
frame = self.build_data_packet_frame(
|
46
|
+
task_id=task_id,
|
47
|
+
business_type=business_type,
|
48
|
+
data_type=data_type,
|
49
|
+
total_packets=total_chunks,
|
50
|
+
current_packet=chunk_idx,
|
51
|
+
chunk_data=chunk_data,
|
52
|
+
)
|
53
|
+
|
54
|
+
print(f"发送包 {chunk_idx + 1}/{total_chunks}, 长度={len(frame)} 字节")
|
55
|
+
upload_data(frame)
|
56
|
+
|
57
|
+
def data_chunk_generator(self, data: bytes, chunk_size: int = 1024):
|
58
|
+
"""
|
59
|
+
将大数据按固定包大小分片
|
60
|
+
:param data: 原始数据字节流
|
61
|
+
:param chunk_size: 每包最大字节数(默认1024)
|
62
|
+
:yield: (当前包序号, 分片数据)
|
63
|
+
"""
|
64
|
+
total = len(data)
|
65
|
+
if total == 0:
|
66
|
+
yield (0, b"") # 空数据单独处理
|
67
|
+
return
|
68
|
+
|
69
|
+
total_chunks = (total + chunk_size - 1) // chunk_size
|
70
|
+
|
71
|
+
for i in range(total_chunks):
|
72
|
+
start = i * chunk_size
|
73
|
+
end = start + chunk_size
|
74
|
+
yield (i, data[start:end])
|
75
|
+
|
76
|
+
def build_response_frame(
|
77
|
+
self, task_id: str, business_type: int, ack_code: int
|
78
|
+
) -> bytes:
|
79
|
+
"""
|
80
|
+
构建接收应答帧(指令类型 0x80)
|
81
|
+
:param task_id: 任务ID(32字节)
|
82
|
+
:param business_type: 业务类型(0或1)
|
83
|
+
:param ack_code: 0-成功,1-失败,2-执行中
|
84
|
+
"""
|
85
|
+
# 固定字段
|
86
|
+
header = bytes([0x24, 0x24])
|
87
|
+
func_code = bytes([0x05, 0x07]) # 主功能码5 + 子功能码7
|
88
|
+
|
89
|
+
# 数据域
|
90
|
+
task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
|
91
|
+
business_byte = bytes([business_type])
|
92
|
+
cmd_byte = bytes([CommandType.ACK.value])
|
93
|
+
ack_byte = bytes([ack_code])
|
94
|
+
data_part = task_bytes + business_byte + cmd_byte + ack_byte
|
95
|
+
|
96
|
+
# 计算长度(功能码2字节 + 数据域37字节 + CRC2字节 = 41)
|
97
|
+
frame_length = len(func_code) + len(data_part) + 2
|
98
|
+
length_bytes = struct.pack("<H", frame_length)
|
99
|
+
|
100
|
+
# 构建临时帧并计算CRC
|
101
|
+
temp_frame = header + length_bytes + func_code + data_part
|
102
|
+
crc = self.crc(temp_frame.hex()).upper()
|
103
|
+
full_frame = temp_frame + bytes.fromhex(crc)
|
104
|
+
return full_frame
|
105
|
+
|
106
|
+
def build_total_packets_frame(
|
107
|
+
self, task_id: str, business_type: int, data_type: int, total_packets: int
|
108
|
+
) -> bytes:
|
109
|
+
"""
|
110
|
+
构建上报总包数帧(指令类型 0x81)
|
111
|
+
:param total_packets: 总包数(若为0,平台停止接收)
|
112
|
+
"""
|
113
|
+
header = bytes([0x24, 0x24])
|
114
|
+
func_code = bytes([0x05, 0x07])
|
115
|
+
|
116
|
+
# 数据域
|
117
|
+
task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
|
118
|
+
business_byte = bytes([business_type])
|
119
|
+
cmd_byte = bytes([CommandType.TOTAL_PACKETS.value])
|
120
|
+
data_length = struct.pack("<H", 2) # 数据长度固定2字节
|
121
|
+
data_type_byte = bytes([data_type])
|
122
|
+
total_packets_bytes = struct.pack("<H", total_packets)
|
123
|
+
|
124
|
+
data_part = (
|
125
|
+
task_bytes
|
126
|
+
+ business_byte
|
127
|
+
+ cmd_byte
|
128
|
+
+ data_length
|
129
|
+
+ data_type_byte
|
130
|
+
+ total_packets_bytes
|
131
|
+
)
|
132
|
+
|
133
|
+
# 计算长度
|
134
|
+
frame_length = len(func_code) + len(data_part) + 2
|
135
|
+
length_bytes = struct.pack("<H", frame_length)
|
136
|
+
|
137
|
+
# 附加CRC
|
138
|
+
temp_frame = header + length_bytes + func_code + data_part
|
139
|
+
crc = self.crc(temp_frame.hex()).upper()
|
140
|
+
return temp_frame + bytes.fromhex(crc)
|
141
|
+
|
142
|
+
def build_data_packet_frame(
|
143
|
+
self,
|
144
|
+
task_id: str,
|
145
|
+
business_type: int,
|
146
|
+
data_type: int,
|
147
|
+
total_packets: int,
|
148
|
+
current_packet: int,
|
149
|
+
chunk_data: bytes,
|
150
|
+
) -> bytes:
|
151
|
+
"""
|
152
|
+
构建具体分包数据帧(指令类型 0x82)
|
153
|
+
"""
|
154
|
+
header = bytes([0x24, 0x24])
|
155
|
+
func_code = bytes([0x05, 0x07])
|
156
|
+
|
157
|
+
# 数据域
|
158
|
+
task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
|
159
|
+
business_byte = bytes([business_type])
|
160
|
+
cmd_byte = bytes([CommandType.DATA_PACKET.value])
|
161
|
+
data_type_byte = bytes([data_type])
|
162
|
+
total_packets_bytes = struct.pack("<H", total_packets)
|
163
|
+
current_packet_bytes = struct.pack("<H", current_packet)
|
164
|
+
data_length = struct.pack("<H", len(chunk_data))
|
165
|
+
|
166
|
+
data_part = (
|
167
|
+
task_bytes
|
168
|
+
+ business_byte
|
169
|
+
+ cmd_byte
|
170
|
+
+ data_type_byte
|
171
|
+
+ total_packets_bytes
|
172
|
+
+ current_packet_bytes
|
173
|
+
+ data_length
|
174
|
+
+ chunk_data
|
175
|
+
)
|
176
|
+
|
177
|
+
# 计算长度
|
178
|
+
frame_length = len(func_code) + len(data_part) + 2
|
179
|
+
length_bytes = struct.pack("<H", frame_length)
|
180
|
+
|
181
|
+
# 附加CRC
|
182
|
+
temp_frame = header + length_bytes + func_code + data_part
|
183
|
+
crc = self.crc(temp_frame.hex()).upper()
|
184
|
+
return temp_frame + bytes.fromhex(crc)
|
185
|
+
|
186
|
+
def build_error_frame(
|
187
|
+
self, task_id: str, business_type: int, error_type: int
|
188
|
+
) -> bytes:
|
189
|
+
"""
|
190
|
+
构建报错应答帧(指令类型 0x83)
|
191
|
+
|
192
|
+
"""
|
193
|
+
header = bytes([0x24, 0x24])
|
194
|
+
func_code = bytes([0x05, 0x07])
|
195
|
+
|
196
|
+
# 数据域
|
197
|
+
task_bytes = task_id.encode("ascii")[:32].ljust(32, b"\x00")
|
198
|
+
business_byte = bytes([business_type])
|
199
|
+
cmd_byte = bytes([CommandType.ERROR.value])
|
200
|
+
error_byte = bytes([error_type])
|
201
|
+
data_part = task_bytes + business_byte + cmd_byte + error_byte
|
202
|
+
|
203
|
+
# 计算长度
|
204
|
+
frame_length = len(func_code) + len(data_part) + 2
|
205
|
+
length_bytes = struct.pack("<H", frame_length)
|
206
|
+
|
207
|
+
# 附加CRC
|
208
|
+
temp_frame = header + length_bytes + func_code + data_part
|
209
|
+
crc = self.crc(temp_frame.hex()).upper()
|
210
|
+
return temp_frame + bytes.fromhex(crc)
|
211
|
+
|
212
|
+
def crc(self, message):
|
213
|
+
"""获取校验位, message: 除去校验位"""
|
214
|
+
crc = 0
|
215
|
+
i = 0
|
216
|
+
length = len(message) // 2
|
217
|
+
while length > 0:
|
218
|
+
crc &= 0xFFFFFFFF
|
219
|
+
da = crc // 256
|
220
|
+
da &= 0xFF
|
221
|
+
crc <<= 8
|
222
|
+
crc ^= CRC_Table[da ^ int(message[i : i + 2], 16)]
|
223
|
+
i += 2
|
224
|
+
length -= 1
|
225
|
+
return f"{crc & 0xffff:04x}"
|
@@ -1,9 +1,9 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.1
|
2
2
|
Name: solax-py-library
|
3
|
-
Version: 1.0.0.
|
3
|
+
Version: 1.0.0.17
|
4
4
|
Summary: some common tool
|
5
|
-
Author:
|
6
|
-
Author-email:
|
5
|
+
Author: shenlvyu
|
6
|
+
Author-email: 13296718439@163.com
|
7
7
|
Requires-Python: >=3.8,<4.0
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
9
|
Classifier: Programming Language :: Python :: 3.8
|
@@ -0,0 +1,36 @@
|
|
1
|
+
solax_py_library/__init__.py,sha256=4wrB7TuGOQaYHQvdn574G4JrcOnH6l8RNSR6AtKAiKc,34
|
2
|
+
solax_py_library/exception.py,sha256=ygAccdTqJctRrdt9bu6-vqZP5KadfKVS_1tjt4KcRn8,257
|
3
|
+
solax_py_library/snap_shot/__init__.py,sha256=OSDexPdSfNVCh15D4f4qFoKHlggIlq93vnAIeVfOw8Y,87
|
4
|
+
solax_py_library/snap_shot/constant/__init__.py,sha256=UNfjAlx1wovXc1oH74af9oIe2TljwCCiTzNXzWgtUms,65
|
5
|
+
solax_py_library/snap_shot/constant/crc_table.py,sha256=D-pSxpf1XDzu7YR8LmbnzdLRvI8exDL2dyDh7RRc4Io,3566
|
6
|
+
solax_py_library/snap_shot/core/__init__.py,sha256=t7RuU89GY58FR12jQXy-3u_np5rTftPFuaODFZqdRNU,137
|
7
|
+
solax_py_library/snap_shot/core/base_modbus.py,sha256=EdDSRvRC2a4IE_LGvjxGznqi6AX5x4O0_Wn1IkHzIpA,403
|
8
|
+
solax_py_library/snap_shot/core/snap_shot.py,sha256=XbzR4yeCgMlLlcy8gEX58xFIc8agCZN7VDXE6SjlDr4,9931
|
9
|
+
solax_py_library/snap_shot/exceptions/__init__.py,sha256=9wLhmIelRKCXvlymcu3EewasVVYuPu4QQxTDLjGj6NQ,112
|
10
|
+
solax_py_library/snap_shot/exceptions/snap_shot.py,sha256=-oxxh_lUhfZwtggJ4zfNBPdkhdGPvcVvDezNlj4nFfY,154
|
11
|
+
solax_py_library/snap_shot/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
12
|
+
solax_py_library/snap_shot/types/__init__.py,sha256=g9ybB88TntvAMGIhLgJ31Xxn26zluSfI496bg-apSTU,290
|
13
|
+
solax_py_library/snap_shot/types/address.py,sha256=JhyB-t2OnKuE8akKk120sojCNXv4_OlLLuWsl5ChFZ8,1148
|
14
|
+
solax_py_library/upload/__init__.py,sha256=M9vBP5Q1mD-hs-voqWNXtzLDKq1FBuFHSLw6a8WhP0E,85
|
15
|
+
solax_py_library/upload/api/__init__.py,sha256=ASShe-YQxP0aA3B_I8EmpWKXIdXPWvaANifrzlYrFEk,84
|
16
|
+
solax_py_library/upload/api/service.py,sha256=ubFepgkG4pQwFAH_f1JJ-mU8ZZrNf9zUMyQ_wy9QN7s,774
|
17
|
+
solax_py_library/upload/core/__init__.py,sha256=XMcnyDzCfsLwWaTAZt9-an7TuwYFqVNSt9W1_QRUrwA,89
|
18
|
+
solax_py_library/upload/core/data_adapter/__init__.py,sha256=9CXepLZSOjZMfNjyYKAWQCWZt353kTL_0tFBlIeUIOo,116
|
19
|
+
solax_py_library/upload/core/data_adapter/base.py,sha256=Va-SEe0eL3gobhNOnzHGkYBLIwf5RVawQdYRHHXg9g0,170
|
20
|
+
solax_py_library/upload/core/data_adapter/csv.py,sha256=8nlnV_43mMAR3re50MQJymzT5HYpZOo7eSeMsEfnEVE,861
|
21
|
+
solax_py_library/upload/core/upload_service/__init__.py,sha256=uA-UeH31rDNxByeZwvPhNFHPV_-J8JyCev8geuc---k,269
|
22
|
+
solax_py_library/upload/core/upload_service/base.py,sha256=dxCBVtPxDhN7oRTjnwnjtc2XAF4hyIz9HsYCJePlggg,912
|
23
|
+
solax_py_library/upload/core/upload_service/ftp.py,sha256=6T8jKgsKXX0Bu_wrGjeYzBnrT331fWy_y38msChqrNs,2923
|
24
|
+
solax_py_library/upload/exceptions/__init__.py,sha256=Tm5zlI3Fn9zLZyOA4ibAXjDXkWOeSi52As-E2dBVzfU,262
|
25
|
+
solax_py_library/upload/exceptions/upload_error.py,sha256=V2_yEMLj9KQEkdQ0Cm1DOogbjZWGb4p8RVnFx7D9yLY,425
|
26
|
+
solax_py_library/upload/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
|
+
solax_py_library/upload/test/test_ftp.py,sha256=tqc7Ag10PqgRewpMsBBG-mfezGK8lsxz3HbKOwQSORQ,2605
|
28
|
+
solax_py_library/upload/types/__init__.py,sha256=og9KBpYbcs36_S1izURj3vyHeuNOLJQrD9GpxK_JJaw,244
|
29
|
+
solax_py_library/upload/types/client.py,sha256=fG674_QEpOw3ibO171lcxJ0cz27yGR_sd3zgiyr4yuI,492
|
30
|
+
solax_py_library/upload/types/ftp.py,sha256=9kCeLB0g5Je19v4ifz8YYEsGOhJL1lKBO2C6V2VBndc,679
|
31
|
+
solax_py_library/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
|
+
solax_py_library/utils/common.py,sha256=MY4Iab1o-jv7JoImcDiRDW12-MTXgwYym8yt_PofqRY,571
|
33
|
+
solax_py_library/utils/parser.py,sha256=74YG14zOopW2am6BQX0zF3NnWTN21pkYcW7gFP1ssko,7703
|
34
|
+
solax_py_library-1.0.0.17.dist-info/METADATA,sha256=bD_ybZjQKgD02r7UnXdESo2vO-3kezzIW7k5bAANCBU,1790
|
35
|
+
solax_py_library-1.0.0.17.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
36
|
+
solax_py_library-1.0.0.17.dist-info/RECORD,,
|