tlkcore 255.255.255__cp39-none-win_amd64.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,211 @@
1
+ import csv
2
+ import logging
3
+ import os
4
+
5
+ from tlkcore.TMYPublic import RetCode, RFMode, BeamType
6
+
7
+ logger = logging.getLogger("TMYBeamConfig")
8
+
9
+ class TMYBeamConfig():
10
+ def __init__(self, sn:str, service, path="CustomBatchBeams.csv", delimiter=","):
11
+ """
12
+ Test for parsing batch beam configs then apply it,
13
+ please edit gains to feet available gain range for your BeamForm devices, e.g., BBoxOne
14
+
15
+ Args:
16
+ sn (str): Device serail number
17
+ service (_type_): TLKCoreService instance
18
+ path (str, optional): _description_. Defaults to "CustomBatchBeams.csv".
19
+ delimiter (str, optional): delimiter in csv. Defaults to ",".
20
+ """
21
+
22
+ self.__sn = sn
23
+ self.__service = service
24
+ self.__config = None
25
+ if not os.path.exists(path):
26
+ logger.error("Not exist: %s" %path)
27
+ return
28
+ self.__config = self.__parse(path, delimiter)
29
+
30
+ def __parse(self, path:str, delimiter:str):
31
+ logger.info("Start to parsing...")
32
+ try:
33
+ aakit_selected = True if self.__service.getAAKitInfo(self.__sn).RetCode is RetCode.OK else False
34
+ logger.info("[AppyBatchBeams] AAKit %sselected" %"" if aakit_selected else "NOT ")
35
+
36
+ file = open(path)
37
+ reader = csv.reader((_.replace('\x00', '') for _ in file), delimiter=delimiter)
38
+ custom = { 'TX': {}, 'RX': {}}
39
+ # Parsing CSV
40
+ for col in reader:
41
+ if len(col) == 0 or len(col[0]) == 0 or col[0] == 'Mode':
42
+ continue
43
+ # print(col)
44
+ mode_name = col[0]
45
+ beamID = int(col[1])
46
+ beam_type = BeamType(int(col[2]))
47
+
48
+ if beam_type is BeamType.BEAM:
49
+ if not aakit_selected:
50
+ logger.warning("PhiA mode not support whole beam config -> skip")
51
+ continue
52
+ # Fetch col 3~5 for db,theta,phi
53
+ config = [col[i] for i in range(3, 6)]
54
+ else: #CHANNEL
55
+ ch = int(col[6])
56
+ # Fetch col 7~9 for sw,db,deg
57
+ config = {str(ch): [col[i] for i in range(7, 10)]}
58
+
59
+ if custom[mode_name].get(str(beamID)) is None:
60
+ # Create new beam config
61
+ beam = {'beam_type': beam_type.value, 'config': config}
62
+ custom[mode_name][str(beamID)] = beam
63
+ else:
64
+ # If exist, replace or add new channel config into beam config
65
+ custom[mode_name][str(beamID)]['config'].update(config)
66
+ # custom[mode_name][str(beamID)].update(beam)
67
+
68
+ # Parsing done
69
+ logger.info("[CustomCSV] " + str(custom))
70
+ return custom
71
+ except:
72
+ logger.exception("Something wrong while parsing")
73
+ return None
74
+
75
+ def getConfig(self):
76
+ if self.__config is None:
77
+ return None
78
+ return self.__config
79
+
80
+ def applyBeams(self):
81
+ try:
82
+ if self.__service is None:
83
+ logger.error("service is None")
84
+ return False
85
+ if self.__config is None:
86
+ logger.error("Beam config is empty!")
87
+ return False
88
+
89
+ service = self.__service
90
+ sn = self.__sn
91
+ custom = self.__config
92
+
93
+ channel_count = service.getChannelCount(sn).RetData
94
+ dr = service.getDR(sn).RetData
95
+ com_dr = service.getCOMDR(sn).RetData
96
+ # print(com_dr)
97
+ ele_dr_limit = service.getELEDR(sn).RetData
98
+ # print(ele_dr_limit)
99
+
100
+ # Get Beam then update custom beam
101
+ for mode_name in [*custom]:
102
+ mode = getattr(RFMode, mode_name)
103
+ # print(mode)
104
+ for id in [*custom[mode_name]]:
105
+ beamID = int(id)
106
+ ret = service.getBeamPattern(sn, mode, beamID)
107
+ beam = ret.RetData
108
+ logger.debug("Get [%s]BeamID %02d info: %s" %(mode_name, beamID, beam))
109
+
110
+ beam_type = BeamType(custom[mode_name][str(beamID)]['beam_type'])
111
+ value = custom[mode_name][str(beamID)]['config']
112
+ logger.info("Get [%s]BeamID %02d custom: %s" %(mode_name, beamID, value))
113
+
114
+ if beam_type is BeamType.BEAM:
115
+ if beam['beam_type'] != beam_type.value:
116
+ # Construct a new config
117
+ beam = {'beam_config': {'db': dr[mode.name][1], 'theta': 0, 'phi':0 }}
118
+ config = beam['beam_config']
119
+ if len(value[0]) > 0:
120
+ config['db'] = float(value[0])
121
+ if len(value[1]) > 0:
122
+ config['theta'] = int(value[1])
123
+ if len(value[2]) > 0:
124
+ config['phi'] = int(value[2])
125
+ else: #CHANNEL
126
+ if beam['beam_type'] != beam_type.value:
127
+ # Construct a new config
128
+ beam = {'channel_config': {}}
129
+ for ch in range(1, channel_count+1):
130
+ if ch%4 == 1: # 4 channels in one board
131
+ # First channel in board: construct brd_cfg
132
+ board = int(ch/4) + 1
133
+ brd_cfg = {}
134
+ # Use MAX COMDR - will check with assign gain to adjust
135
+ brd_cfg['common_db'] = com_dr[mode.value][board-1][1]
136
+ ch_cfg = {
137
+ 'sw': 0,
138
+ # Use MAX ELEDR
139
+ 'db': ele_dr_limit[mode.value][board-1],
140
+ 'deg': 0
141
+ }
142
+ brd_cfg['channel_'+str((ch-1)%4 + 1)] = ch_cfg
143
+ if ch%4 == 0:
144
+ beam['channel_config'].update({'board_'+str(board): brd_cfg})
145
+
146
+ config = beam['channel_config']
147
+
148
+ # Update each channel
149
+ for ch_str, ch_value in value.items():
150
+ ch = int(ch_str)
151
+ if ch > channel_count:
152
+ logger.error("[%s]BeamID %02d - Invalid ch_%s exceeds %d channels! -> skip it"
153
+ %(mode_name, beamID, ch, channel_count))
154
+ return False
155
+ # logger.debug("Update ch%d info: %s" %(ch, ch_value))
156
+ board_idx = int((ch-1)/4)
157
+ board_name = 'board_'+str(board_idx + 1)
158
+ board_ch = (ch-1)%4 + 1
159
+ ch_name = 'channel_'+str(board_ch)
160
+ if len(ch_value[0]) > 0:
161
+ config[board_name][ch_name]['sw'] = int(ch_value[0])
162
+ if len(ch_value[1]) > 0:
163
+ db = float(ch_value[1])
164
+ ele_gain = db - config[board_name]['common_db']
165
+ if ele_gain < 0:
166
+ logger.warning("Ch_%d changed to db:%.1f < com gain:%.1f, adjust com gain later" %(ch, db, config[board_name]['common_db']))
167
+ config[board_name][ch_name]['db'] = ele_gain
168
+ if len(ch_value[2]) > 0:
169
+ config[board_name][ch_name]['deg'] = int(ch_value[2])
170
+ logger.debug("Tmp [%s]BeamID %02d custom: %s" %(mode_name, beamID, config))
171
+
172
+ # Simple check each com_gain, ele_gain for board/channel
173
+ for brd, brd_cfg in config.items():
174
+ brd_idx = int(brd.replace("board_", ""))-1
175
+ brd_db = [v['db'] for k, v in brd_cfg.items() if k.startswith("channel_")]
176
+ # print(brd_db)
177
+ if max(brd_db) - min(brd_db) > ele_dr_limit[mode.value][board_idx]:
178
+ logger.error("[%s]BeamID %02d - [%s] Invalid db setting: %s, the max diff of each db field exceeds the limit: %.1f"
179
+ %(mode_name, beamID, brd, [d+brd_cfg['common_db'] for d in brd_db], ele_dr_limit[mode.value][board_idx]))
180
+ return False
181
+ if min(brd_db) < 0:
182
+ # Lower the common gain to min db
183
+ new_com = brd_cfg['common_db'] + min(brd_db)
184
+ if new_com < com_dr[mode.value][brd_idx][0]:
185
+ logger.error("[%s]BeamID %02d - [%s] Invalid common gain: %.1f < min common gain: %.1f, please tune higher the minimal db field"
186
+ %(mode_name, beamID, brd, new_com, com_dr[mode.value][brd_idx][0]))
187
+ return False
188
+ logger.info("[%s]BeamID %02d - Adjust [%s]com gain: %.1f -> %.1f, and ele gain: %s -> %s"
189
+ %(mode_name, beamID, brd, brd_cfg['common_db'], new_com,
190
+ [v['db'] for k, v in brd_cfg.items() if k.startswith("channel_")],
191
+ [v['db']-min(brd_db) for k, v in brd_cfg.items() if k.startswith("channel_")]))
192
+ brd_cfg['common_db'] = new_com
193
+ for k, v in brd_cfg.items():
194
+ if k.startswith("channel_"):
195
+ v['db'] -= min(brd_db)
196
+ logger.info("Set [%s]BeamID %02d info: %s" %(mode_name, beamID, config))
197
+ ret = service.setBeamPattern(sn, mode, beamID, beam_type, config)
198
+ if ret.RetCode is not RetCode.OK:
199
+ logger.error(ret.RetMsg)
200
+ return False
201
+ except:
202
+ logger.exception("Something wrong while parsing")
203
+ return False
204
+ logger.info("Apply beam configs to %s successfully" %sn)
205
+ return True
206
+
207
+ # if __name__ == '__main__':
208
+ # import logging.config
209
+ # if not os.path.isdir('tlk_core_log/'):
210
+ # os.mkdir('tlk_core_log/')
211
+ # logging.config.fileConfig('logging.conf')
Binary file
tlkcore/TMYLogging.py ADDED
@@ -0,0 +1,112 @@
1
+ from datetime import datetime
2
+ import logging
3
+ import logging.config
4
+ import os
5
+
6
+ from tlkcore.TMYUtils import _Utils
7
+
8
+ class TMYLogging():
9
+ """
10
+ Customerize your logging setting here
11
+ """
12
+ _LOGGING_CONFIG = {
13
+ "version": 1,
14
+ "disable_existing_loggers": False,
15
+ "loggers": {
16
+ "": { # root logger
17
+ "handlers": ["console", "file"],
18
+ "level": logging.DEBUG,
19
+ "propagate": False,
20
+ },
21
+ "TLKCoreService": {
22
+ "handlers": ["console", "libFile"],
23
+ "qualname": "TLKCoreService",
24
+ "propagate": False,
25
+ },
26
+ "Comm":{
27
+ "handlers": ["libConsole", "libFile"],
28
+ "qualname": "Comm",
29
+ "propagate": False,
30
+ },
31
+ "Device":{
32
+ "handlers": ["libConsole", "libFile"],
33
+ "qualname": "Device",
34
+ "propagate": False,
35
+ },
36
+ "DFU":{
37
+ "handlers": ["console", "libFile"],
38
+ "qualname": "DFU",
39
+ "propagate": False,
40
+ },
41
+ "CaliTbl":{
42
+ "handlers": ["libFile"],
43
+ "qualname": "CaliTbl",
44
+ "propagate": False,
45
+ },
46
+ "AAKitTbl":{
47
+ "handlers": ["libFile"],
48
+ "qualname": "AAKitTbl",
49
+ "propagate": False,
50
+ },
51
+ "BeamTbl":{
52
+ "handlers": ["libFile"],
53
+ "qualname": "BeamTbl",
54
+ "propagate": False,
55
+ },
56
+ "UDDeltaTbl":{
57
+ "handlers": ["libFile"],
58
+ "qualname": "UDDeltaTbl",
59
+ "propagate": False,
60
+ },
61
+ "TblDB":{
62
+ "handlers": ["libFile"],
63
+ "qualname": "TblDB",
64
+ "propagate": False,
65
+ },
66
+ },
67
+ "handlers": {
68
+ "console": {
69
+ "class": "logging.StreamHandler",
70
+ "level": logging.INFO,
71
+ "formatter": "default",
72
+ },
73
+ "file":{
74
+ "class": "logging.FileHandler",
75
+ "level": logging.DEBUG,
76
+ "filename": datetime.now().strftime("tlk_core_log/main-%Y-%m-%d.log"),
77
+ "formatter": "default",
78
+ },
79
+ "libConsole": {
80
+ "class": "logging.StreamHandler",
81
+ "level": logging.ERROR,
82
+ "formatter": "default",
83
+ },
84
+ "libFile":{
85
+ "class": "logging.FileHandler",
86
+ "level": logging.DEBUG,
87
+ "filename": datetime.now().strftime("tlk_core_log/tlkcore-%Y-%m-%d.log"),
88
+ "formatter": "default",
89
+ }
90
+ },
91
+ "formatters": {
92
+ "default": {
93
+ "format": "%(asctime)s.%(msecs)3d - %(name)s - %(levelname)s : %(message)s",
94
+ "datefmt": "%Y-%m-%d %H:%M:%S"
95
+ },
96
+ "plain": {
97
+ "format": "%(message)s",
98
+ },
99
+ },
100
+ }
101
+
102
+ def __init__(self):
103
+ """TLKCoreService calls TMYLogging.py if change another root path"""
104
+ print('TMYLogging __init__')
105
+
106
+ def applyLogger(self):
107
+ # Update current dict
108
+ print("Apply logger path to : %s" %_Utils.root)
109
+ self._LOGGING_CONFIG["handlers"]["file"]["filename"] = os.path.join(_Utils.root, self._LOGGING_CONFIG["handlers"]["file"]["filename"])
110
+ self._LOGGING_CONFIG["handlers"]["libFile"]["filename"] = os.path.join(_Utils.root, self._LOGGING_CONFIG["handlers"]["libFile"]["filename"])
111
+
112
+ logging.config.dictConfig(self._LOGGING_CONFIG)
tlkcore/TMYPublic.py ADDED
@@ -0,0 +1,291 @@
1
+ from enum import Enum, Flag, auto, IntEnum
2
+ from typing import Union
3
+
4
+ class RIS_Dir(dict):
5
+ """
6
+ A dict structure for RIS direction includes distance and angle.
7
+
8
+ Args:
9
+ distance (float): Distance from RIS to the source/target
10
+ angle (tuple): Angle of the target, given in (theta, phi) format or theta only with phi=0, Defaults to (0,0)
11
+
12
+ Examples:
13
+ * For a distance of 1 meter and an angle of (0, 0):
14
+ >>> RIS_Dir(1)
15
+ * For a distance of 1 meter and an angle of (0, 0):
16
+ >>> RIS_Dir(1, (0, 0))
17
+ * For a distance of 1 meter and an angle of (30, 0):
18
+ >>> RIS_Dir(1, (30, 0))
19
+ """
20
+ def __init__(self, distance, angle:Union[int, tuple]=(0,0)):
21
+ self['distance'] = distance
22
+ if isinstance(angle, int):
23
+ self['angle'] = (angle, 0)
24
+ # elif isinstance(angle, tuple):
25
+ # # TODO: for multiple reflection angle only
26
+ # self['angle'] = [angle]
27
+ else:
28
+ self['angle'] = angle
29
+
30
+ class RIS_ModuleConfig(dict):
31
+ """
32
+ A data structure for RIS module configuration.
33
+
34
+ Args:
35
+ central_freq_mhz (int): Operating central frequency in MHz.
36
+ module (Union[int, list]): Specifies the target module partition to control.
37
+ It can be a single value (e.g. 1), or a list (e.g. [1, 2]),
38
+ or a nested list (e.g. [[1, 2]] or [[1, 2], [3, 4]]). Defaults to 1.
39
+ module_rotate (dict): Specifies the clockwise rotation degree for each module, therefore the actual pattern will be counter-clockwise rotation
40
+ The degree must be a multiple of 90.
41
+
42
+ Examples:
43
+ * 28GHz with only module 1, no rotation:
44
+ >>> RIS_ModuleConfig(28000, 1)
45
+ * 28GHz with module 1 and 2 in landscape orientation, no rotation:
46
+ >>> RIS_ModuleConfig(28000, [1, 2])
47
+ * 28GHz with module 1 and 2 in portrait orientation, rotate module 1 by 90 degrees:
48
+ >>> RIS_ModuleConfig(28000, [[1], [2]], {'1': 90})
49
+ * 28GHz with module 1 and 2 in landscape orientation, rotate module 1 by 90 degrees and module 2 by 180 degrees:
50
+ >>> RIS_ModuleConfig(28000, [1, 2], {'1': 90, '2': 180})
51
+ * 28GHz with module 1,2,3,4 in landscape orientation, no rotation:
52
+ >>> RIS_ModuleConfig(28000, [1, 2, 3, 4])
53
+ * 28GHz with module 1,2,3,4 in portrait orientation, no rotation:
54
+ >>> RIS_ModuleConfig(28000, [[1], [2], [3], [4]])
55
+ * 28GHz with module 1,2,3,4 in square orientation, rotate module 1 by 90 degrees and module 2 by 180 degrees:
56
+ >>> RIS_ModuleConfig(28000, [[1, 2],
57
+ [3, 4]], {'1': 90, '2': 180})
58
+ """
59
+ def __init__(self, central_freq_mhz:float, module:Union[int, list]=1, module_rotate=None):
60
+ self['central_freq_mhz'] = central_freq_mhz
61
+ self['module'] = module
62
+ self['module_rotate'] = module_rotate
63
+
64
+ class DevInterface(Flag):
65
+ """
66
+ Defines device connect interface for scanning.
67
+ """
68
+ UNKNOWN = 0
69
+ LAN = auto()
70
+ COMPORT = auto()
71
+ USB = auto()
72
+ ALL = LAN | COMPORT | USB
73
+
74
+ class ScanFilter(Flag):
75
+ NONE = 0
76
+ NORMAL = auto()
77
+ DFU = auto()
78
+ ALL = NORMAL | DFU
79
+
80
+ class IPMode(Enum):
81
+ """
82
+ Defines device IP mode as DHCP or static IP mode.
83
+ """
84
+ DHCP = 0
85
+ STATIC_IP = auto()
86
+
87
+ class RFMode(Enum):
88
+ """
89
+ Defines RF mode of beamform devices series.
90
+ """
91
+ TX = 0
92
+ RX = auto()
93
+
94
+ class CellRFMode(Enum):
95
+ STANDBY = -1
96
+ TX = 0
97
+ RX = auto()
98
+
99
+ class BeamType(Enum):
100
+ """
101
+ Defines beam type of beamform devices series for beam configuration.
102
+ """
103
+ BEAM = 0
104
+ CHANNEL = auto()
105
+
106
+ class RetCode(Enum):
107
+ """
108
+ Error code to represent the status of operations in TLKCore.
109
+ """
110
+ def __str__(self):
111
+ return self.name
112
+ def __int__(self):
113
+ return self.value
114
+ OK = 0
115
+ WARNING = auto()
116
+ ERROR = auto()
117
+ NO_RESPONSE = auto()
118
+ # genereal operations
119
+ ERROR_GET_SN = 10
120
+ ERROR_DEV_TYPE = auto()
121
+ ERROR_SCAN = auto()
122
+ ERROR_INIT_OBJECT = auto()
123
+ ERROR_DEV_NOT_INIT = auto()
124
+ ERROR_METHOD_NOT_FOUND = auto()
125
+ ERROR_METHOD_NOT_SUPPORT= auto()
126
+ ERROR_REFLECTION = auto()
127
+ ERROR_POWER = auto()
128
+ ERROR_EXPORT_LOG = auto()
129
+ ERROR_FW_NOT_SUPPORT = auto()
130
+
131
+ # Communication interface related
132
+ ERROR_COMM_NOT_INIT = 30
133
+ ERROR_COMM_INIT = auto()
134
+ ERROR_DISCONNECT = auto()
135
+ ERROR_SOCKET = auto()
136
+ ERROR_SEND_CMD = auto()
137
+ ERROR_RESP_CMD = auto()
138
+ ERROR_SEND_CMD_TIMEOUT = auto()
139
+ ERROR_COMPORT = auto()
140
+ ERROR_USB = auto()
141
+
142
+ # CMD to device
143
+ ERROR_CMD = 40
144
+ ERROR_CMD_INIT = auto()
145
+ ERROR_CMD_PARAM = auto()
146
+
147
+ # WEB - Database related
148
+ ERROR_DB_SERVER = 50
149
+ ERROR_DB_FEEDBACK = auto()
150
+
151
+ # DFU - Device Firmware Update related
152
+ ERROR_DFU = 60
153
+ ERROR_DFU_NOT_SUPPORT = auto()
154
+ ERROR_DFU_TYPE = auto()
155
+ ERROR_DFU_HEADER = auto()
156
+ ERROR_DFU_TRANSMIT = auto()
157
+
158
+ # Beamforming device
159
+ ERROR_BF_STATE = 100
160
+ ERROR_BF_AAKIT = auto()
161
+ ERROR_BF_NO_AAKIT = auto()
162
+ ERROR_BF_CALI_PATH = auto()
163
+ ERROR_BF_BEAM = auto()
164
+ ERROR_BF_GAIN = auto()
165
+ ERROR_BF_PHASE = auto()
166
+ ERROR_BF_RFMODE = auto()
167
+ ERROR_BF_CALI_INCOMPLTE = auto()
168
+ ERROR_BF_CALI_PARSE = auto()
169
+ ERROR_BF_TC = auto()
170
+ ERROR_BF_BEAM_FILE = auto()
171
+ # PD device
172
+ ERROR_PD_CALI = 150
173
+ ERROR_PD_SOURCE = auto()
174
+ # RIS device
175
+ ERROR_RIS_MODULE = 160
176
+ ERROR_RIS_CONFIG = auto()
177
+ # UDM/UDB device
178
+ ERROR_FREQ_RANGE = 240
179
+ ERROR_LICENSE_LENGTH = auto()
180
+ ERROR_LICENSE_KEY = auto()
181
+ ERROR_REF_CHANGE = auto()
182
+ # UD device
183
+ ERROR_UD_FREQ = 245
184
+ ERROR_FREQ_EQUATION = 250
185
+ WARNING_HARMONIC = auto()
186
+ ERROR_HARMONIC_BLOCK = auto()
187
+ ERROR_PLO_UNLOCK = 253
188
+ ERROR_PLO_CRC = auto()
189
+ ERROR_UD_STATE = auto()
190
+
191
+ class UDFreq(Enum):
192
+ """
193
+ UD frequency related categories, also used for key name of dict when calling :func:`~tlkcore.tmydev.DevUDBox.getUDFreq`
194
+ """
195
+ def __str__(self):
196
+ return self.name
197
+ UDFreq = 0
198
+ RFFreq = auto()
199
+ IFFreq = auto()
200
+
201
+ class UDState(Enum):
202
+ """
203
+ The state of UDBox5G
204
+ """
205
+ NO_SET = -1
206
+ PLO_LOCK = 0
207
+ CH1 = auto()
208
+ CH2 = auto() # ignore it if single UD
209
+ OUT_10M = auto()
210
+ OUT_100M = auto()
211
+ SOURCE_100M = auto() # 0:Internal, 1:External
212
+ LED_100M = auto() # 0:OFF, 1:WHITE, 2:BLUE
213
+ PWR_5V = auto()
214
+ PWR_9V = auto()
215
+
216
+ class UDMState(Flag):
217
+ """
218
+ The state of UDM
219
+ """
220
+ NO_SET = 0
221
+ SYSTEM = auto()
222
+ PLO_LOCK = auto()
223
+ REF_LOCK = auto()
224
+ LICENSE = auto()
225
+ ALL = SYSTEM | PLO_LOCK | REF_LOCK | LICENSE
226
+
227
+ class UDM_SYS(Enum):
228
+ """
229
+ It defines the :attr:`UDMState.SYSTEM` state of UDM
230
+ """
231
+ SYS_ERROR = -1
232
+ NORMAL = 0
233
+
234
+ class UD_PLO(Enum):
235
+ """
236
+ It defines the :attr:`UDMState.PLO_LOCK` state of UD series
237
+ """
238
+ UNLOCK = -1
239
+ LOCK = 0
240
+
241
+ class UD_REF(Enum):
242
+ """
243
+ It defines the :attr:`UDMState.REF_LOCK` state of UD series
244
+ """
245
+ UNLOCK = -1
246
+ INTERNAL = 0
247
+ EXTERNAL = auto()
248
+
249
+ class UDM_LICENSE(Enum):
250
+ """
251
+ It defines the :attr:`UDMState.LICENSE` state of UDM
252
+ """
253
+ VERIFY_FAIL_FLASH = -2
254
+ VERIFY_FAIL_DIGEST = -1
255
+ NON_LICENSE = 0
256
+ VERIFY_PASS = auto()
257
+
258
+ class UD_SN_TYPE(Flag):
259
+ """
260
+ The SN type of UD
261
+ """
262
+ UD_BOX = 1
263
+ UD_MODULE = auto()
264
+ ALL = UD_BOX | UD_MODULE
265
+
266
+ class UD_LO_CONFIG(Enum):
267
+ """
268
+ It defines the LO config for UDB series
269
+ """
270
+ LO_CFG_INTERNAL = 0
271
+ LO_CFG_INTERNAL_OUT = auto()
272
+ LO_CFG_EXTERNAL_IN = auto()
273
+ def __str__(self):
274
+ return self.name
275
+
276
+ class POLARIZATION(Flag):
277
+ HORIZON = 1
278
+ VERTICAL = auto()
279
+ DUAL = HORIZON | VERTICAL
280
+ def __str__(self):
281
+ return self.name.lower()
282
+
283
+ class POLAR_SYNTHESIS(IntEnum):
284
+ FORWARD = 0
285
+ BACKWARD = 180
286
+ RIGHT_HAND_CIRCULAR = 90
287
+ LEFT_HAND_CIRCULAR = 270
288
+ def __str__(self):
289
+ return self.name
290
+ def __int__(self):
291
+ return self.value
Binary file
tlkcore/__init__.py ADDED
@@ -0,0 +1 @@
1
+ __version__ = "255.255.255"
tlkcore/db/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ from .TMYDBQueryer import DBQueryer
2
+
3
+ __all__ = ["DBQueryer"]
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,13 @@
1
+ from pathlib import Path
2
+ import sys
3
+
4
+ __file = Path(__file__).absolute()
5
+ __root = __file.parent.parent.parent
6
+ if sys.path.count(__root) == 0:
7
+ sys.path.insert(0, __root)
8
+ # print(sys.path)
9
+
10
+ fromLib = True
11
+
12
+ if __file.suffix == '.py':
13
+ fromLib = False
Binary file
@@ -0,0 +1,9 @@
1
+ This software is proprietary to TMYTEK.
2
+
3
+ Unauthorized reproduction, reverse engineering, decompilation, modification, or redistribution of this software is strictly prohibited.
4
+
5
+ The software may only be used for development and operation in conjunction with TLKCore as authorized.
6
+
7
+ Any usage beyond the licensed scope constitutes a breach of agreement, and TMYTEK reserves all legal rights.
8
+
9
+ Copyright © 2025 TMYTEK. All rights reserved.
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.1
2
+ Name: tlkcore
3
+ Version: 255.255.255
4
+ Summary: TLKCore library
5
+ Home-page: https://github.com/TMYtek/tlkcore-examples/
6
+ Author: TMYTEK Software Team
7
+ Author-email: rd2_common@tmytek.com
8
+ License: UNKNOWN
9
+ Platform: UNKNOWN
10
+ Classifier: License :: Other/Proprietary License
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Topic :: Software Development :: Libraries
14
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
15
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
16
+ Classifier: Topic :: Software Development :: Testing
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Programming Language :: Python :: 3.8
20
+ Classifier: Programming Language :: Python :: 3.9
21
+ Classifier: Programming Language :: Python :: 3.10
22
+ Classifier: Programming Language :: Python :: 3.11
23
+ Classifier: Programming Language :: Python :: 3.12
24
+ Classifier: Programming Language :: Python :: Implementation :: CPython
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/x-rst
27
+ License-File: LICENSE.txt
28
+ Requires-Dist: psutil>=6.1.0
29
+ Requires-Dist: pyserial>=3.5
30
+ Requires-Dist: ft4222>=1.10.0
31
+ Requires-Dist: tftpy==0.8.5
32
+
33
+
34
+ Introduction
35
+ ============
36
+
37
+ **TLKCore** is a core service which inside the TMXLAB KIT(TLK/[WEB-TLK](https://web-tlk.tmytek.com/)), it integrates Python built libraries which developing mmWave( n257 / n258 / n260 / n261 ) **beamforming** and **beam steering** applications on **BBox 5G Series(mmwave beamformer)** and **UDBox 5G Series(mmwave Up-down frequency converter)** and other standard products developed by TMYTEK.
38
+ It provides a simple and efficient way to interact with the hardware, allowing developers to focus on building applications without worrying about low-level details.
39
+
40
+ Installation Troubleshooting
41
+ -----------------------------
42
+
43
+ * If you encounter any issues during `tlkcore` installation or usage, please check the following:
44
+
45
+ 1. Ensure you have the required dependencies installed.
46
+ 2. Check the compatibility of your Python version.
47
+ 3. Review the documentation for any specific configuration steps.
48
+
49
+ * If you meet the error message likes: CERTIFICATE_VERIFY_FAILED,
50
+ you can try the following steps:
51
+
52
+ 1. Update your `pip` to the latest version:
53
+ .. code-block:: bash
54
+
55
+ pip install --upgrade pip
56
+
57
+ 2. You may need to configure your proxy settings if you are behind a corporate firewall.
58
+ 3. You can also try to disable SSL verification (not recommended for production):
59
+ .. code-block:: bash
60
+
61
+ pip install tlkcore --trusted-host pypi.org --trusted-host files.pythonhosted.org
62
+
63
+ 4. Or download cacert.pem from https://curl.se/ca/cacert.pem , then set environment variable `SSL_CERT_FILE` to the path of the downloaded file.
64
+ .. code-block:: bash
65
+
66
+ set SSL_CERT_FILE={$your_path}/cacert.pem
67
+
68
+ Hardware Prequisites
69
+ =======================
70
+
71
+ * Architecture:
72
+
73
+ .. image:: https://github.com/tmytek/tlkcore-examples/blob/master/images/TLKCore_usage.png
74
+ :alt: TLKCore usage architecture
75
+ :width: 600px
76
+
77
+ * USB driver for scanning/connect device
78
+
79
+ - `Installation Guides for all platforms <https://ftdichip.com/document/installation-guides/>`_
80
+ - Windows
81
+
82
+ - Online-Host with external internet capability
83
+ - Auto detect a new device and install driver
84
+
85
+ - Offline-Host
86
+ - Download `setup executable driver from FTDI <https://ftdichip.com/drivers/d2xx-drivers/>`_ and install it.
87
+
88
+ - Linux
89
+
90
+ 1. Follow `steps <https://gitlab.com/msrelectronics/python-ft4222/-/tree/master#accessrights>`_ to create or extend **/etc/udev/rules.d/99-ftdi.rules** includes::
91
+
92
+ SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="601c", GROUP="plugdev", MODE="0666"
93
+
94
+ 2. Try to reload udev rules or re-plugin USB devices::
95
+
96
+ sudo udevadm control --reload-rules
97
+ sudo udevadm trigger
98
+
99
+ Examples
100
+ =========
101
+
102
+ This represents how to use the `tlkcore` API. Please refer to the example from github: https://github.com/tmytek/tlkcore-examples for more details.
103
+
104
+ Initialize & scanDevices
105
+ ------------------------
106
+
107
+ .. code-block:: python
108
+
109
+ from tlkcore.TLKCoreService import TLKCoreService
110
+ service = TLKCoreService(".")
111
+ ret = service.scanDevices()
112
+ print(ret)
113
+
114
+
@@ -0,0 +1,30 @@
1
+ tlkcore/TLKCoreService.cp39-win_amd64.pyd,sha256=rleD4qUrRZyRZzAuLSuR2_AXRYYCVeTnSFcIpVqckrQ,186880
2
+ tlkcore/TMYBeamConfig.py,sha256=r4AC7Pp3lSRVzZefIRlsEuPikH9OHHWQkJAmBykRstw,10970
3
+ tlkcore/TMYCommService.cp39-win_amd64.pyd,sha256=DriQW4cISaCmDRBsKmbYA6uh45YbYI0VADU8CCSZm6c,384512
4
+ tlkcore/TMYDFU.cp39-win_amd64.pyd,sha256=LKwF3UFFHlbG30Cn3kIwUICh2cYur22QxydZOtGXGlQ,255488
5
+ tlkcore/TMYLogging.py,sha256=IfJ3bihGbZqZx9HLX3EMEIJyqmk4Kg9Wu0vBQjcR3Ak,3828
6
+ tlkcore/TMYPublic.py,sha256=tiZkCU4ET_b1DT3F6YdLVtHSkZrcU2t5PcqHTCp30M4,9110
7
+ tlkcore/TMYUtils.cp39-win_amd64.pyd,sha256=aWKdofVsStN-eWPnkW0g7j4L8V78QHRmub_8JL8lp-s,131072
8
+ tlkcore/__init__.py,sha256=oU1ki7IC-ioCzroJrPr_PNM-FqyoTSi23COec0nfVfU,27
9
+ tlkcore/db/TMYDBQueryer.cp39-win_amd64.pyd,sha256=EVzi1B66inRndOJSPgM2-BehJYETZ2nJsS6-of7sPKo,58880
10
+ tlkcore/db/__init__.py,sha256=7c0_FWO1wyv9J2X0ZS-AZGI-4fOJFQVQAtJkDf963BE,62
11
+ tlkcore/tmydev/DevBBoard.cp39-win_amd64.pyd,sha256=gfqDKJBsXsletxsww2aPV7gm5Hn2CPheDxRpsNFJOEQ,87040
12
+ tlkcore/tmydev/DevBBox.cp39-win_amd64.pyd,sha256=lrOJuEkaUmCxPw1GCkK9WH-qrqXXOHHwFWDnT4TvM9g,554496
13
+ tlkcore/tmydev/DevBBoxLite.cp39-win_amd64.pyd,sha256=0oG_m8hE2CUOoiGqleoYb_VkpRrpqan5eSwQHnB_QfQ,71680
14
+ tlkcore/tmydev/DevBBoxOne.cp39-win_amd64.pyd,sha256=2XiKIspJXH8qnKfXOZxH9PmTKdxDboWCQx71ssSfxlo,70144
15
+ tlkcore/tmydev/DevCloverCell.cp39-win_amd64.pyd,sha256=dGEqg32VYYzzztaitO1GbgEVMisZ1CKwSCk4VTHY40M,414208
16
+ tlkcore/tmydev/DevPD.cp39-win_amd64.pyd,sha256=Ci0tb2NCZ0HXVHTWE_WPAcoB_EU50iZctnQ0N4fRYwo,105984
17
+ tlkcore/tmydev/DevRIS.cp39-win_amd64.pyd,sha256=q6Sa-BxHz2VVGGuRcr1NFlnv0SvMuERjY3z5yt3t9NI,232448
18
+ tlkcore/tmydev/DevUDB.cp39-win_amd64.pyd,sha256=nrAUkhEqR34QEy7d3FYHzvO22wYC_OIrsu-JNVx1Hwk,81408
19
+ tlkcore/tmydev/DevUDBox.cp39-win_amd64.pyd,sha256=xWP4m-AtqFGDfysIo3vTHI3EaRUvsSQnsjsqGehzO3E,134144
20
+ tlkcore/tmydev/DevUDC.cp39-win_amd64.pyd,sha256=vgZM85ODl9UqBB9odb3UjLT1TRLeeRL6jkTMZu5DDtM,236032
21
+ tlkcore/tmydev/DevUDM.cp39-win_amd64.pyd,sha256=gc0grqE-X3PXlOPVU5c2WI4Pt-C0vWCrJY8CFki59fI,136704
22
+ tlkcore/tmydev/RIS_pattern_generator.cp39-win_amd64.pyd,sha256=E5y0ejm2CgdeJ9pQGIF9mTd2-Pj3rY_NRdqkDjC3OB0,143872
23
+ tlkcore/tmydev/TMYTableManager.cp39-win_amd64.pyd,sha256=PRKGo-W6dZSkd5IghGWJdLoClHiGG1J6rxAgkI_eoFw,587776
24
+ tlkcore/tmydev/__init__.py,sha256=8ksasd6qXYtFXfv7JehWF_xCHllYtmAlDTLho53Xts0,269
25
+ tlkcore/tmydev/device.cp39-win_amd64.pyd,sha256=inPCvzCzftfDL7RO6S1Hj1cVqdhlVVeoXw6Kot8BBiE,200704
26
+ tlkcore-255.255.255.dist-info/LICENSE.txt,sha256=6_K8eSrAQ-FGMhnjUnh9X_ZtghXE8DOa6TJNaYACAIE,448
27
+ tlkcore-255.255.255.dist-info/METADATA,sha256=drWUOGIvRyC0ESuKPnGhjO25sV6SiMOCbANh94N705U,4433
28
+ tlkcore-255.255.255.dist-info/WHEEL,sha256=1tmyGX1LvzFxvAv-Wsgy80LjDlbkm7X5HKKw_v2usNY,99
29
+ tlkcore-255.255.255.dist-info/top_level.txt,sha256=a5TMUMf1qbFol7Px5jWhx6ZvMZke2kKrwYbrUCjcOQ4,8
30
+ tlkcore-255.255.255.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: bdist_wheel (0.45.1)
3
+ Root-Is-Purelib: true
4
+ Tag: cp39-none-win_amd64
5
+
@@ -0,0 +1 @@
1
+ tlkcore