一款用于自动化执行串口指令的脚本,支持多设备、多指令的串行和并行执行
Project description
AutoCom
一款用于自动化执行串口指令的脚本,支持多设备、多指令的串行和并行执行。
📑 目录
📁 项目结构
AutoCom/
├── 📂 components/ # 核心组件模块
│ └── *.py
├── 📂 utils/ # 工具类和辅助函数
│ └── *.py
├── 📂 tests/ # 测试文件目录
│ └── *.py
├── 📂 scripts/ # 构建和维护脚本
│ └── *.py
├── 📂 docs/ # 项目文档
│ └── *.md
├── 📂 dicts/ # 字典配置文件目录
├── 📂 configs/ # 设备配置文件目录
├── AutoCom.py # 主程序入口
├── cli.py # 命令行接口
├── version.py # 版本信息
├── __init__.py # 包初始化文件
└── README.md # 项目说明文档
📂 目录说明
- components/ - 核心功能组件,包含设备管理、指令执行、数据存储等核心模块
- utils/ - 工具函数和操作处理器,包含自定义 Action 扩展接口
- scripts/ - 开发和维护脚本
dev.py- 统一开发工具,集成测试、构建、发布等功能update_actions_doc.py- 更新 Actions.md 文档
- docs/ - 项目文档
Started.md- 快速开始指南DEV.md- 开发指南和工具说明About.md- 项目详细说明和设计文档ToDO.md- 待办事项和未来计划Actions.md- 所有 Action 操作项的详细说明
- dicts/ - 存放指令字典配置文件
- configs/ - 存放设备配置模板文件
- temps/ - 临时数据存储,运行时自动创建
- device_logs/ - 设备执行日志,运行时自动创建
安装
从 PyPI 安装(推荐)
pip install autocom
从 GitHub 直接安装
无需等待 PyPI 发布,可以直接从 GitHub 安装最新版本:
# 从 main 分支安装最新版本
pip install git+https://github.com/iFishin/AutoCom.git
# 从特定版本安装 (推荐)
pip install git+https://github.com/iFishin/AutoCom.git@v1.0.0
从源码安装
# 克隆仓库
git clone https://github.com/iFishin/AutoCom.git
cd AutoCom
# 安装依赖
pip install -r requirements.txt
# 开发模式安装(可编辑)
pip install -e .
手动打包安装
如果你想自己打包:
python scripts/dev.py build
pip install dist/autocom-<version>-py3-none-any.whl
🚀 快速开始
命令行使用
安装后,可以直接使用 autocom 命令:
# 执行字典文件(循环3次)
autocom -d dicts/dict.json -l 3
# 无限循环模式(按 Ctrl+C 停止)
autocom -d dicts/dict.json -i
# 使用配置文件
autocom -d dicts/dict.json -c configs/config.json
# 执行文件夹内所有字典文件
autocom -f dicts/
# 监控模式(监听文件夹,自动执行新文件)
autocom -m temps/
Python API 使用
from autocom import CommandDeviceDict, CommandExecutor, CommonUtils
# 加载配置
dict_data = {...} # 你的配置字典
device_dict = CommandDeviceDict(dict_data)
# 创建执行器
executor = CommandExecutor(device_dict)
# 执行指令
result = executor.execute()
# 清理资源
device_dict.close_all_devices()
executor.data_store.stop()
从源代码中执行
- 单个字典文件执行
python cli.py -d <xxx.json> -l <times> [-c <configFile>]
- 文件夹内所有字典文件顺序执行
python cli.py -f <dictFilePath> -c <configFile>
文件夹内的文件命名得加上前缀区分执行顺序:
[<order>]<filename>.json
- 监听文件夹内新文件
python cli.py -m <monitoredFilePath>
格式框架
设备
Devices
"Devices": [
{
"name": "DeviceA",
"status": "enabled",
"port": "COM65",
"baud_rate": 115200,
"stop_bits": 1,
"parity": null,
"data_bits": 8,
"flow_control": {
"xon_xoff": false,
"rts_cts": false,
"dsr_dtr": false
},
"dtr": false,
"rts": false
},
{
"name": "DeviceB",
"status": "disabled",
"port": "COM64",
"baud_rate": 115200,
"stop_bits": 1,
"parity": null,
"data_bits": 8,
"flow_control": {
"xon_xoff": false,
"rts_cts": false,
"dsr_dtr": false
},
"dtr": false,
"rts": false
}
]
设备参数
| Device | 内容 | 作用 |
|---|---|---|
| name | 设备名称(如 "DeviceA"、"DeviceB") | 标识不同的设备 |
| status | 设备状态("enabled"/"disabled") | 表示设备当前状态 |
| port | 串口名称(如 "COM65") | 指定设备物理连接端口 |
| baud_rate | 波特率(如 115200) | 设定通信速率 |
| stop_bits | 停止位(1/2) | 设定停止位 |
| parity | 奇偶校验("None"/"Even"/"Odd") | 设定奇偶校验 |
| data_bits | 数据位(5/6/7/8) | 设定数据位 |
| flow_control | 流控制配置 | 设定流控制 |
| dtr | DTR信号(true/false) | 设定DTR信号 |
| rts | RTS信号(true/false) | 设定RTS信号 |
| monitor | 是否持续监听设备(true/false) | 设定是否持续监听日志 |
配置执行设备的基本信息。
monitor是针对Debug串口设计的持续日志监听功能,当该属性开启之后,会单独启动一个线程持续监听来自串口的日志。默认情况下是关闭,默认的监听逻辑为有指令发送至该串口后,才会监听一次来自串口的返回数据。
设备列表全局配置
更新加入了
ConfigForDevices属性块,可以利用全局配置来减少设备列表的属性编辑覆盖逻辑为:
ConfigForDevices中的键值对只会替换Devices中相对应不存在的键值对,相反的,如果Devices中存在status: "enabled",且你在ConfigForDevices中也设置了该属性,则不会利用全局配置来替换。
With ConfigForDevices
"ConfigForDevices": {
"status": "enabled",
"stop_bits": 1,
"parity": null,
"data_bits": 8,
"flow_control": {
"xon_xoff": false,
"rts_cts": false,
"dsr_dtr": false
},
"dtr": false,
"rts": false
},
"Devices": [
{
"name": "DeviceA",
"port": "COM14",
"baud_rate": 115200
},
{
"name": "DebugA",
"port": "COM13",
"baud_rate": 115200,
"monitor": true
},
{
"name": "DeviceB",
"port": "COM36",
"baud_rate": 115200
}
]
</code>
</pre> </details>
<h3>操作项</h3>
<p>新版中,已剥离了Actions操作项的函数,单独设计成一个扩展的类,Actions类中包含了所有操作项的实现逻辑。用户可以根据自己的需求,自定义操作项的实现逻辑,方便扩展和维护。</p>
<blockquote>
<p>📖 <strong>详细文档</strong>: 查看 <a href="docs/Actions.md">docs/Actions.md</a> 获取所有操作项的完整说明、参数详解和使用示例。</p>
<p>actions也是一个list类型,包含了针对特定情境的处理方式,如果指令包含了相应的actions项,则会顺序执行列表内的所有action项。</p>
</blockquote>
<h4>操作项全局配置</h4>
<blockquote>
<p>更新加入了<code>ConfigForActions</code>属性块,可以引入自定义的操作项配置。</p>
</blockquote>
<details>
<summary><font size="6">With ConfigForActions</font></summary>
<pre><code class="language-json">
{
"ConfigForActions": {
"handler_class": "utils.custom_actions.CustomActionHandler"
},
"Devices": [...],
"Commands": [...]
}
</code>
</pre> </details>
<h4>操作项编写指南</h4>
<p>在分离ActionHandler之后,在<code>utils/ActionHandler</code>中编写了常用到的action操作,下面用一个简单的例子来讲解自定义Action编写方法:</p>
<pre lang="python"><code>def handle_test(self, text, command, response, context):
"""
测试功能
用法:
{
"test": "test_message"
}
"""
test_message = self.handle_variables_from_str(text)
CommonUtils.print_log_line(f"ℹ Test action executed with message: {test_message}")
CommonUtils.print_log_line("")
return True
首先先了解这个Action是指的什么。上面注释中所描述的{ "test": "test_message" }是一个Action项,也是一个Object对象,这个Action项的名称为test,而这个Action的内容则是test_message。在执行时,这个Action会被传入到handle_test函数中。
然后看看传入的参数列表:
① self这个是指向当前ActionHandler实例的引用,这里必须包含,用于注册ActionHandler的函数
② text这个是传入action所含的Object内容,这里是指{"test": "test_message"}中的"test_message"部分。如果action名包含的是一个Object对象,则会将该对象传入,这里需要注意类型对应。
③ command这个是指当前执行的指令对象,也就是指令字典中的command属性内容。
④ response这个是指当前指令执行后响应内容,这个类型是List,得注意。
⑤ context这个是指当前执行上下文,包含了当前设备、指令等信息。这里的context内容目前为:
{
"device": device,
"device_name": device_name,
"cmd_str": cmd_str,
"expected_responses": updated_expected_responses
}
由于ActionHandler扩展性太多,后续可能变更,请以实际代码逻辑为准。
指令
Commands
"Commmands": [
{
"command": "AT+COMMAND1",
"status": "enabled",
"expected_responses": [
"OK",
"RDY"
],
"device": "DeviceA",
"order": 1,
"parameters": [],
"timeout": 2000,
"concurrent_strategy": "parallel",
"success_actions": [
{
"set_status": "disabled"
}
],
"success_response_actions": [
],
"error_actions": [
{
"retry": 3
}
],
"error_response_actions": [
]
},
{
"command": "AT+COMMAND2",
"status": "enabled",
"expected_responses": [
"OK"
],
"device": "DeviceA",
"order": 3,
"parameters": [],
"timeout": 3000,
"concurrent_strategy": "sequential",
"success_actions": [
{
"set_status": "disabled"
}
],
"success_response_actions": {
"GOT_IP": [
{
"print": "GOT_IP"
}
]
},
"error_actions": [
{
"retry": 3
}
],
"error_response_actions": {
"WLAN_DISCONNECTED": [
{
"print": "DISCONNECTED"
}
],
"SCAN_NO_AP": [
{
"print": "NO AP"
}
]
}
}
]
</code>
</pre> </details>
<h4>指令参数</h4>
<table>
<thead>
<tr>
<th>Command</th>
<th>内容</th>
<th>作用</th>
</tr>
</thead>
<tbody>
<tr>
<td>command</td>
<td>AT指令字符串(如 "AT+RST")</td>
<td>发送给设备的具体指令</td>
</tr>
<tr>
<td>hex_mode</td>
<td>是否以十六进制模式发送指令(true/false)</td>
<td>设定指令发送格式</td>
</tr>
<tr>
<td>status</td>
<td>指令状态("enabled"/"disabled")</td>
<td>指定指令是否可用</td>
</tr>
<tr>
<td>expected_responses</td>
<td>预期响应列表(如 ["OK","RDY"])</td>
<td>判断指令执行成功条件</td>
</tr>
<tr>
<td>device</td>
<td>目标设备名称</td>
<td>指定执行指令的设备</td>
</tr>
<tr>
<td>order</td>
<td>执行顺序(数字)</td>
<td>确定指令执行顺序</td>
</tr>
<tr>
<td><u>parameters</u></td>
<td>指令参数列表</td>
<td>提供指令所需参数</td>
</tr>
<tr>
<td>timeout</td>
<td>超时时间(毫秒)</td>
<td>设定指令执行时限</td>
</tr>
<tr>
<td>concurrent_strategy</td>
<td>"sequential"或"parallel"</td>
<td>设定指令并发策略</td>
</tr>
<tr>
<td><strong>error_actions</strong></td>
<td>错误处理配置</td>
<td>定义错误响应处理方式</td>
</tr>
<tr>
<td><strong>success_actions</strong></td>
<td>成功后续操作</td>
<td>指定成功后的附加动作</td>
</tr>
<tr>
<td><strong>error_response_actions</strong></td>
<td>错误响应后续操作</td>
<td>特定错误响应后的动作</td>
</tr>
<tr>
<td><strong>success_response_actions</strong></td>
<td>成功响应后续操作</td>
<td>特定成功响应后的动作</td>
</tr>
<tr>
<td><del>dependencies</del></td>
<td>依赖指令列表</td>
<td>设定指令执行依赖项</td>
</tr>
</tbody>
</table>
<blockquote>
<ul>
<li>command</li>
<li>expected_responses</li>
<li>parameters</li>
</ul>
<p>expected_responses 的判断逻辑为:顺序匹配,只有所有预期响应都匹配成功,才认为指令执行成功</p>
<p>上面参数都支持向临时数据文件中取用变量,取用逻辑为:<code>{variable_name}</code></p>
<hr />
<ul>
<li>variable_name</li>
</ul>
<p>这个变量的命名格式是字母和下划线的混合</p>
<p>如果临时数据文件中存在该变量则返回对应的值</p>
<p>如果临时数据文件中不存在该变量,则会原始文本输出{variable_name}</p>
<hr />
<ul>
<li>concurrent_strategy</li>
</ul>
<p>脚本中的并发策略为:为相邻参与并行执行的指令按照设备分组,然后为每个设备创建一个线程,并行执行完成后返回直接结果,线程设置了30ms超时时限,防止阻塞。</p>
<hr />
<ul>
<li>order</li>
</ul>
<p>这个执行序号如若遇到序号相同的情形,指令重排之后,相同序号的指令则会按照原始排列出现的顺序执行</p>
</blockquote>
<h4>指令列表全局配置</h4>
<blockquote>
<p>覆盖逻辑同<code>ConfigForDevices</code>,用于简化重复的属性配置。</p>
</blockquote>
<details>
<summary><font size="6">With ConfigForDevices</font></summary>
<pre><code class="language-json">
"ConfigForCommands": {
"status": "enabled",
"timeout": 1000,
"concurrent_strategy": "sequential",
"error_actions": [
{
"retry": 1
}
]
},
"Commands": [
{
"command": "AT+RST",
"expected_responses": [
"OK",
"RDY"
],
"device": "DeviceA",
"success_actions": [
{
"set_status": "disabled"
}
],
"order": 1
},
{
"command": "AT+ECHO=1",
"expected_responses": [
"OK"
],
"device": "DeviceA",
"success_actions": [
{
"set_status": "disabled"
}
],
"order": 1
},
{
"command": "AT+RST",
"expected_responses": [
"OK",
"RDY"
],
"device": "DeviceB",
"success_actions": [
{
"set_status": "disabled"
}
],
"order": 1
},
{
"command": "AT+ECHO=1",
"expected_responses": [
"OK"
],
"device": "DeviceB",
"success_actions": [
{
"set_status": "disabled"
}
],
"order": 1
}
]
</code>
</pre> </details>
<h3>临时性数据</h3>
<details>
<summary><font size="6">Temp-Data</font></summary>
<pre><code class="language-json">
{
"DeviceB": {
"fish": "RST",
"gatt_char": "\"36f5\"",
"ble_address": "\"D87A3B6D522B\""
},
"DeviceA": {
"gatt_char": "\"36f5\""
}
}
</code>
</pre> </details>
> Temp-Data可当作一个简易数据库的功能,用于存取执行过程中的各类临时性变量。
<p>目前这个数据存取使用一个<code>DataStore</code>类来控制,该类目前提供了两个方法:</p>
<ul>
<li><strong>store_data</strong></li>
</ul>
<blockquote>
<p>用于存储变量到指定设备名中去。操作方法为(data_store为实例):</p>
<p><code>data_store.store_data(<device_name>, <variable_name>, <value>)</code></p>
</blockquote>
<ul>
<li><strong>get_data</strong></li>
</ul>
<blockquote>
<p>用于获取指定设备名中的变量值。操作方法为(data_store为实例):</p>
<p><code>data_store.get_data(<device_name>, <variable_name>)</code></p>
</blockquote>
<h3>全局常量</h3>
<blockquote>
<p>全局常量是指在指令字典文件中,<code>Constants</code>属性块内定义的常量。这些常量可以在指令参数、操作项参数等地方通过<code>{constant_name}</code>的方式引用,方便在多个地方使用同一个值,并且只需要修改一处即可。</p>
<p>常量的命名格式为全大写字母和下划线的组合,例如<code>AP_NAME</code>、<code>AP_PASSWORD</code>等。使用时需要确保常量名称与定义时一致,并且在引用时使用花括号包裹起来。</p>
<p>ℹ 当常量中没有给定相对应的值的时候,在你执行字典文件时会提示你输入该常量的值,输入完成后会自动替换指令参数中的相应常量引用,并且将你输入的值存储到临时数据中,供后续指令参数调用。</p>
</blockquote>
<h4>全局常量使用方法</h4>
<p><code>Constants</code>属性块与<code>Commands</code>和<code>Devices</code>等属性块是平级的,位于指令字典文件的根层级。你可以在<code>Constants</code>中定义任意数量的常量,例如:</p>
<pre lang="json"><code>{
"Constants": {
"DeviceA_PORT": "COM14",
"AP_NAME": "MyAccessPoint",
"AP_PASSWORD": "SecurePass123",
"Target_SSID": "TargetNetwork",
"Target_PASSWORD": "targetpass456"
},
"Devices": [...],
"Commands": [...]
}
在上面的例子中,我们定义了四个常量:AP_NAME、AP_PASSWORD、Target_SSID和Target_PASSWORD。你可以在指令参数中通过{AP_NAME}、{AP_PASSWORD}等方式引用这些常量,例如:
{
"command": "AT+SOFTAP=\"{AP_NAME}\",\"{AP_PASSWORD}\"",
"expected_responses": [
"OK"
],
"device": "DeviceA",
"order": 1,
"parameters": [],
"timeout": 3000,
"success_actions": [
{
"wifi_connect": {
"ssid": "{AP_NAME}",
"password": "{AP_PASSWORD}",
"timeout": 20
}
}
]
}
当然,你也可以在执行字典中各个地方穿插全局常量的引用,你甚至可以在Devices属性块中引用全局常量,例如:
{
"Constants": {
"DeviceA_PORT": "COM14",
"AP_NAME": "MyAccessPoint",
"AP_PASSWORD": "SecurePass123"
},
"Devices": [
{
"name": "DeviceA",
"status": "enabled",
"port": "{DeviceA_PORT}",
"baud_rate": 115200,
"stop_bits": 1,
"parity": null,
"data_bits": 8,
"flow_control": {
"xon_xoff": false,
"rts_cts": false,
"dsr_dtr": false
},
"dtr": false,
"rts": false
}
],
"Commands": [
{
"command": "AT+SOFTAP=\"{AP_NAME}\",\"{AP_PASSWORD}\"",
"expected_responses": [
"OK"
],
"device": "DeviceA",
"order": 1,
"parameters": [],
"timeout": 3000,
"success_actions": [
{
"wifi_connect": {
"ssid": "{AP_NAME}",
"password": "{AP_PASSWORD}",
"timeout": 20
}
}
]
}
]
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file autocom-1.1.0.tar.gz.
File metadata
- Download URL: autocom-1.1.0.tar.gz
- Upload date:
- Size: 59.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b46cebeb662694c1d0f4b3dc8f0e8fe87424ae66889bb31aaf5eb91333e3039c
|
|
| MD5 |
de9532919b939503872a99e43a433942
|
|
| BLAKE2b-256 |
eef949dc0cd0879435f49b87f62722f4675b72123460d6c4b5fd1f4fb5cf7081
|
File details
Details for the file autocom-1.1.0-py3-none-any.whl.
File metadata
- Download URL: autocom-1.1.0-py3-none-any.whl
- Upload date:
- Size: 63.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.9.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4423476514bd6a2dfd34af70a5562d1760bc81c1e19e36f53c76fccfc3b4e6cd
|
|
| MD5 |
a41c653363063bbf1200e12bd60e2dd0
|
|
| BLAKE2b-256 |
bfe214eb274611ad8a43ffb6755c4de4cffc1d94a5fd1ff874d6ea2e84a07aaa
|