项目实战——使用python脚本完成指定OTA或者其他功能的自动化断电上电测试

前言

在嵌入式设备的OTA场景测试和其他断电上电测试过程中,有的场景发生在夜晚 或者随时 可能发生,这个时候不可能24h人工盯着,需要自动化抓取串口日志处罚断电上电操作。

下面的python脚本可以实现自动抓取串口指定关键词,然后触发继电器的主动断电上电操作,具体场景是在我实际开发项目中,有一个静默升级的功能,在夜间静默推送升级功能,需要做下载过程的随机断电防止出现升级过程卡死。

我写了以下的工具,可以捕捉mobxterm上面的日志指定关键字,当扫描到指定关键字进行断电或者上电的测试,完成夜间的随机物理断电测试。

准备工作

  1. 带有ch340串口芯片或者其他串口芯片的继电器模块

  2. mobxterm软件

  3. python脚本

代码

python脚本如下,python3环境执行

c 复制代码
# *Copyright(C),2025-20xx
# *FileName:  
# *Author:  ljl
# *Version:  
# *Date:  
# *Description:  


import serial
import time
import os

last_mod_time = 0
# 监控的日志文件路径
log_file_path = "[com COM3]  (2025-01-09_152828)  罗的板子(COM3).log"

# 你想要监控的关键词,这里设置为 "percent: 40"
keywords = ["percent: 40"]

# 设置串口参数
serial_port = 'COM2'  # 请根据你的实际情况更改串口号
baud_rate = 9600  # 根据你的设备设置正确的波特率

# 发送十六进制串口指令的函数
def send_hex_serial_command(port, baudrate, hex_command):
    # 打开串口
    ser = serial.Serial(port, baudrate, timeout=1)

    try:
        # 将十六进制字符串转换为字节对象
        command_bytes = bytes.fromhex(hex_command)

        # 发送指令
        ser.write(command_bytes)

    except Exception as e:
        print(f"发生错误: {e}")

    finally:
        # 关闭串口
        ser.close()


def elect_init():
    print("初始化继电器,执行串口上电程序!")
    # 执行串口上电
    hex_command_to_send = "A0 01 00 A1"  # 断电指令
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)

    hex_command_to_send = "A0 02 00 A2"  # 断电指令
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)

    hex_command_to_send = "A0 03 00 A3"  # 断电指令
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)

    hex_command_to_send = "A0 04 00 A4"  # 断电指令
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)


# 根据关键词执行串口断电操作
def execute_script():
    print("找到 'percent: 40',执行串口断电程序!")

    # 执行串口断电
    hex_command_to_send = "A0 01 01 A2"  # 请替换为你实际要发送的十六进制指令,用空格分隔每个字节
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)
    hex_command_to_send = "A0 02 01 A3"  # 请替换为你实际要发送的十六进制指令,用空格分隔每个字节
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)
    hex_command_to_send = "A0 03 01 A4"  # 请替换为你实际要发送的十六进制指令,用空格分隔每个字节
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)
    hex_command_to_send = "A0 04 01 A5"  # 请替换为你实际要发送的十六进制指令,用空格分隔每个字节
    send_hex_serial_command(serial_port, baud_rate, hex_command_to_send)


# 监控日志文件的函数
def monitor_log():
    global last_mod_time
    start_time = time.time()  # 获取程序开始时的时间
    print("开始监控日志文件...")

    try:
        while True:
            # 获取文件的最后修改时间
            current_mod_time = os.path.getmtime(log_file_path)

            # 如果文件发生更新(修改时间不同),重新读取并检查文件
            if current_mod_time > last_mod_time:
                last_mod_time = current_mod_time  # 更新最后修改时间

                with open(log_file_path, "r") as log_file:
                    # 从文件开头开始读取
                    for line in log_file:
                        # 检查日志行是否包含关键词
                        for keyword in keywords:
                            if keyword in line:
                                # 计算当前时间与开始时间的间隔
                                elapsed_time = time.time() - start_time
                                print(f"找到关键词 '{keyword}',执行串口指令")
                                print(f"当前时间:{time.strftime('%H:%M:%S', time.gmtime(elapsed_time))},已运行 {elapsed_time:.2f} 秒")
                                execute_script()
                                break

            # 每10秒钟再次执行一次检查
            time.sleep(10)

    except FileNotFoundError:
        print(f"错误: 无法打开日志文件 {log_file_path},文件未找到。")
    except IOError as e:
        print(f"错误: 打开日志文件时发生IO错误: {e}")


if __name__ == "__main__":
    elect_init()  # 初始化继电器
    monitor_log()  # 开始监控日志文件

实验现象

执行脚本后,如果文件不存在会直接打印文件不存在,找到对应关键字和执行相关操作都会有时间打印。

注意

mobxterm等其他串口工具可以实现自动保存日志,但是日志不会再次刷新,python脚本中需要检测文件编辑时间去再次打开文件获取最新串口数据

相关推荐
mftang16 小时前
基于GD32的直流无刷电机控制算法实现和验证
单片机·嵌入式硬件·rt-thread·gd32f527i-eval
X.Ming 同学16 小时前
QXlsx 库在麒麟 Linux(Qt 5.15.2)下完整安装步骤(含问题排查 & 经验总结)
linux·数据库·qt
杰克崔16 小时前
localtime接口与localtime_r接口
linux·运维·服务器·车载系统
HalvmånEver16 小时前
Linux:简介(进程间通信一)
linux·运维·服务器
代码游侠16 小时前
学习笔记——数据封包拆包与协议
linux·运维·开发语言·网络·笔记·学习
清风66666616 小时前
基于单片机的十字路口交通信号灯控制系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业
FIT2CLOUD飞致云16 小时前
支持IP证书签发、数据库TCP代理,1Panel v2.0.16版本正式发布
linux·运维·服务器·开源·1panel·ip证书
渡我白衣16 小时前
计算机组成原理(10):逻辑门电路
android·人工智能·windows·嵌入式硬件·硬件工程·计组·数电
Q741_14716 小时前
Linux UDP 服务端 实战思路 C++ 套接字 源码包含客户端与服务端 游戏服务端开发基础
linux·服务器·c++·游戏·udp
SMF191916 小时前
解决从物理机复制的文件无法粘贴到vm虚拟机centos系统中问题
linux·运维·centos