diff --git a/generate_manual.py b/generate_manual.py index dbc2049..f063925 100644 --- a/generate_manual.py +++ b/generate_manual.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -生成《网关配置工具使用说明书》PDF +ɡùʹ˵顷PDF """ import os from reportlab.lib.pagesizes import A4 @@ -15,14 +15,14 @@ from reportlab.platypus import ( from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.ttfonts import TTFont -# ── 注册中文字体 ────────────────────────────────────────────── +# ע FONT_DIR = os.path.join(os.environ.get("WINDIR", r"C:\Windows"), "Fonts") FONT_NAME = "SimSun" FONT_BOLD = "SimHei" pdfmetrics.registerFont(TTFont(FONT_NAME, os.path.join(FONT_DIR, "simsun.ttc"))) pdfmetrics.registerFont(TTFont(FONT_BOLD, os.path.join(FONT_DIR, "simhei.ttf"))) -# ── 颜色 ───────────────────────────────────────────────────── +# ɫ PRIMARY = HexColor("#1565C0") ACCENT = HexColor("#4CAF50") LIGHT_BG = HexColor("#E3F2FD") @@ -30,7 +30,7 @@ TABLE_HEAD_BG = HexColor("#1565C0") TABLE_ALT_BG = HexColor("#F5F5F5") BORDER_COLOR = HexColor("#BDBDBD") -# ── 样式 ────────────────────────────────────────────────────── +# ʽ styles = getSampleStyleSheet() style_title = ParagraphStyle( @@ -70,9 +70,9 @@ style_toc_sub = ParagraphStyle( leftIndent=10 * mm, spaceAfter=1 * mm ) -# ── 工具函数 ────────────────────────────────────────────────── -LQ = "\u300c" # 左角括号 -RQ = "\u300d" # 右角括号 +# ߺ +LQ = "\u300c" # +RQ = "\u300d" # ҽ def heading1(text): return Paragraph(text, style_h1) @@ -125,8 +125,8 @@ def make_table(headers, rows, col_widths=None): t.setStyle(TableStyle(style_cmds)) return t -# ── 构建文档 ────────────────────────────────────────────────── -OUTPUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "网关配置工具使用说明书.pdf") +# ĵ +OUTPUT = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ùʹ˵.pdf") doc = SimpleDocTemplate( OUTPUT, pagesize=A4, @@ -136,21 +136,21 @@ doc = SimpleDocTemplate( story = [] -# ==================== 封面 ==================== +# ==================== ==================== story.append(Spacer(1, 50 * mm)) -story.append(Paragraph("网关配置工具", style_title)) -story.append(Paragraph("使用说明书", style_title)) +story.append(Paragraph("ù", style_title)) +story.append(Paragraph("ʹ˵", style_title)) story.append(Spacer(1, 15 * mm)) story.append(HRFlowable(width="60%", thickness=2, color=PRIMARY, spaceAfter=6 * mm)) -story.append(Paragraph("适用于物联网网关设备的串口配置管理", style_subtitle)) +story.append(Paragraph("豸Ĵù", style_subtitle)) story.append(Spacer(1, 10 * mm)) cover_info = [ - ["软件名称", "网关配置工具"], - ["适用设备", "物联网网关(HC32F460 + 4G/Cat1 + Ethernet)"], - ["通信接口", "串口(UART),波特率默认500000可修改"], - ["运行环境", "Windows 7/10/11"], - ["文档版本", "V1.0"], + ["", "ù"], + ["豸", ""], + ["ͨŽӿ", "ڣUARTĬ500000޸"], + ["л", "Windows 7/10/11"], + ["ĵ汾", "V1.0"], ] cover_table = Table(cover_info, colWidths=[40 * mm, 90 * mm]) cover_table.setStyle(TableStyle([ @@ -170,223 +170,223 @@ cover_table.setStyle(TableStyle([ story.append(cover_table) story.append(PageBreak()) -# ==================== 目录 ==================== -story.append(heading1("目 录")) +# ==================== Ŀ¼ ==================== +story.append(heading1("Ŀ ¼")) story.append(hr()) toc_items = [ - ("1", "产品概述"), - (" 1.1", "功能简介"), - (" 1.2", "系统要求"), - (" 1.3", "软件界面总览"), - ("2", "快速入门"), - (" 2.1", "连接设备"), - (" 2.2", "查看网关配置"), - ("3", "功能详解"), - (" 3.1", "串口连接"), - (" 3.2", "查看配置(para)"), - (" 3.3", "Lora信道配置"), - (" 3.4", "自定义指令"), - (" 3.5", "通讯日志"), - ("4", "指令参考"), - ("5", "常见问题(FAQ)"), - ("6", "注意事项"), + ("1", "Ʒ"), + (" 1.1", "ܼ"), + (" 1.2", "ϵͳҪ"), + (" 1.3", ""), + ("2", ""), + (" 2.1", "豸"), + (" 2.2", "鿴"), + ("3", ""), + (" 3.1", ""), + (" 3.2", "鿴ãpara"), + (" 3.3", "Loraŵ"), + (" 3.4", "Զָ"), + (" 3.5", "ͨѶ־"), + ("4", "ָο"), + ("5", "⣨FAQ"), + ("6", "ע"), ] for num, title in toc_items: s = style_toc if not num.startswith(" ") else style_toc_sub story.append(Paragraph(f"{num} {title}", s)) story.append(PageBreak()) -# ==================== 1. 产品概述 ==================== -story.append(heading1("1 产品概述")) +# ==================== 1. Ʒ ==================== +story.append(heading1("1 Ʒ")) story.append(hr()) -story.append(heading2("1.1 功能简介")) +story.append(heading2("1.1 ܼ")) story.append(body( - f"网关配置工具是一款基于串口通信的物联网网关设备配置管理软件。通过本工具,用户可以方便地完成以下操作:" + f"ùһڴͨŵ豸ùͨߣûԷ²" )) story.append(Spacer(1, 2 * mm)) features = [ - ["功能模块", "说明"], - ["串口通信", "通过USB转串口连接网关设备,波特率默认500000可自行修改,实时收发指令"], - ["配置读取", "一键读取网关全部参数,包括软件/硬件版本、MAC地址、电池状态、注册状态等"], - ["Lora信道配置", "选择并设置Lora通信信道频率(470.1MHz ~ 492.6MHz)"], - ["自定义指令", "支持手动输入任意指令与网关交互"], - ["通讯日志", "实时显示发送和接收的通讯数据,便于调试"], + ["ģ", "˵"], + ["ͨ", "ͨUSBת豸Ĭ500000޸ģʵʱշָ"], + ["öȡ", "һȡȫ/Ӳ汾MACַ״̬ע״̬"], + ["Loraŵ", "ѡLoraͨŵƵʣ470.1MHz ~ 492.6MHz"], + ["Զָ", "ֶָ֧ؽ"], + ["ͨѶ־", "ʵʱʾͺͽյͨѶݣڵ"], ] story.append(make_table(features[0], features[1:], col_widths=[35 * mm, 115 * mm])) story.append(Spacer(1, 3 * mm)) -story.append(heading2("1.2 系统要求")) +story.append(heading2("1.2 ϵͳҪ")) req_rows = [ - ["操作系统", "Windows 7 / 10 / 11(64位推荐)"], - ["接口", "USB接口(用于连接USB转串口线)"], - ["驱动", "USB转串口芯片驱动(如CH340/CP2102等)"], - ["运行依赖", "无需安装Python环境,直接运行可执行文件"], + ["ϵͳ", "Windows 7 / 10 / 1164λƼ"], + ["ӿ", "USBӿڣUSBתߣ"], + ["", "USBתоƬCH340/CP2102ȣ"], + ["", "谲װPythonֱпִļ"], ] -story.append(make_table(["项目", "要求"], req_rows, col_widths=[35 * mm, 115 * mm])) +story.append(make_table(["Ŀ", "Ҫ"], req_rows, col_widths=[35 * mm, 115 * mm])) -story.append(heading2("1.3 软件界面总览")) -story.append(body("软件界面自上而下分为以下几个区域:")) +story.append(heading2("1.3 ")) +story.append(body("϶·Ϊ¼")) ui_rows = [ - [f"{LQ}串口连接{RQ}区", "选择串口、刷新端口列表、打开/关闭串口"], - [f"{LQ}参数配置{RQ}区", f"设置LoRa信道频率、{LQ}查看配置(para){RQ}、{LQ}设备升级{RQ}按钮"], - [f"{LQ}设备参数信息{RQ}区", f"显示网关读取到的各项参数(版本、MAC、电池、注册状态等)"], - [f"{LQ}通讯日志{RQ}区", f"实时显示收发数据(蓝色=发送,橙色=接收)"], - [f"{LQ}自定义指令{RQ}区", f"手动输入任意指令发送"], + [f"{LQ}{RQ}", "ѡ񴮿ڡˢ¶˿б/رմ"], + [f"{LQ}{RQ}", f"LoRaŵƵʡ{LQ}鿴(para){RQ}{LQ}豸{RQ}ť"], + [f"{LQ}豸Ϣ{RQ}", f"ʾضȡĸ汾MACءע״̬ȣ"], + [f"{LQ}ͨѶ־{RQ}", f"ʵʱʾշݣɫ=ͣɫ=գ"], + [f"{LQ}Զָ{RQ}", f"ֶָ"], ] -story.append(make_table(["区域", "功能说明"], ui_rows, col_widths=[35 * mm, 115 * mm])) +story.append(make_table(["", "˵"], ui_rows, col_widths=[35 * mm, 115 * mm])) story.append(PageBreak()) -# ==================== 2. 快速入门 ==================== -story.append(heading1("2 快速入门")) +# ==================== 2. ==================== +story.append(heading1("2 ")) story.append(hr()) -story.append(heading2("2.1 连接设备")) -story.append(body("按照以下步骤连接网关设备:")) +story.append(heading2("2.1 豸")) +story.append(body("²豸")) steps = [ - "使用USB转串口线连接电脑与网关设备的调试串口;", - "确认电脑已安装对应的USB转串口驱动;", - f"启动{LQ}网关配置工具{RQ}软件;", - f"在{LQ}串口连接{RQ}区域,点击刷新按钮,扫描可用串口;", - "从下拉列表中选择对应的串口号(如COM3);", - "点击打开串口按钮,建立连接。", + "ʹUSBתӵ豸ĵԴڣ", + "ȷϵѰװӦUSBת", + f"{LQ}ù{RQ}", + f"{LQ}{RQ}򣬵ˢťɨôڣ", + "бѡӦĴںţCOM3", + "򿪴ťӡ", ] for i, s in enumerate(steps, 1): - story.append(Paragraph(f"步骤{i}:{s}", style_body)) + story.append(Paragraph(f"{i}{s}", style_body)) story.append(Spacer(1, 2 * mm)) -story.append(note(f"连接成功后,按钮变为红色{LQ}关闭串口{RQ},状态栏显示已连接的串口号。")) +story.append(note(f"ӳɹ󣬰ťΪɫ{LQ}رմ{RQ}״̬ʾӵĴںš")) -story.append(heading2("2.2 查看网关配置")) +story.append(heading2("2.2 鿴")) story.append(body( - f"串口连接成功后,点击查看配置(para)按钮,软件将自动向网关发送{LQ}para{RQ}指令," - f"网关返回配置信息后,界面各区域将自动更新显示当前参数值。" + f"ӳɹ󣬵鿴(para)ťԶط{LQ}para{RQ}ָ" + f"طϢ󣬽Զʾǰֵ" )) story.append(PageBreak()) -# ==================== 3. 功能详解 ==================== -story.append(heading1("3 功能详解")) +# ==================== 3. ==================== +story.append(heading1("3 ")) story.append(hr()) # 3.1 -story.append(heading2("3.1 串口连接")) -story.append(body("串口连接是使用本工具的前提。串口参数(波特率可修改,默认500000):")) +story.append(heading2("3.1 ")) +story.append(body("ʹñߵǰᡣڲʿ޸ģĬ500000")) serial_rows = [ - ["波特率", "500000(可在下拉框中选择或手动输入)"], - ["数据位", "8"], - ["停止位", "1"], - ["校验位", "None(无校验)"], + ["", "500000ѡֶ룩"], + ["λ", "8"], + ["ֹͣλ", "1"], + ["Уλ", "NoneУ飩"], ] -story.append(make_table(["参数", "值"], serial_rows, col_widths=[40 * mm, 60 * mm])) +story.append(make_table(["", "ֵ"], serial_rows, col_widths=[40 * mm, 60 * mm])) story.append(Spacer(1, 2 * mm)) -story.append(note("如无法连接,请检查串口驱动是否正确安装,以及串口是否被其他程序占用。")) +story.append(note("޷ӣ鴮ǷȷװԼǷռá")) # 3.2 -story.append(heading2("3.2 查看配置(para)")) +story.append(heading2("3.2 鿴ãpara")) story.append(body( - f"点击{LQ}查看配置(para){RQ}按钮后,软件发送{LQ}para{RQ}指令,网关返回包含以下信息的配置数据块:" + f"{LQ}鿴(para){RQ}ť{LQ}para{RQ}ָطذϢݿ飺" )) para_rows = [ - ["软件版本", "SoftWare V", "网关固件版本号"], - ["硬件版本", "HardWare V", "网关硬件版本号"], - ["网关MAC", "GateWay MAC", "网关唯一MAC地址"], - ["电池电量", "Battery", "当前电池电量"], - ["注册状态", "MuchReg", "true=已注册,false/null=未注册"], - ["通讯方式", "Much", "当前主通讯方式(eth/cat1/lora)"], - ["Cat1 IMEI", "Cat1 IMEI", "4G模块IMEI号"], - ["Cat1 SIM", "Cat1 SIM", "SIM卡信息"], - ["Lora频率", "Lora fc", "当前Lora信道频率"], + ["汾", "SoftWare V", "ع̼汾"], + ["Ӳ汾", "HardWare V", "Ӳ汾"], + ["MAC", "GateWay MAC", "ΨһMACַ"], + ["ص", "Battery", "ǰص"], + ["ע״̬", "MuchReg", "true=עᣬfalse/null=δע"], + ["ͨѶʽ", "Much", "ǰͨѶʽeth/cat1/lora"], + ["Cat1 IMEI", "Cat1 IMEI", "4GģIMEI"], + ["Cat1 SIM", "Cat1 SIM", "SIMϢ"], + ["LoraƵ", "Lora fc", "ǰLoraŵƵ"], ] -story.append(make_table(["显示项", "指令关键字", "说明"], para_rows, col_widths=[30 * mm, 45 * mm, 75 * mm])) +story.append(make_table(["ʾ", "ָؼ", "˵"], para_rows, col_widths=[30 * mm, 45 * mm, 75 * mm])) # 3.3 -story.append(heading2("3.3 Lora信道配置")) +story.append(heading2("3.3 Loraŵ")) story.append(body( - "Lora信道配置用于设置网关的Lora无线通信频率。信道列表覆盖470.1MHz至492.6MHz范围," - "频率间隔0.5MHz,共46个信道可供选择。" + "LoraŵصLoraͨƵʡŵб470.1MHz492.6MHzΧ" + "Ƶʼ0.5MHz46ŵɹѡ" )) story.append(Spacer(1, 2 * mm)) -story.append(heading3("操作步骤")) +story.append(heading3("")) lora_steps = [ - "在Lora信道下拉框中选择目标信道(显示信道编号和对应频率);", - f"点击发送按钮,发送{LQ}lora fc [频率值]{RQ}指令。", + "LoraŵѡĿŵʾŵźͶӦƵʣ", + f"ť{LQ}lora fc [Ƶֵ]{RQ}ָ", ] for i, s in enumerate(lora_steps, 1): story.append(Paragraph(f"{i}. {s}", style_body)) story.append(Spacer(1, 2 * mm)) lora_range = [ - ["起始频率", "470.1 MHz(信道0)"], - ["终止频率", "492.6 MHz(信道45)"], - ["频率间隔", "0.5 MHz(500 kHz)"], - ["指令格式", "lora fc [频率值,单位Hz]"], + ["ʼƵ", "470.1 MHzŵ0"], + ["ֹƵ", "492.6 MHzŵ45"], + ["Ƶʼ", "0.5 MHz500 kHz"], + ["ָʽ", "lora fc [ƵֵλHz]"], ] -story.append(make_table(["项目", "值"], lora_range, col_widths=[35 * mm, 115 * mm])) +story.append(make_table(["Ŀ", "ֵ"], lora_range, col_widths=[35 * mm, 115 * mm])) # 3.4 -story.append(heading2("3.4 自定义指令")) +story.append(heading2("3.4 Զָ")) story.append(body( - "自定义指令区域允许用户手动输入任意指令与网关交互,适用于高级调试和特殊配置场景。" + "Զָûֶָؽڸ߼Ժó" )) story.append(Spacer(1, 2 * mm)) custom_steps = [ - "在指令输入框中输入要发送的指令文本;", - "按Enter键或点击发送按钮发送指令;", - "发送后输入框自动清空,回复数据将在通讯日志中显示。", + "ָҪ͵ָı", + "Enterťָ", + "ͺԶգظݽͨѶ־ʾ", ] for i, s in enumerate(custom_steps, 1): story.append(Paragraph(f"{i}. {s}", style_body)) # 3.5 -story.append(heading2("3.5 通讯日志")) -story.append(body("通讯日志区域实时显示与网关的通讯数据,采用深色背景方便阅读:")) +story.append(heading2("3.5 ͨѶ־")) +story.append(body("ͨѶ־ʵʱʾصͨѶݣɫĶ")) log_rows = [ - ["蓝色文字", "发送的指令(>>> 前缀)", "发送的指令内容"], - ["橙色文字", "接收的数据(<<< 前缀)", "网关返回的原始数据"], + ["ɫ", "͵ָ>>> ǰ׺", "͵ָ"], + ["ɫ", "յݣ<<< ǰ׺", "طصԭʼ"], ] -story.append(make_table(["颜色", "类型", "说明"], log_rows, col_widths=[25 * mm, 45 * mm, 80 * mm])) +story.append(make_table(["ɫ", "", "˵"], log_rows, col_widths=[25 * mm, 45 * mm, 80 * mm])) story.append(Spacer(1, 2 * mm)) -story.append(note(f"点击{LQ}清空日志{RQ}按钮可清除当前日志内容。日志数据仅保留在内存中,关闭软件后自动清除。")) +story.append(note(f"{LQ}־{RQ}ťǰ־ݡ־ݽڴУرԶ")) story.append(PageBreak()) -# ==================== 4. 指令参考 ==================== -story.append(heading1("4 指令参考")) +# ==================== 4. ָο ==================== +story.append(heading1("4 ָο")) story.append(hr()) -story.append(body("以下为网关配置工具使用的全部指令汇总:")) +story.append(body("Ϊùʹõȫָܣ")) story.append(Spacer(1, 2 * mm)) cmd_rows = [ - ["para", "读取网关全部配置参数", "查看配置(para)"], - ["lora fc <频率>", "设置Lora信道频率(Hz)", "Lora信道配置"], + ["para", "ȡȫò", "鿴(para)"], + ["lora fc <Ƶ>", "LoraŵƵ(Hz)", "Loraŵ"], ] story.append(make_table( - ["指令格式", "功能说明", "对应操作"], + ["ָʽ", "˵", "Ӧ"], cmd_rows, col_widths=[42 * mm, 58 * mm, 50 * mm] )) story.append(Spacer(1, 3 * mm)) -story.append(note("所有指令以回车换行(\\r\\n)结尾。自定义指令区域可发送以上指令及网关支持的其他指令。")) +story.append(note("ָԻس(\\r\\n)βԶָɷָֵָ֧")) story.append(PageBreak()) -# ==================== 5. 常见问题 ==================== -story.append(heading1("5 常见问题(FAQ)")) +# ==================== 5. ==================== +story.append(heading1("5 ⣨FAQ")) story.append(hr()) faqs = [ - ("Q1:打开串口失败怎么办?", - "1)检查USB转串口线是否正确连接;2)确认串口驱动已安装(设备管理器中可见COM口);" - f"3)确认该串口未被其他程序占用;4)尝试点击{LQ}刷新{RQ}重新扫描串口列表。"), - ("Q2:发送指令后没有回复?", - f"1)确认串口已成功打开(按钮显示红色{LQ}关闭串口{RQ});2)检查串口线RX/TX是否接反;" - "3)确认网关设备已上电且正常运行;4)尝试重新连接串口。"), - ("Q3:Lora信道列表很长,如何快速选择?", - "Lora信道下拉框支持鼠标滚轮滚动选择,也可以点击下拉后直接滚动浏览。" - "信道编号和频率一一对应,选择后点击发送即可。"), + ("Q1򿪴ʧô죿", + "1USBתǷȷӣ2ȷϴѰװ豸пɼCOMڣ" + f"3ȷϸôδռã4Ե{LQ}ˢ{RQ}ɨ贮б"), + ("Q2ָûлظ", + f"1ȷϴѳɹ򿪣ťʾɫ{LQ}رմ{RQ}2鴮RX/TXǷӷ" + "3ȷ豸ϵУ4Ӵڡ"), + ("Q3Loraŵбܳοѡ", + "Loraŵֹ֧ѡҲԵֱӹ" + "ŵźƵһһӦѡͼɡ"), ] for q, a in faqs: story.append(Paragraph(f"{q}", style_body)) @@ -395,16 +395,16 @@ for q, a in faqs: story.append(PageBreak()) -# ==================== 6. 注意事项 ==================== -story.append(heading1("6 注意事项")) +# ==================== 6. ע ==================== +story.append(heading1("6 ע")) story.append(hr()) warnings = [ - "串口独占:同一串口在同一时间只能被一个程序打开,请确保使用前关闭其他可能占用串口的软件。", - "波特率:波特率默认500000,可在下拉框选择或手动输入修改,请与网关固件实际波特率保持一致。", - f"数据备份:修改配置前建议先通过{LQ}查看配置{RQ}记录当前参数,以便需要时恢复。", - "断电保护:配置修改后请确认网关已保存参数,避免在参数写入过程中断电。", - "驱动安装:首次使用需安装USB转串口芯片驱动(如CH340、CP2102等),具体型号取决于使用的转接线。", + "ڶռͬһͬһʱֻܱһ򿪣ȷʹǰرռôڵ", + "ʣĬ500000ѡֶ޸ģع̼ʵʲʱһ¡", + f"ݱݣ޸ǰͨ{LQ}鿴{RQ}¼ǰԱҪʱָ", + "ϵ籣޸ĺȷѱڲджϵ硣", + "װ״ʹ谲װUSBתоƬCH340CP2102ȣͺȡʹõתߡ", ] for w in warnings: story.append(Paragraph(f"\u26a0 {w}", style_body)) @@ -412,11 +412,11 @@ for w in warnings: story.append(Spacer(1, 20 * mm)) story.append(hr()) -story.append(Paragraph("\u2014 文档结束 \u2014", ParagraphStyle( +story.append(Paragraph("\u2014 ĵ \u2014", ParagraphStyle( "End", fontName=FONT_NAME, fontSize=10, alignment=TA_CENTER, textColor=HexColor("#9E9E9E") ))) -# ── 生成PDF ────────────────────────────────────────────────── +# PDF doc.build(story) -print(f"PDF已生成: {OUTPUT}") +print(f"PDF: {OUTPUT}")