v0.1.7.0(2024/06/25)-未发布
1. [aio.py] 取消了在本文件中开启openapi线程的做法,并修改如下:
	- 通过包的方式导入其他模块
    - 使用current_path来规避文件路径问题
    - 声名了 self.hr 变量,用来接收openapi的实例化
    - 修改了对于segment button的错误调用
    - 设定progress bar的长度是10
    - 完善了segmented_button_callback函数
    - 在detect_network函数中增加heartbeat初始化
    - tabview_click函数中新增textbox清屏功能,以及实例化openapi,并做检测
2. [openapi.py] 取消了初始化中无限循环检测,因为阻塞了aio主界面进程!!!socket也无法多次连接!!!浪费了好多时间!!!很生气!!!!
	- 通过tabview切换来实现重新连接,并保留了异常处理部分
    - 将所有的 __xxxx 函数都替换成 xxxx 函数,去掉了 __
    - 使用current_path来规避文件路径问题
3. [do_brake.py] 初步完成了机器状态收集的功能,还需要完善
    - 使用current_path来规避文件路径问题
    - 新增validate_resp函数,校验数据
    - 完善了调用接口
			
			
This commit is contained in:
		| @@ -246,24 +246,49 @@ v0.1.6.3(2024/06/18) | |||||||
|  |  | ||||||
| > !!WARNING:目前版本的电机电流程序还支持DriverMaster采集的数据处理,等明确后,将不再支持,也即所有的电机电流数据(工业+协作),都是用诊断曲线来采集 | > !!WARNING:目前版本的电机电流程序还支持DriverMaster采集的数据处理,等明确后,将不再支持,也即所有的电机电流数据(工业+协作),都是用诊断曲线来采集 | ||||||
|  |  | ||||||
| v0.1.7.0(2024/06/29) | v0.1.7.0(2024/06/19)-未发布 | ||||||
| 1. [openapi.py] 初步搭建起框架,完成了新老协议的封包/解包/异步采集日志的操作(未充分测试,但基本无问题) | 1. [openapi.py] 初步搭建起框架,完成了新老协议的封包/解包/异步采集日志的操作(未充分测试,但基本无问题) | ||||||
| 2. [openapi.py] 修改了封包的规则,使之更加明晰,封包操作没有实现分包功能,目前看实际场景用不到 | 2. [openapi.py] 修改了封包的规则,使之更加明晰,封包操作没有实现分包功能,目前看实际场景用不到 | ||||||
| 3. [openapi.py] 定义 MAX_FRAME_SIZE 常量(1024),替换socket接收以及响应数据处理相关部分 |  | ||||||
| 4. [openapi.py] 使用 int.to_bytes 和 int.from_bytes 替换 binascii 模块的功能 | v0.1.7.0(2024/06/21)-未发布 | ||||||
| 5. [aio.py] 修改了Data Process中初始化的动作,使得初始化时的状态统一成程序刚启动时的样子 | 1. [openapi.py] 定义 MAX_FRAME_SIZE 常量(1024),替换socket接收以及响应数据处理相关部分 | ||||||
| 6. [aio.py] 增加了tabview的点击行为函数,每次点击tab都会初始化 | 2. [openapi.py] 使用 int.to_bytes 和 int.from_bytes 替换 binascii 模块的功能 | ||||||
| 7. [aio.py] 增加了Automatic Test界面元素,包括如下,并完成了功能框架的搭建 | 3. [aio.py] 修改了Data Process中初始化的动作,使得初始化时的状态统一成程序刚启动时的样子 | ||||||
|  |  | ||||||
|  | v0.1.7.0(2024/06/23)-未发布 | ||||||
|  | 1. [aio.py] 增加了tabview的点击行为函数,每次点击tab都会初始化 | ||||||
|  | 2. [aio.py] 增加了Automatic Test界面元素,包括如下,并完成了功能框架的搭建 | ||||||
|    - 标签:文件/角速度/减速比 |    - 标签:文件/角速度/减速比 | ||||||
|    - 按钮:急停及恢复 |    - 按钮:急停及恢复 | ||||||
|    - 输入框:文件路径/角速度/减速比 |    - 输入框:文件路径/角速度/减速比 | ||||||
|    - OptionMenu:负载 |    - OptionMenu:负载 | ||||||
|    - 进度条 |    - 进度条 | ||||||
| 8. [openapi.py] 增加心跳检测函数,并开启线程执行;取消在该文件中生成实例 | 3. [openapi.py] 增加心跳检测函数,并开启线程执行;取消在该文件中生成实例 | ||||||
| 9. [aio.py] 完成detect_network,并在main函数开启线程 | 4. [aio.py] 完成detect_network,并在main函数开启线程 | ||||||
| 10. 将templates文件夹移动到assets内 | 5. 将templates文件夹移动到assets内 | ||||||
| 11. [openapi.py] 建联部分做容错逻辑,并将读写文件做自适应处理 |  | ||||||
| 12. [aio.py] 将读写文件做自适应处理,引入openapi模块并生成实例,做心跳检测,将socket超时时间修改为3s | v0.1.7.0(2024/06/24)-未发布 | ||||||
|  | 1. [openapi.py] 建联部分做容错逻辑,并将读写文件做自适应处理 | ||||||
|  | 2. [aio.py] 将读写文件做自适应处理,引入openapi模块并生成实例,做心跳检测,将socket超时时间修改为3s | ||||||
|  |  | ||||||
|  | v0.1.7.0(2024/06/25)-未发布 | ||||||
|  | 1. [aio.py] 取消了在本文件中开启openapi线程的做法,并修改如下: | ||||||
|  | 	- 通过包的方式导入其他模块 | ||||||
|  |     - 使用current_path来规避文件路径问题 | ||||||
|  |     - 声名了 self.hr 变量,用来接收openapi的实例化 | ||||||
|  |     - 修改了对于segment button的错误调用 | ||||||
|  |     - 设定progress bar的长度是10 | ||||||
|  |     - 完善了segmented_button_callback函数 | ||||||
|  |     - 在detect_network函数中增加heartbeat初始化 | ||||||
|  |     - tabview_click函数中新增textbox清屏功能,以及实例化openapi,并做检测 | ||||||
|  | 2. [openapi.py] 取消了初始化中无限循环检测,因为阻塞了aio主界面进程!!!socket也无法多次连接!!!浪费了好多时间!!!很生气!!!! | ||||||
|  | 	- 通过tabview切换来实现重新连接,并保留了异常处理部分 | ||||||
|  |     - 将所有的 __xxxx 函数都替换成 xxxx 函数,去掉了 __ | ||||||
|  |     - 使用current_path来规避文件路径问题 | ||||||
|  | 3. [do_brake.py] 初步完成了机器状态收集的功能,还需要完善 | ||||||
|  |     - 使用current_path来规避文件路径问题 | ||||||
|  |     - 新增validate_resp函数,校验数据 | ||||||
|  |     - 完善了调用接口 | ||||||
|  |  | ||||||
| > **关于HMI接口** | > **关于HMI接口** | ||||||
| > - 封包解包顺序:帧长度二字节/包长度四字节/协议二字节/预留二字节,\x04\x00:\x00\x00\tR:\x02:\x00 | > - 封包解包顺序:帧长度二字节/包长度四字节/协议二字节/预留二字节,\x04\x00:\x00\x00\tR:\x02:\x00 | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| 0 | 1 | ||||||
							
								
								
									
										1
									
								
								aio/code/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								aio/code/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | __all__ = ['automatic_test', 'data_process'] | ||||||
| @@ -1,3 +1,4 @@ | |||||||
|  | import sys | ||||||
| import tkinter | import tkinter | ||||||
| from os.path import exists, dirname | from os.path import exists, dirname | ||||||
| from os import getcwd | from os import getcwd | ||||||
| @@ -7,12 +8,10 @@ import customtkinter | |||||||
| from time import time, strftime, localtime, sleep | from time import time, strftime, localtime, sleep | ||||||
| from urllib.request import urlopen | from urllib.request import urlopen | ||||||
| from socket import setdefaulttimeout | from socket import setdefaulttimeout | ||||||
| import data_process.brake as brake | from data_process import * | ||||||
| import data_process.current as current | from automatic_test import * | ||||||
| import data_process.iso as iso |  | ||||||
| import data_process.wavelogger as wavelogger |  | ||||||
| import automatic_test.openapi as openapi |  | ||||||
|  |  | ||||||
|  | current_path = dirname(__file__) | ||||||
| customtkinter.set_appearance_mode("System")  # Modes: "System" (standard), "Dark", "Light" | customtkinter.set_appearance_mode("System")  # Modes: "System" (standard), "Dark", "Light" | ||||||
| customtkinter.set_default_color_theme("blue")  # Themes: "blue" (standard), "green", "dark-blue" | customtkinter.set_default_color_theme("blue")  # Themes: "blue" (standard), "green", "dark-blue" | ||||||
| customtkinter.set_widget_scaling(1.1)  # widget dimensions and text size | customtkinter.set_widget_scaling(1.1)  # widget dimensions and text size | ||||||
| @@ -73,6 +72,7 @@ class App(customtkinter.CTk): | |||||||
|         super().__init__() |         super().__init__() | ||||||
|         self.my_font = customtkinter.CTkFont(family="Consolas", size=16, weight="bold") |         self.my_font = customtkinter.CTkFont(family="Consolas", size=16, weight="bold") | ||||||
|         self.w_param = 84 |         self.w_param = 84 | ||||||
|  |         self.hr = None | ||||||
|         # ===================================================================== |         # ===================================================================== | ||||||
|         # configure window |         # configure window | ||||||
|         self.title("AIO - All in one automatic toolbox") |         self.title("AIO - All in one automatic toolbox") | ||||||
| @@ -142,7 +142,7 @@ class App(customtkinter.CTk): | |||||||
|         # For data process tab END ===================================================================== |         # For data process tab END ===================================================================== | ||||||
|         # For automatic test tab START ===================================================================== |         # For automatic test tab START ===================================================================== | ||||||
|         # create buttons |         # create buttons | ||||||
|         self.seg_button = customtkinter.CTkSegmentedButton(self.tabview.tab('Automatic Test'), font=self.my_font, command=lambda value='机器状态': self.thread_it(self.segmented_button_callback())) |         self.seg_button = customtkinter.CTkSegmentedButton(self.tabview.tab('Automatic Test'), font=self.my_font, command=lambda value='机器状态': self.thread_it(self.segmented_button_callback)) | ||||||
|         self.seg_button.grid(row=1, column=2, columnspan=12, padx=(20, 10), pady=(10, 10), sticky="ew") |         self.seg_button.grid(row=1, column=2, columnspan=12, padx=(20, 10), pady=(10, 10), sticky="ew") | ||||||
|         self.seg_button.configure(values=["无效功能", "触发急停", "停止运动", "继续运动", "零点位姿", "机器状态", "告警信息"]) |         self.seg_button.configure(values=["无效功能", "触发急停", "停止运动", "继续运动", "零点位姿", "机器状态", "告警信息"]) | ||||||
|         self.seg_button.set("无效功能") |         self.seg_button.set("无效功能") | ||||||
| @@ -150,7 +150,7 @@ class App(customtkinter.CTk): | |||||||
|         # create progress bar |         # create progress bar | ||||||
|         self.progressbar = customtkinter.CTkProgressBar(self.tabview.tab('Automatic Test')) |         self.progressbar = customtkinter.CTkProgressBar(self.tabview.tab('Automatic Test')) | ||||||
|         self.progressbar.grid(row=5, column=1, padx=5, pady=5, sticky="ew") |         self.progressbar.grid(row=5, column=1, padx=5, pady=5, sticky="ew") | ||||||
|         self.progressbar.configure(mode="determinnate") |         self.progressbar.configure(mode="determinnate", width=10) | ||||||
|         self.progressbar.start() |         self.progressbar.start() | ||||||
|         # create widgits_at |         # create widgits_at | ||||||
|         for widgit in widgits_at: |         for widgit in widgits_at: | ||||||
| @@ -189,44 +189,70 @@ class App(customtkinter.CTk): | |||||||
|             tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......") |             tkinter.messagebox.showwarning(title="版本更新", message="连接服务器失败,无法确认当前是否是最新版本......") | ||||||
|     # functions below ↓ ---------------------------------------------------------------------------------------- |     # functions below ↓ ---------------------------------------------------------------------------------------- | ||||||
|  |  | ||||||
|     def segmented_button_callback(self): |  | ||||||
|         value = self.seg_button.get() |  | ||||||
|         print(f"segment button is triggered: {value}") |  | ||||||
|         match value: |  | ||||||
|             case '触发急停': |  | ||||||
|                 pass |  | ||||||
|             case '停止运动': |  | ||||||
|                 pass |  | ||||||
|             case '继续运动': |  | ||||||
|                 pass |  | ||||||
|             case '零点位姿': |  | ||||||
|                 pass |  | ||||||
|             case '机器状态': |  | ||||||
|                 pass |  | ||||||
|             case '告警信息': |  | ||||||
|                 pass |  | ||||||
|  |  | ||||||
|     def detect_network(self): |  | ||||||
|         current_path = dirname(__file__) |  | ||||||
|         while True: |  | ||||||
|             with open(f'{current_path}/../assets/templates/heartbeat', 'r', encoding='utf-8') as f_h: |  | ||||||
|                 pb_color = 'green' if f_h.read().strip() == '1' else 'red' |  | ||||||
|                 self.progressbar.configure(progress_color=pb_color) |  | ||||||
|             sleep(3) |  | ||||||
|  |  | ||||||
|     def thread_it(self, func, *args): |     def thread_it(self, func, *args): | ||||||
|         """ 将函数打包进线程 """ |         """ 将函数打包进线程 """ | ||||||
|         self.myThread = Thread(target=func, args=args) |         self.myThread = Thread(target=func, args=args) | ||||||
|         self.myThread.daemon = True  # 主线程退出就直接让子线程跟随退出,不论是否运行完成。 |         self.myThread.daemon = True  # 主线程退出就直接让子线程跟随退出,不论是否运行完成。 | ||||||
|         self.myThread.start() |         self.myThread.start() | ||||||
|  |  | ||||||
|  |     def segmented_button_callback(self): | ||||||
|  |         value = self.seg_button.get() | ||||||
|  |         self.textbox.configure(state='normal') | ||||||
|  |  | ||||||
|  |         match value: | ||||||
|  |             case '触发急停': | ||||||
|  |                 self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |                 self.write2textbox(f"segment button is triggered: {value}") | ||||||
|  |             case '停止运动': | ||||||
|  |                 self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |                 self.write2textbox(f"segment button is triggered: {value}") | ||||||
|  |             case '继续运动': | ||||||
|  |                 self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |                 self.write2textbox(f"segment button is triggered: {value}") | ||||||
|  |             case '零点位姿': | ||||||
|  |                 self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |                 self.write2textbox(f"segment button is triggered: {value}") | ||||||
|  |             case '机器状态': | ||||||
|  |                 self.textbox.configure(state='normal') | ||||||
|  |                 self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |                 with open(f'{current_path}/../assets/templates/heartbeat', 'r', encoding='utf-8') as f_h: | ||||||
|  |                     connection_state = f_h.read().strip() | ||||||
|  |  | ||||||
|  |                 if connection_state == '0': | ||||||
|  |                     self.write2textbox("无法连接机器人,检查是否已经使用Robot Assist软件连接机器,重试中...") | ||||||
|  |                 else: | ||||||
|  |                     do_brake.main(self.hr, 'get_state', self.write2textbox) | ||||||
|  |  | ||||||
|  |             case '告警信息': | ||||||
|  |                 self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |                 self.write2textbox(f"segment button is triggered: {value}") | ||||||
|  |  | ||||||
|  |         self.textbox.configure(state='disable') | ||||||
|  |  | ||||||
|  |     def detect_network(self): | ||||||
|  |         with open(f"{current_path}/../assets/templates/heartbeat", "w", encoding='utf-8') as f_h: | ||||||
|  |             f_h.write('0') | ||||||
|  |         while True: | ||||||
|  |             with open(f'{current_path}/../assets/templates/heartbeat', 'r', encoding='utf-8') as f_h: | ||||||
|  |                 pb_color = 'green' if f_h.read().strip() == '1' else 'red' | ||||||
|  |                 self.progressbar.configure(progress_color=pb_color) | ||||||
|  |             sleep(3) | ||||||
|  |  | ||||||
|     def tabview_click(self): |     def tabview_click(self): | ||||||
|         self.initialization() |         self.initialization() | ||||||
|  |         self.textbox.configure(state='normal') | ||||||
|  |         self.textbox.delete(index1='1.0', index2='end') | ||||||
|  |         self.textbox.configure(state='disabled') | ||||||
|  |  | ||||||
|         tab_name = self.tabview.get() |         tab_name = self.tabview.get() | ||||||
|         if tab_name == 'Data Process': |         if tab_name == 'Data Process': | ||||||
|             self.menu_main_dp.set("Start Here!") |             self.menu_main_dp.set("Start Here!") | ||||||
|         elif tab_name == 'Automatic Test': |         elif tab_name == 'Automatic Test': | ||||||
|             self.menu_main_at.set("Start Here!") |             self.menu_main_at.set("Start Here!") | ||||||
|  |             with open(f"{current_path}/../assets/templates/heartbeat", "r", encoding='utf-8') as f_h: | ||||||
|  |                 connection_state = f_h.read().strip() | ||||||
|  |             if connection_state == '0' or self.hr is None: | ||||||
|  |                 self.hr = openapi.HmiRequest() | ||||||
|  |  | ||||||
|     def initialization(self): |     def initialization(self): | ||||||
|         tab_name = self.tabview.get() |         tab_name = self.tabview.get() | ||||||
| @@ -492,10 +518,6 @@ class App(customtkinter.CTk): | |||||||
|  |  | ||||||
|  |  | ||||||
| if __name__ == "__main__": | if __name__ == "__main__": | ||||||
|     t_hr = Thread(target=openapi.HmiRequest) |  | ||||||
|     t_hr.daemon = True |  | ||||||
|     t_hr.start() |  | ||||||
|  |  | ||||||
|     aio = App() |     aio = App() | ||||||
|     aio.net_detect = Thread(target=aio.detect_network) |     aio.net_detect = Thread(target=aio.detect_network) | ||||||
|     aio.net_detect.daemon = True |     aio.net_detect.daemon = True | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								aio/code/automatic_test/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								aio/code/automatic_test/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | __all__ = ['openapi', 'do_brake'] | ||||||
| @@ -1,6 +1,61 @@ | |||||||
| import openapi | import json | ||||||
|  | from os.path import dirname | ||||||
|  | from sys import argv | ||||||
|  |  | ||||||
|  | current_path = dirname(__file__) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def validate_resp(_id, response, w2t): | ||||||
|  |     match _id: | ||||||
|  |         case 'DATA ERR': | ||||||
|  |             w2t(f"数据处理错误,需要确认", 0, 4, 'red') | ||||||
|  |         case 'DATA READ ERR': | ||||||
|  |             w2t(f"无法读取数据,需要确认", 0, 3, 'red') | ||||||
|  |         case 'NOT SUPPORT': | ||||||
|  |             w2t(f"不支持的功能,需要确认", 0, 2, 'red') | ||||||
|  |     if not response: | ||||||
|  |         w2t(f"无法获取{id}请求的响应信息", 0, 1, 'red') | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def get_state(hr, w2t): | ||||||
|  |     # 获取机器状态 | ||||||
|  |     _id = hr.excution('state.get_state') | ||||||
|  |     _msg = hr.get_from_id(_id) | ||||||
|  |     if not _msg: | ||||||
|  |         w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red') | ||||||
|  |     else: | ||||||
|  |         _response = json.loads(_msg)['data'] | ||||||
|  |         validate_resp(_id, _response, w2t) | ||||||
|  |  | ||||||
|  |     stat_desc = {'engine': '上电状态', 'operate': '操作模式', 'rc_state': '控制器状态', 'robot_action': '机器人动作', 'safety_mode': '安全模式', 'servo_mode': '伺服工作模式', 'task_space': '工作任务空间'} | ||||||
|  |     for component, state in _response.items(): | ||||||
|  |         w2t(f"{stat_desc[component]}: {state}") | ||||||
|  |  | ||||||
|  |     _id = hr.excution('device.get_params') | ||||||
|  |     _msg = hr.get_from_id(_id) | ||||||
|  |     if not _msg: | ||||||
|  |         w2t(f"无法获取{_id}请求的响应信息", 0, 6, 'red') | ||||||
|  |     else: | ||||||
|  |         _response = json.loads(_msg)['data']['devices'] | ||||||
|  |         validate_resp(_id, _response, w2t) | ||||||
|  |     dev_desc = {0: '伺服版本', 1: '伺服参数', 2: '安全板固件', 3: '控制器', 4: '通讯总线', 5: '解释器', 6: '运动控制', 8: '力控版本', 9: '末端固件', 10: '机型文件', 11: '环境包'} | ||||||
|  |     dev_vers = {} | ||||||
|  |     for device in _response: | ||||||
|  |         dev_vers[device['type']] = device['version'] | ||||||
|  |     for i in sorted(dev_desc.keys()): | ||||||
|  |         w2t(f"{dev_desc[i]}: {dev_vers[i]}") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def main(hr, func, w2t): | ||||||
|  |     # func: get_state/ | ||||||
|  |     match func: | ||||||
|  |         case 'get_state': | ||||||
|  |             get_state(hr, w2t) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     main(*argv[1:]) | ||||||
|  |  | ||||||
| hr = openapi.HmiRequest() |  | ||||||
|  |  | ||||||
| # 一、设置/检测机器人状态: | # 一、设置/检测机器人状态: | ||||||
| #   1. 上电 | #   1. 上电 | ||||||
| @@ -19,13 +74,3 @@ hr = openapi.HmiRequest() | |||||||
|  |  | ||||||
| # 四 | # 四 | ||||||
|  |  | ||||||
|  |  | ||||||
| # _id = hr.excution("state.get_state") |  | ||||||
| # print(hr.get_from_id(_id)) |  | ||||||
| # _id = hr.excution('state.set_tp_mode', tp_mode='without') |  | ||||||
| # print(hr.get_from_id(_id)) |  | ||||||
|  |  | ||||||
| _id = hr.excution('device.get_params') |  | ||||||
| print(hr.get_from_id(_id)) |  | ||||||
| # _id = hr.excution('state.switch_manual') |  | ||||||
| # print(hr.get_from_id(_id)) |  | ||||||
|   | |||||||
| @@ -3,52 +3,51 @@ import socket | |||||||
| import threading | import threading | ||||||
| import selectors | import selectors | ||||||
| import time | import time | ||||||
| import os | from os.path import dirname | ||||||
|  |  | ||||||
| MAX_FRAME_SIZE = 1024 | MAX_FRAME_SIZE = 1024 | ||||||
| socket.setdefaulttimeout(3) | socket.setdefaulttimeout(3) | ||||||
|  | current_path = dirname(__file__) | ||||||
|  |  | ||||||
|  |  | ||||||
| class HmiRequest(object): | class HmiRequest(object): | ||||||
|     def __init__(self): |     def __init__(self): | ||||||
|         super().__init__() |         super().__init__() | ||||||
|         while True: |         try: | ||||||
|             try: |             self.c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||||
|                 self.c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |             self.c.connect(('192.168.0.160', 5050)) | ||||||
|                 # self.c.connect(('192.168.0.160', 5050)) |             # self.c.connect(('192.168.84.129', 5050)) | ||||||
|                 self.c.connect(('192.168.84.129', 5050)) |             self.c.setblocking(False) | ||||||
|                 self.c.setblocking(False) |             self.c_xs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||||||
|                 self.c_msg = [] |             self.c_xs.connect(('192.168.0.160', 6666)) | ||||||
|                 self.c_xs = socket.socket(socket.AF_INET, socket.SOCK_STREAM) |             # self.c_xs.connect(('192.168.84.129', 6666)) | ||||||
|                 # self.c_xs.connect(('192.168.0.160', 6666)) |             self.c_xs.setblocking(False) | ||||||
|                 self.c_xs.connect(('192.168.84.129', 6666)) |             with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_h: | ||||||
|                 self.c_xs.setblocking(False) |                 f_h.write('1') | ||||||
|                 self.c_msg_xs = [] |         except Exception as Err: | ||||||
|                 break |             with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_h: | ||||||
|             except Exception as Err: |                 f_h.write('0') | ||||||
|                 current_path = os.path.dirname(__file__) |             print("Connection failed, please try to re-connect via switching tabs...") | ||||||
|                 with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_h: |  | ||||||
|                     f_h.write('0') |  | ||||||
|  |  | ||||||
|                 print("Connection failed, will try again after 2 seconds...") |         self.c_msg = [] | ||||||
|                 time.sleep(2) |         self.c_msg_xs = [] | ||||||
|  |  | ||||||
|         self.t_heartbeat = threading.Thread(target=self.__heartbeat) |  | ||||||
|         self.t_heartbeat.daemon = True |  | ||||||
|         self.t_heartbeat.start() |  | ||||||
|         self.t_unpackage = threading.Thread(target=self.__unpackage, args=(self.c, )) |  | ||||||
|         self.t_unpackage.daemon = True |  | ||||||
|         self.t_unpackage.start() |  | ||||||
|         self.t_unpackage_xs = threading.Thread(target=self.__unpackage_xs, args=(self.c_xs, )) |  | ||||||
|         self.t_unpackage_xs.daemon = True |  | ||||||
|         self.t_unpackage_xs.start() |  | ||||||
|         self.flag = 0 |         self.flag = 0 | ||||||
|         self.response = '' |         self.response = '' | ||||||
|         self.leftover = 0 |         self.leftover = 0 | ||||||
|         self.flag_xs = 0 |         self.flag_xs = 0 | ||||||
|         self.response_xs = '' |         self.response_xs = '' | ||||||
|  |  | ||||||
|     def __header_check(self, index, data): |         self.t_heartbeat = threading.Thread(target=self.heartbeat) | ||||||
|  |         self.t_heartbeat.daemon = True | ||||||
|  |         self.t_heartbeat.start() | ||||||
|  |         self.t_unpackage = threading.Thread(target=self.unpackage, args=(self.c, )) | ||||||
|  |         self.t_unpackage.daemon = True | ||||||
|  |         self.t_unpackage.start() | ||||||
|  |         self.t_unpackage_xs = threading.Thread(target=self.unpackage_xs, args=(self.c_xs, )) | ||||||
|  |         self.t_unpackage_xs.daemon = True | ||||||
|  |         self.t_unpackage_xs.start() | ||||||
|  |  | ||||||
|  |     def header_check(self, index, data): | ||||||
|         try: |         try: | ||||||
|             _frame_size = int.from_bytes(data[index:index+2], byteorder='big') |             _frame_size = int.from_bytes(data[index:index+2], byteorder='big') | ||||||
|             _pkg_size = int.from_bytes(data[index+2:index+6], byteorder='big') |             _pkg_size = int.from_bytes(data[index+2:index+6], byteorder='big') | ||||||
| @@ -59,22 +58,21 @@ class HmiRequest(object): | |||||||
|                 return index+8, _frame_size, _pkg_size |                 return index+8, _frame_size, _pkg_size | ||||||
|             else: |             else: | ||||||
|                 print("数据有误,需要确认") |                 print("数据有误,需要确认") | ||||||
|                 exit(9) |                 return 'DATA ERR' | ||||||
|         except Exception as Err: |         except Exception as Err: | ||||||
|             print(f"Err = {Err}") |             print(f"Err = {Err}") | ||||||
|             print("无法读取数据,需要确认") |             print("无法读取数据,需要确认") | ||||||
|             exit(10) |             return 'DATA READ ERR' | ||||||
|  |  | ||||||
|     def __heartbeat(self): |     def heartbeat(self): | ||||||
|         current_path = os.path.dirname(__file__) |  | ||||||
|         while True: |         while True: | ||||||
|             _id = self.excution('controller.heart') |             _id = self.excution('controller.heart') | ||||||
|             _flag = 1 if self.get_from_id(_id) else 0 |             _flag = 1 if self.get_from_id(_id) else 0 | ||||||
|             with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_h: |             with open(f"{current_path}/../../assets/templates/heartbeat", "w", encoding='utf-8') as f_h: | ||||||
|                 f_h.write(str(_flag)) |                 f_h.write(str(_flag)) | ||||||
|             time.sleep(10) |             time.sleep(3) | ||||||
|  |  | ||||||
|     def __msg_storage(self, response, flag=0): |     def msg_storage(self, response, flag=0): | ||||||
|         messages = self.c_msg if flag == 0 else self.c_msg_xs |         messages = self.c_msg if flag == 0 else self.c_msg_xs | ||||||
|         if len(messages) < 1000: |         if len(messages) < 1000: | ||||||
|             messages.insert(0, response) |             messages.insert(0, response) | ||||||
| @@ -83,15 +81,15 @@ class HmiRequest(object): | |||||||
|             while len(messages) > 1000: |             while len(messages) > 1000: | ||||||
|                 messages.pop() |                 messages.pop() | ||||||
|  |  | ||||||
|     def __get_response(self, data): |     def get_response(self, data): | ||||||
|         _index = 0 |         _index = 0 | ||||||
|         while _index < len(data): |         while _index < len(data): | ||||||
|             if self.flag == 0: |             if self.flag == 0: | ||||||
|                 _index, _frame_size, _pkg_size = self.__header_check(_index, data) |                 _index, _frame_size, _pkg_size = self.header_check(_index, data) | ||||||
|                 if _pkg_size <= len(data) - _index: |                 if _pkg_size <= len(data) - _index: | ||||||
|                     # 说明剩余部分的数据正好就是完整的包数据 |                     # 说明剩余部分的数据正好就是完整的包数据 | ||||||
|                     self.response = data[_index:_index+_pkg_size].decode() |                     self.response = data[_index:_index+_pkg_size].decode() | ||||||
|                     self.__msg_storage(flag=0, response=self.response) |                     self.msg_storage(flag=0, response=self.response) | ||||||
|                     _index += _pkg_size |                     _index += _pkg_size | ||||||
|                     self.flag = 0 |                     self.flag = 0 | ||||||
|                     self.response = '' |                     self.response = '' | ||||||
| @@ -111,7 +109,7 @@ class HmiRequest(object): | |||||||
|  |  | ||||||
|                 _frame_size = int.from_bytes(data[_index - 2:_index], byteorder='big') |                 _frame_size = int.from_bytes(data[_index - 2:_index], byteorder='big') | ||||||
|                 if _frame_size == 0: |                 if _frame_size == 0: | ||||||
|                     self.__msg_storage(flag=0, response=self.response) |                     self.msg_storage(flag=0, response=self.response) | ||||||
|                     self.flag = 0 |                     self.flag = 0 | ||||||
|                     self.response = '' |                     self.response = '' | ||||||
|                     self.leftover = 0 |                     self.leftover = 0 | ||||||
| @@ -124,7 +122,7 @@ class HmiRequest(object): | |||||||
|                 else: |                 else: | ||||||
|                     if _index+_frame_size <= MAX_FRAME_SIZE: |                     if _index+_frame_size <= MAX_FRAME_SIZE: | ||||||
|                         self.response += data[_index:_index+_frame_size].decode() |                         self.response += data[_index:_index+_frame_size].decode() | ||||||
|                         self.__msg_storage(flag=0, response=self.response) |                         self.msg_storage(flag=0, response=self.response) | ||||||
|                         self.flag = 0 |                         self.flag = 0 | ||||||
|                         self.response = '' |                         self.response = '' | ||||||
|                         self.leftover = 0 |                         self.leftover = 0 | ||||||
| @@ -134,19 +132,19 @@ class HmiRequest(object): | |||||||
|                         self.leftover = _index + _frame_size - MAX_FRAME_SIZE |                         self.leftover = _index + _frame_size - MAX_FRAME_SIZE | ||||||
|                         break |                         break | ||||||
|  |  | ||||||
|     def __get_response_xs(self, data): |     def get_response_xs(self, data): | ||||||
|         if self.flag_xs == 0: |         if self.flag_xs == 0: | ||||||
|             if data[-1].decode() == '\r': |             if data[-1].decode() == '\r': | ||||||
|                 _responses = data.decode().split('\r') |                 _responses = data.decode().split('\r') | ||||||
|                 for _response in _responses: |                 for _response in _responses: | ||||||
|                     self.__msg_storage(flag=1, response=_response) |                     self.msg_storage(flag=1, response=_response) | ||||||
|  |  | ||||||
|             else: |             else: | ||||||
|                 _responses = data.decode().split('\r') |                 _responses = data.decode().split('\r') | ||||||
|                 for _response in _responses[:-1]: |                 for _response in _responses[:-1]: | ||||||
|                     if not _response: |                     if not _response: | ||||||
|                         break |                         break | ||||||
|                     self.__msg_storage(flag=1, response=_response) |                     self.msg_storage(flag=1, response=_response) | ||||||
|  |  | ||||||
|                 self.response_xs = _responses[-1] |                 self.response_xs = _responses[-1] | ||||||
|                 self.flag_xs = 1 |                 self.flag_xs = 1 | ||||||
| @@ -154,7 +152,7 @@ class HmiRequest(object): | |||||||
|             if data[-1].decode() == '\r': |             if data[-1].decode() == '\r': | ||||||
|                 _responses = (self.response_xs.encode() + data).decode().split('\r') |                 _responses = (self.response_xs.encode() + data).decode().split('\r') | ||||||
|                 for _response in _responses: |                 for _response in _responses: | ||||||
|                     self.__msg_storage(flag=1, response=_response) |                     self.msg_storage(flag=1, response=_response) | ||||||
|  |  | ||||||
|                 self.response_xs = '' |                 self.response_xs = '' | ||||||
|                 self.flag_xs = 0 |                 self.flag_xs = 0 | ||||||
| @@ -163,7 +161,7 @@ class HmiRequest(object): | |||||||
|                 for _response in _responses[:-1]: |                 for _response in _responses[:-1]: | ||||||
|                     if not _response: |                     if not _response: | ||||||
|                         break |                         break | ||||||
|                     self.__msg_storage(flag=1, response=_response) |                     self.msg_storage(flag=1, response=_response) | ||||||
|  |  | ||||||
|                 self.response_xs = _responses[-1] |                 self.response_xs = _responses[-1] | ||||||
|                 self.flag_xs = 1 |                 self.flag_xs = 1 | ||||||
| @@ -176,25 +174,24 @@ class HmiRequest(object): | |||||||
|                     return msg |                     return msg | ||||||
|             time.sleep(1) |             time.sleep(1) | ||||||
|         else: |         else: | ||||||
|             # print(f'无法查询到{msg_id}对应的响应') |  | ||||||
|             return None |             return None | ||||||
|  |  | ||||||
|     def __package(self, cmd): |     def package(self, cmd): | ||||||
|         _frame_head = (len(cmd)+6).to_bytes(length=2, byteorder='big') |         _frame_head = (len(cmd)+6).to_bytes(length=2, byteorder='big') | ||||||
|         _pkg_head = len(cmd).to_bytes(length=4, byteorder='big') |         _pkg_head = len(cmd).to_bytes(length=4, byteorder='big') | ||||||
|         _protocol = int(2).to_bytes(length=1, byteorder='big') |         _protocol = int(2).to_bytes(length=1, byteorder='big') | ||||||
|         _reserved = int(0).to_bytes(length=1, byteorder='big') |         _reserved = int(0).to_bytes(length=1, byteorder='big') | ||||||
|         return _frame_head + _pkg_head + _protocol + _reserved + cmd.encode() |         return _frame_head + _pkg_head + _protocol + _reserved + cmd.encode() | ||||||
|  |  | ||||||
|     def __package_xs(self, cmd): |     def package_xs(self, cmd): | ||||||
|         return f"{json.dumps(cmd, separators=(',', ':'))}\r".encode() |         return f"{json.dumps(cmd, separators=(',', ':'))}\r".encode() | ||||||
|  |  | ||||||
|     def __unpackage(self, sock): |     def unpackage(self, sock): | ||||||
|         def to_read(conn): |         def to_read(conn): | ||||||
|             data = conn.recv(MAX_FRAME_SIZE) |             data = conn.recv(MAX_FRAME_SIZE) | ||||||
|             if data: |             if data: | ||||||
|                 # print(data) |                 # print(data) | ||||||
|                 self.__get_response(data) |                 self.get_response(data) | ||||||
|             else: |             else: | ||||||
|                 print('closing', sock) |                 print('closing', sock) | ||||||
|                 sel.unregister(conn) |                 sel.unregister(conn) | ||||||
| @@ -209,12 +206,12 @@ class HmiRequest(object): | |||||||
|                 callback = key.data |                 callback = key.data | ||||||
|                 callback(key.fileobj) |                 callback(key.fileobj) | ||||||
|  |  | ||||||
|     def __unpackage_xs(self, sock): |     def unpackage_xs(self, sock): | ||||||
|         def to_read(conn): |         def to_read(conn): | ||||||
|             data = conn.recv(1024)  # Should be ready |             data = conn.recv(1024)  # Should be ready | ||||||
|             if data: |             if data: | ||||||
|                 # print(data) |                 # print(data) | ||||||
|                 self.__get_response_xs(data) |                 self.get_response_xs(data) | ||||||
|             else: |             else: | ||||||
|                 print('closing', sock) |                 print('closing', sock) | ||||||
|                 sel.unregister(conn) |                 sel.unregister(conn) | ||||||
| @@ -229,32 +226,30 @@ class HmiRequest(object): | |||||||
|                 callback = key.data |                 callback = key.data | ||||||
|                 callback(key.fileobj) |                 callback(key.fileobj) | ||||||
|  |  | ||||||
|     def __gen_id(self, command): |     def gen_id(self, command): | ||||||
|         _now = time.time() |         _now = time.time() | ||||||
|         _id = f"{command}-{_now}" |         _id = f"{command}-{_now}" | ||||||
|         return _id |         return _id | ||||||
|  |  | ||||||
|     def excution(self, command, flag=0, **kwargs): |     def excution(self, command, flg=0, **kwargs): | ||||||
|         current_path = os.path.dirname(__file__) |         if flg == 0:  # for old protocols | ||||||
|  |  | ||||||
|         if flag == 0:  # for old protocols |  | ||||||
|             req = None |             req = None | ||||||
|             try: |             try: | ||||||
|                 with open(f'{current_path}/../../assets/templates/{command}.json', encoding='utf-8', mode='r') as f_json: |                 with open(f'{current_path}/../../assets/templates/{command}.json', encoding='utf-8', mode='r') as f_json: | ||||||
|                     req = json.load(f_json) |                     req = json.load(f_json) | ||||||
|             except: |             except: | ||||||
|                 print(f"暂不支持 {command} 功能,或确认该功能存在...") |                 print(f"暂不支持 {command} 功能,或确认该功能存在...") | ||||||
|                 exit(1) |                 return 'NOT SUPPORT' | ||||||
|  |  | ||||||
|             match command: |             match command: | ||||||
|                 case 'state.set_tp_mode': |                 case 'state.set_tp_mode': | ||||||
|                     req['data']['tp_mode'] = kwargs['tp_mode'] |                     req['data']['tp_mode'] = kwargs['tp_mode'] | ||||||
|                 case 1: |                 case 1: | ||||||
|                     pass |                     pass | ||||||
|             req['id'] = self.__gen_id(command) |             req['id'] = self.gen_id(command) | ||||||
|             print(f"req = {req}") |             print(f"req = {req}") | ||||||
|             cmd = json.dumps(req, separators=(',', ':')) |             cmd = json.dumps(req, separators=(',', ':')) | ||||||
|             self.c.send(self.__package(cmd)) |             self.c.send(self.package(cmd)) | ||||||
|             time.sleep(2) |             time.sleep(2) | ||||||
|             return req['id'] |             return req['id'] | ||||||
|         else:  # for xService |         else:  # for xService | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								aio/code/data_process/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								aio/code/data_process/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | __all__ = ['brake', 'current', 'iso', 'wavelogger'] | ||||||
		Reference in New Issue
	
	Block a user