mirror of
https://github.com/dptech-corp/Uni-Lab-OS.git
synced 2026-02-06 23:15:10 +00:00
Fix Build 1
This commit is contained in:
17
.github/workflows/multi-platform-build.yml
vendored
17
.github/workflows/multi-platform-build.yml
vendored
@@ -1,11 +1,16 @@
|
|||||||
name: Multi-Platform Conda Build
|
name: Multi-Platform Conda Build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
|
# 在 CI Check 工作流完成后触发(仅限 main/dev 分支)
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["CI Check"]
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
branches: [main, dev]
|
||||||
|
# 支持 tag 推送(不依赖 CI Check)
|
||||||
push:
|
push:
|
||||||
branches: [main, dev]
|
|
||||||
tags: ['v*']
|
tags: ['v*']
|
||||||
pull_request:
|
# 手动触发
|
||||||
branches: [main, dev]
|
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
platforms:
|
platforms:
|
||||||
@@ -20,6 +25,10 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
# 只有当不是 workflow_run 触发,或者 CI Check 成功时才执行
|
||||||
|
if: >-
|
||||||
|
github.event_name != 'workflow_run' ||
|
||||||
|
github.event.workflow_run.conclusion == 'success'
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -46,6 +55,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
|
# 如果是 workflow_run 触发,使用触发 CI Check 的 commit
|
||||||
|
ref: ${{ github.event.workflow_run.head_sha || github.ref }}
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
- name: Check if platform should be built
|
- name: Check if platform should be built
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import asyncio
|
import asyncio
|
||||||
import os
|
import os
|
||||||
|
import shutil
|
||||||
import signal
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
@@ -215,7 +216,8 @@ def main():
|
|||||||
args_dict = vars(args)
|
args_dict = vars(args)
|
||||||
|
|
||||||
# 环境检查 - 检查并自动安装必需的包 (可选)
|
# 环境检查 - 检查并自动安装必需的包 (可选)
|
||||||
if not args_dict.get("skip_env_check", False):
|
skip_env_check = args_dict.get("skip_env_check", False)
|
||||||
|
if not skip_env_check:
|
||||||
from unilabos.utils.environment_check import check_environment
|
from unilabos.utils.environment_check import check_environment
|
||||||
|
|
||||||
if not check_environment(auto_install=True):
|
if not check_environment(auto_install=True):
|
||||||
@@ -226,7 +228,19 @@ def main():
|
|||||||
|
|
||||||
# 加载配置文件,优先加载config,然后从env读取
|
# 加载配置文件,优先加载config,然后从env读取
|
||||||
config_path = args_dict.get("config")
|
config_path = args_dict.get("config")
|
||||||
if os.getcwd().endswith("unilabos_data"):
|
|
||||||
|
# 当 skip_env_check 时,默认使用当前目录作为 working_dir
|
||||||
|
if skip_env_check and not args_dict.get("working_dir") and not config_path:
|
||||||
|
working_dir = os.path.abspath(os.getcwd())
|
||||||
|
print_status(f"跳过环境检查模式:使用当前目录作为工作目录 {working_dir}", "info")
|
||||||
|
# 检查当前目录是否有 local_config.py
|
||||||
|
local_config_in_cwd = os.path.join(working_dir, "local_config.py")
|
||||||
|
if os.path.exists(local_config_in_cwd):
|
||||||
|
config_path = local_config_in_cwd
|
||||||
|
print_status(f"发现本地配置文件: {config_path}", "info")
|
||||||
|
else:
|
||||||
|
print_status(f"未指定config路径,可通过 --config 传入 local_config.py 文件路径", "info")
|
||||||
|
elif os.getcwd().endswith("unilabos_data"):
|
||||||
working_dir = os.path.abspath(os.getcwd())
|
working_dir = os.path.abspath(os.getcwd())
|
||||||
else:
|
else:
|
||||||
working_dir = os.path.abspath(os.path.join(os.getcwd(), "unilabos_data"))
|
working_dir = os.path.abspath(os.path.join(os.getcwd(), "unilabos_data"))
|
||||||
@@ -245,7 +259,7 @@ def main():
|
|||||||
working_dir = os.path.dirname(config_path)
|
working_dir = os.path.dirname(config_path)
|
||||||
elif os.path.exists(working_dir) and os.path.exists(os.path.join(working_dir, "local_config.py")):
|
elif os.path.exists(working_dir) and os.path.exists(os.path.join(working_dir, "local_config.py")):
|
||||||
config_path = os.path.join(working_dir, "local_config.py")
|
config_path = os.path.join(working_dir, "local_config.py")
|
||||||
elif not config_path and (
|
elif not skip_env_check and not config_path and (
|
||||||
not os.path.exists(working_dir) or not os.path.exists(os.path.join(working_dir, "local_config.py"))
|
not os.path.exists(working_dir) or not os.path.exists(os.path.join(working_dir, "local_config.py"))
|
||||||
):
|
):
|
||||||
print_status(f"未指定config路径,可通过 --config 传入 local_config.py 文件路径", "info")
|
print_status(f"未指定config路径,可通过 --config 传入 local_config.py 文件路径", "info")
|
||||||
|
|||||||
@@ -1,187 +0,0 @@
|
|||||||
# UniLabOS 日志配置说明
|
|
||||||
|
|
||||||
> **文件位置**: `unilabos/utils/log.py`
|
|
||||||
> **最后更新**: 2026-01-11
|
|
||||||
> **维护者**: Uni-Lab-OS 开发团队
|
|
||||||
|
|
||||||
本文档说明 UniLabOS 日志系统中对第三方库和内部模块的日志级别配置,避免控制台被过多的 DEBUG 日志淹没。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📋 已屏蔽的日志
|
|
||||||
|
|
||||||
以下库/模块的日志已被设置为 **WARNING** 或 **INFO** 级别,不再显示 DEBUG 日志:
|
|
||||||
|
|
||||||
### 1. pymodbus(Modbus 通信库)
|
|
||||||
|
|
||||||
**配置位置**: `log.py` 第196-200行
|
|
||||||
|
|
||||||
```python
|
|
||||||
# pymodbus 库的日志太详细,设置为 WARNING
|
|
||||||
logging.getLogger('pymodbus').setLevel(logging.WARNING)
|
|
||||||
logging.getLogger('pymodbus.logging').setLevel(logging.WARNING)
|
|
||||||
logging.getLogger('pymodbus.logging.base').setLevel(logging.WARNING)
|
|
||||||
logging.getLogger('pymodbus.logging.decoders').setLevel(logging.WARNING)
|
|
||||||
```
|
|
||||||
|
|
||||||
**屏蔽原因**:
|
|
||||||
- pymodbus 在 DEBUG 级别会输出每一次 Modbus 通信的详细信息
|
|
||||||
- 包括 `Processing: 0x5 0x1e 0x0 0x0...` 等原始数据
|
|
||||||
- 包括 `decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersResponse(...)` 等解码信息
|
|
||||||
- 这些信息对日常使用价值不大,但会快速刷屏
|
|
||||||
|
|
||||||
**典型被屏蔽的日志**:
|
|
||||||
```
|
|
||||||
[DEBUG] Processing: 0x5 0x1e 0x0 0x0 0x0 0x7 0x1 0x3 0x4 0x0 0x0 0x0 0x0 [handleFrame:72] [pymodbus.logging.base]
|
|
||||||
[DEBUG] decoded PDU function_code(3 sub -1) -> ReadHoldingRegistersResponse(...) [decode:79] [pymodbus.logging.decoders]
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 2. websockets(WebSocket 库)
|
|
||||||
|
|
||||||
**配置位置**: `log.py` 第202-205行
|
|
||||||
|
|
||||||
```python
|
|
||||||
# websockets 库的日志输出较多,设置为 WARNING
|
|
||||||
logging.getLogger('websockets').setLevel(logging.WARNING)
|
|
||||||
logging.getLogger('websockets.client').setLevel(logging.WARNING)
|
|
||||||
logging.getLogger('websockets.server').setLevel(logging.WARNING)
|
|
||||||
```
|
|
||||||
|
|
||||||
**屏蔽原因**:
|
|
||||||
- WebSocket 连接、断开、心跳等信息在 DEBUG 级别会频繁输出
|
|
||||||
- 对于长时间运行的服务,这些日志意义不大
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 3. ROS Host Node(设备状态更新)
|
|
||||||
|
|
||||||
**配置位置**: `log.py` 第207-208行
|
|
||||||
|
|
||||||
```python
|
|
||||||
# ROS 节点的状态更新日志过于频繁,设置为 INFO
|
|
||||||
logging.getLogger('unilabos.ros.nodes.presets.host_node').setLevel(logging.INFO)
|
|
||||||
```
|
|
||||||
|
|
||||||
**屏蔽原因**:
|
|
||||||
- 设备状态更新(如手套箱压力)每隔几秒就会更新一次
|
|
||||||
- DEBUG 日志会记录每一次状态变化,导致日志刷屏
|
|
||||||
- 这些频繁的状态更新对调试价值不大
|
|
||||||
|
|
||||||
**典型被屏蔽的日志**:
|
|
||||||
```
|
|
||||||
[DEBUG] [/devices/host_node] Status updated: BatteryStation.data_glove_box_pressure = 4.229457855224609 [property_callback:666] [unilabos.ros.nodes.presets.host_node]
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
### 4. asyncio 和 urllib3
|
|
||||||
|
|
||||||
**配置位置**: `log.py` 第224-225行
|
|
||||||
|
|
||||||
```python
|
|
||||||
logging.getLogger("asyncio").setLevel(logging.INFO)
|
|
||||||
logging.getLogger("urllib3").setLevel(logging.INFO)
|
|
||||||
```
|
|
||||||
|
|
||||||
**屏蔽原因**:
|
|
||||||
- asyncio: 异步 IO 的内部调试信息
|
|
||||||
- urllib3: HTTP 请求库的连接池、重试等详细信息
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 如何临时启用这些日志(调试用)
|
|
||||||
|
|
||||||
### 方法1: 修改 log.py(永久启用)
|
|
||||||
|
|
||||||
在 `log.py` 的 `configure_logger()` 函数中,将对应库的日志级别改为 `logging.DEBUG`:
|
|
||||||
|
|
||||||
```python
|
|
||||||
# 临时启用 pymodbus 的 DEBUG 日志
|
|
||||||
logging.getLogger('pymodbus').setLevel(logging.DEBUG)
|
|
||||||
logging.getLogger('pymodbus.logging').setLevel(logging.DEBUG)
|
|
||||||
logging.getLogger('pymodbus.logging.base').setLevel(logging.DEBUG)
|
|
||||||
logging.getLogger('pymodbus.logging.decoders').setLevel(logging.DEBUG)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方法2: 在代码中临时启用(单次调试)
|
|
||||||
|
|
||||||
在需要调试的代码文件中添加:
|
|
||||||
|
|
||||||
```python
|
|
||||||
import logging
|
|
||||||
|
|
||||||
# 临时启用 pymodbus DEBUG 日志
|
|
||||||
logging.getLogger('pymodbus').setLevel(logging.DEBUG)
|
|
||||||
|
|
||||||
# 你的 Modbus 调试代码
|
|
||||||
...
|
|
||||||
|
|
||||||
# 调试完成后恢复
|
|
||||||
logging.getLogger('pymodbus').setLevel(logging.WARNING)
|
|
||||||
```
|
|
||||||
|
|
||||||
### 方法3: 使用环境变量或配置文件(推荐)
|
|
||||||
|
|
||||||
未来可以考虑在启动参数中添加 `--debug-modbus` 等选项来动态控制。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 日志级别说明
|
|
||||||
|
|
||||||
| 级别 | 数值 | 用途 | 是否显示 |
|
|
||||||
|------|------|------|---------|
|
|
||||||
| TRACE | 5 | 最详细的跟踪信息 | ✅ |
|
|
||||||
| DEBUG | 10 | 调试信息 | ✅ |
|
|
||||||
| INFO | 20 | 一般信息 | ✅ |
|
|
||||||
| WARNING | 30 | 警告信息 | ✅ |
|
|
||||||
| ERROR | 40 | 错误信息 | ✅ |
|
|
||||||
| CRITICAL | 50 | 严重错误 | ✅ |
|
|
||||||
|
|
||||||
**当前配置**:
|
|
||||||
- UniLabOS 自身代码: DEBUG 及以上全部显示
|
|
||||||
- pymodbus/websockets: **WARNING** 及以上显示(屏蔽 DEBUG/INFO)
|
|
||||||
- ROS host_node: **INFO** 及以上显示(屏蔽 DEBUG)
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ⚠️ 重要提示
|
|
||||||
|
|
||||||
### 修改生效时间
|
|
||||||
- 修改 `log.py` 后需要 **重启 unilab 服务** 才能生效
|
|
||||||
- 不需要重新安装或重新编译
|
|
||||||
|
|
||||||
### 调试 Modbus 通信问题
|
|
||||||
如果需要调试 Modbus 通信故障,应该:
|
|
||||||
1. 临时启用 pymodbus DEBUG 日志(方法2)
|
|
||||||
2. 复现问题
|
|
||||||
3. 查看详细的通信日志
|
|
||||||
4. 调试完成后记得恢复 WARNING 级别
|
|
||||||
|
|
||||||
### 调试设备状态问题
|
|
||||||
如果需要调试设备状态更新问题:
|
|
||||||
```python
|
|
||||||
logging.getLogger('unilabos.ros.nodes.presets.host_node').setLevel(logging.DEBUG)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 维护记录
|
|
||||||
|
|
||||||
| 日期 | 修改内容 | 操作人 |
|
|
||||||
|------|---------|--------|
|
|
||||||
| 2026-01-11 | 初始创建,添加 pymodbus、websockets、ROS host_node 屏蔽 | - |
|
|
||||||
| 2026-01-07 | 添加 pymodbus 和 websockets 屏蔽(log-0107.py) | - |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔗 相关文件
|
|
||||||
|
|
||||||
- `log.py` - 日志配置主文件
|
|
||||||
- `unilabos/devices/workstation/coin_cell_assembly/` - 使用 Modbus 的扣电工作站代码
|
|
||||||
- `unilabos/ros/nodes/presets/host_node.py` - ROS 主机节点代码
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
**维护提示**: 如果添加了新的第三方库或发现新的日志刷屏问题,请在此文档中记录并更新 `log.py` 配置。
|
|
||||||
@@ -24,6 +24,7 @@ class EnvironmentChecker:
|
|||||||
"msgcenterpy": "msgcenterpy",
|
"msgcenterpy": "msgcenterpy",
|
||||||
"opentrons_shared_data": "opentrons_shared_data",
|
"opentrons_shared_data": "opentrons_shared_data",
|
||||||
"typing_extensions": "typing_extensions",
|
"typing_extensions": "typing_extensions",
|
||||||
|
"crcmod": "crcmod-plus",
|
||||||
}
|
}
|
||||||
|
|
||||||
# 特殊安装包(需要特殊处理的包)
|
# 特殊安装包(需要特殊处理的包)
|
||||||
|
|||||||
Reference in New Issue
Block a user