我的技术记录
type: channel
link: https://www.arcsiny.com/
description: 偷得浮生半日闲
items: CAD快速统计文字数量
items: 火山引擎全站加速证书自动更新脚本实践
items: CAD自定义命令:一键拉伸对齐
items: Microsoft ToDo月视图看板
items: HomeAssistant配置-公共事业仪表
items: 末日生存指南-药品篇
items: 末日生存指南-汇总篇
items: FreeCAD 批量获取Step文件各零件包围盒尺寸
items: CAD自定义块属性
items: Linux 查询开机以来磁盘写入量

CAD快速统计文字数量
type: item
date: 2026-05-25T15:15:00+08:00
description: 在CAD图纸中，经常需要统计不同文字内容的出现次数，比如房间名称、设备编号、材料标注等。当文字种类达到十几种甚至几十种时，手动计数或重复使用“快速选择”会非常低效。本文将介绍几种实用的统计方法，并重点给出一种能够在图纸内自动生成统计表格的完整解决方案。 一、常见统计方法对比 方法 核心操作 适用场景 是否支持一键分类 TEXTCOUNT / TC 直接输入命令，全选文字 只需文字总数 否 查找和替换 (FIND) 输入具体文字串，查看匹配数 统计某一种特定文字 否（每次一种） 快速选择 (QSELECT) 按“内容”特性筛选指定文字 文字种类较少时 否（需重复操作） 数据提取 + Excel 将文字内容导出为CSV/XLS，用透视表统计 任意数量种类，一次性导出 是 专用LISP插件 运行程序，自动生成表格 频繁需要统计并出表 是 当文字种类达到16种以上时，数据提取法和LISP插件法是最佳选择。 二、方法一：数据提取 + Excel（无需插件） 该方法利用AutoCAD自带的“数据提取”功能，将所有文字内容导出到外部表格，再借助Excel的数据透视表完成分类计数。 操作步骤 启动数据提取 命令行输入 DATAEXTRACTION（或 DX），回车。 创建新提取 选择“创建新提取”，为.dxe文件命名并保存。 选择对象 选择“在当前图形中选择对象” 点击“选择对象”，框选整个图形或按Ctrl+A全选 确认后进入下一步。 选择对象类型 在对象类型列表中只勾选“文字”和“多行文字”。（若需统计块内文字或属性文字，可额外勾选相应类型） 选择特性 只勾选“内容”（TextString / Content），其余特性（如图层、位置）可不选，以保持数据纯净。 优化输出 推荐不合并相同行，保留每条原始记录，以便后续在Excel中灵活透视。 输出到外部文件 选择输出格式为XLS或CSV，指定保存路径，完成导出。 Excel中统计 打开导出的文件，选中“内容”列。 插入“数据透视表”，将“内容”拖入“行”区域和“值”区域（计数）。 立即得到所有不同文字及其出现次数，无论多少种，整个过程只需几分钟。 三、方法二：专用LISP插件（生成图纸内表格） 如果需要直接在CAD图形中生成表格（TABLE对象），并且希望以后反复快速运行，可以加载以下AutoLISP程序。该程序会： 让用户框选（或全选）文字对象 统计每种文字内容的出现次数 按内容升序排序 在当前图形中创建一个两列表格：“文字内容”和“数量” 完整LISP代码 将以下代码保存为 TextCountTable.lsp（编码ANSI）： ;;; ============================================================ ;;; 文字内容统计并生成 AutoCAD 表格 (TABLE) ;;; 命令: TCT ;;; 功能: 统计所选文字对象(单行/多行)的内容，生成统计表格 ;;; ============================================================ (defun c:TCT (/ ss i ent txt lst pair item pt rowCnt tblObj colWidth1 colWidth2 rowHeight tblHeight) (princ "\n请选择需要统计的文字对象 (可框选或直接回车选择全部): ") ;; 选择文字对象（支持单行文字、多行文字） (setq ss (ssget '((0 . "*TEXT")))) (if (null ss) (progn (alert "没有选中任何文字对象，程序退出。") (exit) ) ) ;; 统计文字内容 (setq i 0) (while (< i (sslength ss)) (setq ent (entget (ssname ss i)) txt (cdr (assoc 1 ent)) ) ;; 忽略空字符串 (if (and txt (/= txt "")) (if (setq pair (assoc txt lst)) (setq lst (subst (cons txt (1+ (cdr pair))) pair lst)) (setq lst (cons (cons txt 1) lst)) ) ) (setq i (1+ i)) ) ;; 检查统计结果 (if (null lst) (progn (alert "所选文字中没有有效内容。") (exit) ) ) ;; 按文字内容排序 (升序) (setq lst (vl-sort lst '(lambda (a b) (< (car a) (car b))))…

火山引擎全站加速证书自动更新脚本实践
type: item
date: 2026-05-14T14:07:00+08:00
description: 背景 火山云全站加速配置SSL证书，手动上传并绑定证书的过程虽然简单，但多域名重复操作既繁琐又容易出错。于是决定写一个自动化脚本，利用火山引擎 CLI 工具（ve）完成证书上传与绑定的全流程。 工具选型与思路 火山引擎提供了统一的命令行工具 ve，支持 CDN、DCDN 等多个服务。一开始查看了 DCDN 相关的命令： ve dcdn CreateCertBind --help 发现 CreateCertBind 需要一个已存在于证书中心的 CertId，而不能直接传递证书文件内容。这意味着必须先将证书上传到火山引擎的证书中心，拿到 CertId 后再绑定到 DCDN 域名。 庆幸的是，ve cdn AddCertificate 命令可以将证书上传至火山引擎证书中心（设置 Source 为 volc_cert_center），并且返回的 CertId 可以在 DCDN 中直接使用。这样一来，流程就清晰了： 读取本地证书文件（fullchain.pem 和 privkey.pem） 调用 AddCertificate 上传，获取 CertId（若证书已存在则复用） 调用 CreateCertBind 将证书绑定到 DCDN 域名 遇到的两个坑 1. 通配符域名不被 DCDN 接受 一开始脚本中的 DomainNames 写成了 ["example.com", "*.example.com"]，执行后报错： DomainNotExist: Domain Name [*.example.com] does not exist 通过 ve dcdn ListDomainConfig 查看实际已添加的加速域名，发现 DCDN 控制台并不接受 *.example.com 这样的通配符形式。实际存在的域名是 example.com、sub.example.com 以及一个以点开头的特殊域名 .example.com（可能是历史原因或内部标识）。因此最终使用的域名列表需要与实际配置完全一致。 2. 错误响应的解析路径不一致 ve cdn AddCertificate 的错误信息位于 .ResponseMetadata.Error，而 ve dcdn CreateCertBind 的错误信息却直接在根节点 .Error 中。最初脚本只检查了 .ResponseMetadata.Error，导致 CreateCertBind 明明失败了，脚本却输出“绑定成功”。修正后同时检查两个可能的路径。 最终脚本 以下脚本实现了自动上传证书并绑定到 DCDN 域名。使用时请根据实际情况修改证书存放目录、日志目录以及目标域名列表。 #!/bin/bash #set -xv log_date() { date '+[%Y/%m/%d %H:%M:%S]' } # 配置 - 请按实际修改 CERT_STORE_DIR="/path/to/your/certificates" LOG_DIR="/path/to/log" mkdir -p "$LOG_DIR" exec > >(tee -a "$LOG_DIR/cert.log") 2>&1 echo "$(log_date) 脚本开始执行" # 加载证书内容 cert_content=$(cat "$CERT_STORE_DIR/fullchain.pem") key_content=$(cat "$CERT_STORE_DIR/privkey.pem") echo "$(log_date) 证书内容长度: ${#cert_content}" echo "$(log_date) 私钥内容长度: ${#key_content}" # 1. 上传证书到火山引擎证书中心 upload_json_request() { jq -n \ --arg cert "$cert_content" \ --arg key "$key_content" \ '{ "Source": "volc_cert_center", "CertType": "server_cert", "Certificate": $cert, "PrivateKey": $key }' } echo "$(log_date) 正在上传证书到火山引擎证书中心..." response=$(ve cdn AddCertificate --body "$(upload_json_request)") if echo "$response" | jq -e '.ResponseMetadata.Error' > /dev/null 2>&1; then error_code=$(echo "$response" | jq -r '.ResponseMetadata.…

CAD自定义命令:一键拉伸对齐
type: item
date: 2026-05-10T00:55:00+08:00
description: 批量改变的矩形上下方向的高度（竖向长度），用一条水平线作为目标，将多个矩形的一侧（上边或下边）拉伸到那条线上，同时保持矩形的宽度和另一侧边位置不变。 一个一键批量拉伸矩形高度的 LISP 程序，支持选择水平参考线，并将矩形上边（或下边）对齐到该线。 ✅ 以线为界，批量调整矩形高度（竖向拉伸） 程序功能 选择一条水平直线（程序自动获取其 Y 坐标）。 选择多个矩形（轴对齐矩形，边平行于坐标轴）。 选择拉伸模式： 上边对齐到线（底部固定，顶部拉伸到参考线） 下边对齐到线（顶部固定，底部拉伸到参考线） 矩形宽度和另一侧位置完全不变。 代码（直接粘贴到 CAD 命令行） (defun C:StretchHeightToLine ( / lineEnt lineY ss i ent pts minX maxX minY maxY newMinY newMaxY mode newPts newEnt) (setq lineEnt (car (entsel "\n选择水平参考线（直线）："))) (if (not lineEnt) (progn (prompt "\n未选择直线") (exit))) (setq lineY (cadr (vlax-curve-getStartPoint lineEnt))) ; 取直线的 Y 坐标 (setq ss (ssget '((0 . "LWPOLYLINE") (70 . 1)))) ; 只选闭合多段线 (if (not ss) (progn (prompt "\n未选择任何矩形") (exit))) (initget "Top Bottom") (setq mode (getkword "\n对齐方式 [上边对齐到线(Top)/下边对齐到线(Bottom)]: ")) (if (not mode) (exit)) (setq i 0) (repeat (sslength ss) (setq ent (ssname ss i)) (setq pts (mapcar 'cdr (vl-remove-if '(lambda (x) (/= (car x) 10)) (entget ent)))) (if (>= (length pts) 4) (progn (setq minX (apply 'min (mapcar 'car pts))) (setq maxX (apply 'max (mapcar 'car pts))) (setq minY (apply 'min (mapcar 'cadr pts))) (setq maxY (apply 'max (mapcar 'cadr pts))) (cond ((= mode "Top") ;; 顶部对齐到线：底边不变，顶边改为 lineY (setq newMinY minY) (setq newMaxY lineY) ) ((= mode "Bottom") ;; 底部对齐到线：顶边不变，底边改为 lineY (setq newMinY lineY) (setq newMaxY maxY) ) ) ;; 构建新顶点（左下 -> 右下 -> 右上 -> 左上） (setq newPts (list (list minX newMinY) (list maxX newMinY) (list maxX newMaxY) (list minX newMaxY) )) ;; 更新多段线 (setq newEnt (entget ent)) (setq newEnt (vl-remove-if '(lambda (x) (= (car x) 10)) newEnt)) (foreach p newPts (setq newEnt (append newEnt (list (cons 10 p)))) ) (entmod newEnt) ) ) (setq i (1+ i)) ) (prompt (strcat "\n已修改 " (itoa i) " 个矩形，参考线 Y = " (rtos lineY 2 2))) (princ) ) 操作步骤 加载代码：在 CAD 命令行粘贴全部代码，按回车。 如果提示“函数已加载”，则可直接使用。 如果粘贴不成功（比如多行提示），请先输入 VLIDE 打开编辑器，新建文件粘贴，保存为 .lsp 文件，再用 APPLOAD 加载。 执行命令：输入 StretchHeightToLine 回车。 选择参考线：单击一条水平直线（多段线的直线段也可，程序会自动取它的 Y 坐标）。 选择矩形：框选所有要修改的矩形，按回车。 选择对齐方式： 输入 T 选择「上边对齐到线」 → 矩形底部固定，顶部拉伸到参考线。 输入 B 选择「下边对齐…

Microsoft ToDo月视图看板
type: item
date: 2026-04-18T23:20:00+08:00
description: 市面上的任务管理工具，但凡带个日历视图、数据导出功能，不是按月收费就是按年订阅。自己动手，用 Microsoft Graph API 一小时就能搭一个专属的 To Do 看板——月视图、周视图、CSV 导出，全部免费，数据还留在自己手里。 为什么做这个？ Microsoft To Do 本身非常轻量，但缺少一个直观的月视图/周视图。你只能按列表查看任务，无法一眼看出哪天有哪些事、哪些已经完成。更别说导出数据做周报、月报了。 市面上的“日历+任务”类应用，像 Todoist、TickTick 的高级版确实提供日历视图，但都放在了付费墙后面。对于个人开发者或者小团队，为了一个视图功能去订阅并不划算。 于是我花了一个晚上，基于 Microsoft Graph API 和纯前端技术，写了一个完全免费的 To Do 看板。它支持： 月视图（周一为起始，符合国内习惯） 周视图（显示 ISO 周数，每天的任务完成比例） 一键导出 CSV（按时间排序，包含创建时间、完成时间、备注等字段） 切换账号、实时统计（全部任务/已完成数量） 而且个人 Microsoft 账号（outlook.com、hotmail.com）和 E5 订阅账号都可以直接使用。 技术选型 需求 技术方案 登录与授权 MSAL.js (Microsoft Authentication Library) 获取任务数据 Microsoft Graph API (/me/todo/lists 和 /tasks) 日历渲染 手写 HTML/CSS/JS（轻量，不依赖第三方库） 数据导出 动态生成 CSV 文件，浏览器下载 性能优化 并行请求 + 限流控制 之所以不直接用 FullCalendar 等现成库，是为了完全控制 UI 样式，并且避免额外的依赖加载。 核心功能实现 1. 登录与权限 使用 MSAL.js 实现 OAuth 2.0 授权码流（PKCE）。只需要在 Azure AD 中注册一个应用，配置重定向 URI 为 SPA 类型，然后请求 Tasks.Read 和 User.Read 权限即可。 const msalConfig = { auth: { clientId: '你的客户端ID', authority: 'https://login.microsoftonline.com/common', redirectUri: window.location.origin } }; const loginRequest = { scopes: ['Tasks.Read', 'User.Read'] }; 个人账号注意：Azure 应用注册时，必须选择“任何组织目录中的帐户和个人 Microsoft 帐户”，否则个人账号无法登录。 2. 获取所有任务 Microsoft To Do 的数据模型是：用户有多个任务列表，每个列表下有多个任务。所以需要两步： 请求 GET /me/todo/lists 获取所有列表。 对每个列表请求 GET /me/todo/lists/{id}/tasks?$top=500 获取其中的任务。 性能瓶颈：如果列表较多（比如十几个），串行请求会非常慢（每个请求约 200~300ms，总耗时 = 列表数 × 单次耗时）。例如 16 个列表，串行需要 5 秒左右。 3. 并行请求 + 限流处理 为了提速，我们使用 Promise.all 并发请求，但并发量过大会触发 Microsoft Graph 的限流（HTTP 429）。解决方案是限制并发数，同时加入简单的重试机制。 // 限制同时最多 3 个请求 async function asyncPool(poolLimit, array, iteratorFn) { // 实现略 } const fetchListTasks = async (list) => { // 遇到 429 则等待 Retry-After 秒后重试 }; const results = await asyncPool(3, lists, fetchListTasks); 实测并发数 3 时，16 个列表的加载时间从 5 秒降到 1.2 秒左右，且不会触发限流。 4. 月视图实现（周一为起始） 纯手写一个日历表格，关键点在于计算每月第一天是周几，并转换为周一为起始的索引。 let startWeekday = firstDay.getDay(); // 0=周日 startWeekday = (startWeekday === 0 ? 6 : startWeekday - 1); // 周一=0, 周日=6 然后生成 42 个格子（6 行×7 列），根据日期填充任务。每个格子内显示当天任务列表，按“进行中 → 已完成”排序。 5…

HomeAssistant配置-公共事业仪表
type: item
date: 2026-04-14T08:35:00+08:00
description: 在 Home Assistant (HA) 中，Utility Meter（公共事业仪表）是一个用于累计计量的辅助集成组件。它的核心作用是将一个随时间变化的数值（如电量消耗、燃气流量、用水量）按照指定周期（小时、日、月、年）进行累加、重置并存储历史数据，最终生成类似于电表、水表的读数。 简单来说：如果你的传感器提供的是瞬时功率（W，瓦），Utility Meter 能帮你算出总用电量（kWh，千瓦时）；如果你的传感器提供的是水流的瞬时流量（L/min，升/分钟），它能帮你算出总用水量（m³，立方米）。 1. 核心概念与工作原理 源实体 (Source Entity)：需要被累加的传感器实体，通常是瞬时速率（W、L/min、m³/h）或已经累加但需要周期性重置的值。 周期 (Cycle)：重置计数的间隔。可选：hourly、daily、weekly、monthly、yearly。 计量类型 (Meter Type)： accumulating：适用于表计本身读数一直在增长的设备（如智能电表读数）。Utility Meter 会计算差值（本期读数 - 上期读数）。 incremental：适用于传感器每次上报的是增量值（如 5 kWh）。直接累加这个值。 gauge：直接将当前值作为统计值，不累加，不推荐用于能耗统计。 计量偏移 (Meter Offset)：定义周期的起点。例如，想让“月”周期从每月 5 号开始，而不是 1 号。 2. 典型使用场景 场景 源实体 (Source) Utility Meter 输出 典型周期 家庭总用电 智能电表读数 (kWh, accumulating) 今日用电量、本月用电量 日、月、年 太阳能发电 逆变器发电量 (kWh, incremental) 今日发电量、本月发电量 日、月 燃气消耗 燃气流量计 (m³/h) 或 累加表 本月燃气用量 月 电动汽车充电 充电桩功率传感器 (W) 每次充电电量 按需手动重置 区域空调能耗 空调功率传感器 (W) 客厅今日空调用电 日 3. 如何配置 Utility Meter 有两种主要配置方法： 方法一：通过 UI 配置（推荐新手） 进入 设置 → 设备与服务 → 辅助元素。 点击右下角 添加辅助元素 → 选择 累计计量表 (Utility Meter)。 填写参数： 名称：Electricity Daily，Water Monthly 等。 计量对象 (Meter Type)：选择 accumulating（如果你的电表直接给读数）。 源实体 (Source Entity)：选择你的传感器实体（如 sensor.electricity_meter_reading）。 重置周期 (Reset Cycle)：选择 monthly。 周期性偏移 (Periodic offset)：一般保持默认（月周期从每月 1 号开始）。 点击 创建。系统会自动生成一个新的 sensor.xxx 实体。 方法二：通过 configuration.yaml 配置（更灵活） utility_meter: # 示例：日用电量 daily_electricity: source: sensor.electricity_meter_reading # 源实体 cycle: daily # 日周期 meter_type: accumulating # 累加型表计 # 示例：月用电量（基于日累计表） monthly_electricity: source: sensor.daily_electricity # 可以嵌套，将日表作为源 cycle: monthly meter_type: incremental # 因为源已重置，这里是增量型 # 示例：带偏移的月用水量（从每月15号开始新周期） monthly_water_offset: source: sensor.water_meter cycle: monthly offset: 14 # 15号开始（0-based索引？实际测试：offset: 14 表示周期从每月15日0点开始） meter_type: accumulating 配置后需要重启 HA 或重载核心配置。 4. 在能源仪表板中使用 Utility Meter 最常见的使用场景是作为 HA 官方能源仪表板 (Energy Dashboard) 的数据源。 进入 设置 → 仪表板 → 能源。 在 能源配置 中，选择 用电量 → 添加耗能设备。 在“使用实体”中选择你创建的 Utility Meter 实体（如 sensor.daily_electricity）。 关键点：你需要将 Utility Meter 的源实体（智能电表读数）也添加为电网输入的实体。HA 会自动…

末日生存指南-药品篇
type: item
date: 2026-04-03T14:36:00+08:00
description: 针对末日/战争场景下的家庭药箱，我按优先级和功能分类，给你一份可直接照单准备的清单。所有药品请存放在阴凉、干燥、避光、儿童够不到的地方，并每半年检查一次有效期。 一、外伤处理（最常用，战斗或劳作难免受伤） 物品 数量 用途与备注 碘伏棉球或碘伏液+棉签 1瓶+1包 清洗伤口，比酒精刺激性小 75%医用酒精 1小瓶 消毒工具、针头，不要直接洗大伤口 无菌纱布块 2包 覆盖伤口、止血 绷带卷 3卷 固定纱布，可做三角巾 弹性绷带 1卷 扭伤固定关节 医用胶带 1卷 固定纱布 创可贴（各种尺寸） 20片 小划伤 止血带（或军用橡皮管） 1条 大出血时保命用，需学会使用 云南白药粉（含保险子） 1瓶 止血、化瘀，对刀伤有效 无菌缝合针线（或一次性皮肤吻合器） 1套 深长伤口临时缝合，平时用针线煮沸消毒可替代 镊子+小剪刀 1套 挑刺、剪坏死组织 二、抗感染药物（没有抗生素，小伤可能致命） 药品 规格 用途 阿莫西林（青霉素类） 2盒 呼吸道、皮肤软组织感染（需不过敏） 头孢克肟或头孢拉定 2盒 较严重感染，与阿莫西林二选一备 左氧氟沙星片 1盒 肠道感染、尿路感染 甲硝唑片 2瓶 牙周炎、阑尾炎预防、厌氧菌感染 红霉素软膏 2支 皮肤脓疱、小烧伤 莫匹罗星软膏（百多邦） 1支 更有效对付金黄色葡萄球菌 注意：抗生素属处方药，现在合法途径难大量备，可托人从乡镇卫生院少量购买，或备鱼腥草、蒲公英干品煮水作为替代（效果弱但有总比没有强）。 三、消化道用药（脏水、变质食物易引起腹泻） 药品 数量 用途 口服补液盐（Ⅲ） 10袋 最重要，防脱水，可自制（1升水+6勺白糖+半勺盐） 蒙脱石散（思密达） 2盒 物理止泻，吸附毒素 黄连素片 2瓶 细菌性肠炎 藿香正气水（不含酒精型） 2盒 中暑、湿滞肠胃、恶心呕吐 健胃消食片 1盒 吃粗粮过多消化不良 开塞露 5支 严重便秘（长期吃干粮易便秘） 四、呼吸道与退烧镇痛 药品 数量 用途 布洛芬片（或胶囊） 2瓶 退烧、止痛（头痛、关节痛、痛经） 对乙酰氨基酚（扑热息痛） 1瓶 退烧（与布洛芬交替使用） 复方氨酚烷胺（感康） 2盒 普通感冒症状 氨溴索片（沐舒坦） 1盒 化痰 急支糖浆或川贝枇杷膏 2瓶 止咳（甜，可补充热量） 氯苯那敏（扑尔敏） 1瓶 过敏、流涕、助眠 五、外用止痛与皮肤 物品 数量 用途 双氯芬酸二乙胺乳胶剂（扶他林） 1支 关节扭伤、肌肉痛 风油精或清凉油 5盒 蚊虫叮咬、提神、防中暑 炉甘石洗剂 1瓶 湿疹、荨麻疹、痱子 高锰酸钾片（外用） 10片 化水清洗感染伤口、坐浴、消毒果蔬（极稀） 凡士林 1罐 防皮肤干裂、润滑、轻度烫伤保护 六、特殊场景与工具 物品 数量 用途 一次性注射器（2ml、5ml） 各5支 临时冲洗伤口、喂药（不带针头） 针灸针或三棱针 1套 放血急救（中风、高热惊厥），需懂穴位 电子体温计 1支 不推荐水银，易碎 急救手册（小本） 1本 关键时刻查阅 酒精棉片 50片 快速消毒 医用橡胶手套 10副 防交叉感染 七、长期保存与替代方案（农村特色） 石灰：半斤生石灰块，密封保存。加水可发热（热敷）、可消毒厕所。 食盐：2斤粗盐，配水成盐水（0.9%）可洗伤口、洗鼻。 艾绒：干艾叶搓绒，卷成艾条可艾灸（止痛、温经）、也可熏蚊。 大蒜：捣碎外敷治痈肿，内服抗肠道菌（生吃2瓣/日）。 高度白酒（60度以上）：半斤，替代酒精消毒工具。 八、存放建议 用一个防水的塑料收纳箱（红色十字标记），放在卧室角落不碍事处。 附一张手写清单，注明每种药的用法、用量、失效期。 每3个月检查一次，补充消耗品。 最后提醒：不要盲目囤积过期药品，以上清单总花费约200~300元（不含抗生素，抗生素需另想办法）。如果完全买不到抗生素，多备金银花、连翘、黄连等草药干品，煮水内服或外洗。保持伤口清洁比抗生素更重要——干净的水+碘伏+无菌纱布能解决大部分小伤。 现在就可以开始收集一个鞋盒大小的“基础药包”，从碘伏、纱布、布洛芬、蒙脱石散、口服补液盐这五样起步。

末日生存指南-汇总篇
type: item
date: 2026-04-03T14:34:00+08:00
description: 末日生存指南：一份让你活下来的实操手册 不张扬、不浪费、不放弃 —— 农村生存的十二字真言 当城市陷入混乱，当电网崩溃、通讯中断、秩序瓦解，农村老家将是你最坚实的避风港。这里有一望无际的庄稼地、压不垮的水井、砖墙土院和世代传承的生存智慧。但光有土地还不够，你需要一份真正接地气、可操作的生存指南。本文整合了电力、水源、医疗、通信、防御等所有关键环节，全部基于农村的实际条件，不搞花架子，只讲保命干货。 一、核心原则：为什么农村比城市更安全？ 自给自足：粮食、水源、燃料就在身边 人口稀疏：降低冲突和感染风险 隐蔽性强：独门独院，易于伪装 工具丰富：农具可攻可守，柴火垛能藏人 但也要面对现实挑战：电力中断、水泵停转、医疗资源匮乏、通讯孤岛。下面我们逐项破解。 二、家庭药箱：没有医院，你就是医生 在末日，一场腹泻或一处伤口感染就可能致命。按以下清单准备，总花费约200-300元（抗生素除外）。 外伤处理（最常用） 碘伏棉球、75%酒精、无菌纱布、绷带、医用胶带 创可贴、止血带、云南白药粉（含保险子） 无菌缝合针线（或普通针线煮沸消毒替代） 镊子、小剪刀 抗感染药物（关键） 阿莫西林、头孢拉定、左氧氟沙星、甲硝唑 红霉素软膏、莫匹罗星软膏（百多邦） 备选草药：蒲公英、鱼腥草干品煮水 消化道用药（脏水易致腹泻） 口服补液盐Ⅲ（最重要，防脱水） 蒙脱石散、黄连素、藿香正气水（无酒精型） 健胃消食片、开塞露 退烧镇痛与呼吸 布洛芬、对乙酰氨基酚（可交替使用） 复方氨酚烷胺（感康）、氨溴索（化痰） 氯苯那敏（扑尔敏，抗过敏/助眠） 外用皮肤与工具 扶他林（关节扭伤）、风油精、炉甘石洗剂 高锰酸钾片（外用消毒）、凡士林 一次性注射器（冲洗伤口）、体温计、急救手册 农村特色替代品 生石灰：消毒厕所、加水发热热敷 粗盐：配成0.9%盐水洗伤口 艾绒：艾灸止痛、熏蚊 高度白酒（60度以上）：替代酒精消毒 存放：防水收纳箱，标注用法和有效期，每3个月检查一次。 三、电力中断：没有国家电网，你还有太阳和双手 农村常见“细水井”（管径同普通水管），电力中断后水泵停转、冰箱失效、夜晚漆黑。解决方案分层如下： 3.1 照明 蜡烛：备50根以上，铁盒存放防软 油灯：碗+食用油+棉绳（鞋带），一碗油≈20小时 手电/头灯：用5号电池的LED款，备20节电池 火把：柴油+破布缠棍（慎用，防火灾） 3.2 食物保存（冰箱停摆） 地窖/红薯窖：恒温10-15℃，存放萝卜、白菜、土豆 井水吊篮：食物吊入井内离水面半米，鲜肉可存1-2天 长期无电方法：晒干（豆角、茄子）、盐腌（酸菜、腊肉）、油封（肉块炸后浸猪油）、粮食装塑料袋扎紧放入陶缸盖草木灰 3.3 水源（细水井解决方案） 你的细水井（小口径塑料管井）可以配合直流光伏深井潜水泵使用。关键步骤： 选泵：测量井管内径，选择3英寸或4英寸直流潜水泵（12V-24V），功率150W-500W（根据井深和用水量） 配光伏板：功率高出水泵20%-30%，推荐单晶硅板 不必须配电池：白天抽水存入高位水塔，靠重力实现24小时用水，比电池更可靠 预算：基础抽水套装约1500-4000元；含蓄电池和逆变器约1-3万元 购买渠道：淘宝/1688搜索“直流光伏深井泵 套装”，或咨询县城光伏网点 储水容器：所有大可乐瓶、油桶、浴缸、太阳能热水器（约150升）都可临时储水。 3.4 取暖与烹饪 柴火灶：备足玉米芯、树枝、秸秆 火盆：铁盆烧木炭，注意通风（防一氧化碳） 土暖气：烟道盘成炕，睡人 放大镜点火：晴天可点燃干草，省打火机 3.5 长期无电技巧 太阳能充电：旧光伏板+汽车电瓶+逆变器，可带LED灯和手机 手摇发电机：旧自行车摩擦带动12V电机 盐水电池：铜片+锌片插入盐水，串联得1-2V，点LED 蒸发冷却罐：两陶罐套叠中间填湿沙，内罐降温10℃ 手摇石磨：磨小麦、玉米 四、通信：当手机变成砖头 移动基站和宽带在极端情况下会迅速瘫痪。你的通信方案必须不依赖公共设施。 4.1 必备设备金字塔 层级 设备 作用 预算 基础 全波段短波收音机（手摇充电） 接收外界信息，生命线 200-500元 基础 免执照公众对讲机（人手一台） 团队内部1-5公里通信 200-800元/对 进阶 业余电台（UV段手台） 数十公里通信，需考取执照 500-2000元 进阶 短波电台 数百至数千公里通联 3000-8000元 核心 北斗短报文终端/卫星电话 地面网络完全崩溃时求救 数千至万元 4.2 重要提醒 普通对讲机不能当收音机用（频段不同），但少数型号集成FM收音机 所有设备提前备好电池、充电线，利用光伏板供电 和家人约定“失联后的家庭通信计划”：对讲机频道、汇合地点、卫星求救暗号 4.3 信息获取 收音机调频FM弱时，用中波MW 村里大喇叭（蓄电池）也可听通知 …

FreeCAD 批量获取Step文件各零件包围盒尺寸
type: item
date: 2026-04-03T00:26:00+08:00
description: 使其能够自动识别 STEP 文件中的每个独立部件（即导入后的每个对象），为每个部件单独计算其边界框尺寸和体积，并生成序号（同一文件内从 1 开始递增）。输出 CSV 文件在原有列（文件名、长、宽、高、三维尺寸、体积）前增加一列“序号”，其他格式处理（如尺寸整数化、保留两位小数）保持不变。 修改后的完整脚本 BatchStepBBox # -*- coding: utf-8 -*- import os import csv import FreeCAD import Part from PySide2 import QtWidgets def select_folder(): """弹出文件夹选择对话框，返回所选文件夹路径""" folder = QtWidgets.QFileDialog.getExistingDirectory( None, "选择包含 STEP 文件的文件夹", "", QtWidgets.QFileDialog.ShowDirsOnly ) return folder def format_dimension(value): """ 格式化尺寸值：如果是整数则返回整数形式，否则保留两位小数 """ # 判断是否为整数（容差1e-6） if abs(value - round(value)) < 1e-6: return str(int(round(value))) else: return f"{value:.2f}" def process_step_files(folder_path, output_csv): """ 批量处理文件夹内的STEP文件，识别每个独立部件，提取尺寸并导出为CSV """ extensions = ('.step', '.stp') results = [] for filename in os.listdir(folder_path): if filename.lower().endswith(extensions): file_path = os.path.join(folder_path, filename) print(f"正在处理: {filename}") try: doc = FreeCAD.newDocument("TempDoc") Part.insert(file_path, doc.Name) # 收集所有具有形状的对象 shapes = [obj for obj in doc.Objects if hasattr(obj, 'Shape') and obj.Shape] if not shapes: print(f"警告: {filename} 没有有效形状") FreeCAD.closeDocument(doc.Name) continue # 为每个对象单独处理 for idx, obj in enumerate(shapes, start=1): bbox = obj.Shape.BoundBox # 获取三边长度并排序（长、宽、高） lengths = [bbox.XLength, bbox.YLength, bbox.ZLength] lengths.sort(reverse=True) length, width, height = lengths volume = length * width * height # 格式化 length_str = format_dimension(length) width_str = format_dimension(width) height_str = format_dimension(height) dimension_str = f"{length_str}*{width_str}*{height_str}" volume_str = format_dimension(volume) results.append([ filename, idx, # 新增序号 length_str, width_str, height_str, dimension_str, volume_str ]) FreeCAD.closeDocument(doc.Name) except Exception as e: print(f"处理 {filename} 时出错: {e}") # 写入CSV文件（表头增加“序号”列） with open(output_csv, 'w', newline='', encoding='utf-8') as f: writer = csv.writer(f) writer.writerow(['文件名', '序号', '长', '宽', '高', '三维尺寸', '体积(mm³)'…

CAD自定义块属性
type: item
date: 2026-04-02T08:17:00+08:00
description: 在AutoCAD中，为图块添加属性（即可变的文字，如编号、型号、尺寸等）主要有两种情况：创建新块时加入属性，以及为现有块添加属性。 以下是具体操作步骤： 一、 创建新块时加入属性 如果正在制作一个需要带文字标注的块（例如粗糙度符号、标高、门窗编号），建议在创建块之前先定义属性。 定义属性 先绘制好块的图形部分。 输入命令 ATTDEF （或点击菜单：绘图 → 块 → 定义属性）。 在弹出的对话框中设置： 标记：这是属性的名称（例如“编号”、“长度”）。（必填） 提示：插入块时提示用户输入的内容（例如“请输入设备编号：”）。如果不填，默认显示“标记”。 默认：如果不修改，默认显示的文字。 文字设置：设置文字高度、对齐方式等。 点击“确定”，将属性文字放置在图形旁边的合适位置。 创建块 输入命令 BLOCK （或 B）。 在“选择对象”时，框选图形和刚才定义的属性文字。 指定插入点后，点击确定。 注意：在“块定义”对话框中，不要勾选“分解”，否则属性会失效。 二、 为现有块添加属性 如果图块已经存在，想要给它增加新的属性（例如给一个已有的椅子图块增加“型号”属性），需要使用 块编辑器（BEDIT）。 进入块编辑器 输入命令 BEDIT （或 BE）。 在弹出的对话框中选择你要修改的那个块，点击“确定”。 添加属性 进入块编辑器界面后，输入命令 ATTDEF 定义属性。 设置好“标记”、“提示”和“默认值”等。 将属性文字放置在块图形中的合适位置。 保存并同步 点击工具栏上的 “关闭块编辑器”。 选择“保存更改”。 关键步骤：为了让已经插入图纸中的旧块也显示出新属性，必须输入命令 ATTSYNC （属性同步），选择该块并回车。如果不做这一步，旧块不会自动获得新属性。 三、 插入块并填写/编辑属性 插入时填写：输入 INSERT 选择该块，在图纸中点击插入点后，会自动弹出对话框（或命令行提示），输入对应的属性值即可。 插入后修改： 双击带有属性的块，会弹出“增强属性编辑器”，可以在这里修改属性值。 选中块，按 Ctrl + 1 打开特性面板，在“属性”栏中也可以修改。 其他相关设置（在同一对话框中） 文字选项：可以提前设置好文字的样式、高度、对齐方式。高度建议根据块的实际比例设置，例如在 1:1 图纸中，属性文字高度设为 2.5 或 3 比较常用。 预设（Preset）：勾选后，插入块时不会提示，直接使用默认值，适合固定内容（如材料名称）。 不可见（Invisible）：勾选后属性在图纸中隐藏，但数据仍然存在，可用于存储不显示的信息（如设备编号数据库）。 验证（Verify）：勾选后插入块时会要求用户确认输入的值，较少使用。 固定（Constant）：勾选后属性值不能修改，相当于固定的文字。 常见提示 属性不显示/显示为标签？ 如果插入块后显示的是“标记”里的内容（如“编号”）而不是你输入的值，输入命令 ATTMODE，将值设置为 1 或 2，然后输入 REGEN 重生成模型。 属性文字太大或太小？ 在定义属性（ATTDEF）时预设的文字高度要合适。如果是现有块，可以用 BEDIT 进入块编辑器调整属性文字的高度。 总结建议 标记：用英文标识，无空格，用于后台识别。 提示：用清晰的中文问句，指导填写。 默认值：填入最常用的值，减少重复输入。 设置好这三个字段，再配合块编辑器和属性同步（ATTSYNC），就能让图块变得既规范又高效。

Linux 查询开机以来磁盘写入量
type: item
date: 2026-03-17T19:41:00+08:00
description: 以下是直接获取写入量的命令（使用内核统计，最准确）： eMMC 总写入量 awk '{printf "eMMC 总写入量: %.2f GB\n", $7*512/1024/1024/1024}' /sys/block/mmcblk0/stat SATA SSD 总写入量（假设设备为 /dev/sda） awk '{printf "SATA 总写入量: %.2f GB\n", $7*512/1024/1024/1024}' /sys/block/sda/stat 如果 SATA 设备名不是 sda（例如 sdb），请用 lsblk 确认挂载 /volume 的设备并替换。