iotStudio轻量级工业物联网平台实战:Modbus设备快速接入与产线看板落地
简介iotStudio是一款面向工业物联网开发者的轻量级开源管理后台专为降低技术门槛而设计适用于中小型制造企业、IoT初创团队及低代码爱好者解决传统物联网平台部署复杂、二次开发成本高、可视化能力弱等痛点。资源包共612个文件以259个Vue组件文件和219个JS逻辑脚本为核心支撑全低代码框架、动态菜单与amis表单辅以30个PNG图标、15个JSON配置、12个YML服务定义及Konva/Three.js相关资源完整实现2D大屏与3D设备可视化整体压缩包仅10.38MB结构清晰、开箱即用。已有227人学习下载读者可直接获取一套融合边缘计算接入、权限驱动动态路由、响应式表单引擎与WebGL三维渲染的工业级IoT后台源码含完整构建流程、预设主题样式如gauge.css、waves.css及Git工程规范文件.editorconfig、pre-commit等便于快速二次开发与本地部署。1. iotStudio 轻量级工业物联网管理后台不是“又一个IoT平台”而是产线老师傅能当天上手的设备看板你刚接手一家做PLC控制柜的中型制造厂车间里散落着37台西门子S7-1200、15台汇川H3U和8台研华ADAM-6000系列采集模块——没有统一协议没有历史数据沉淀更没人愿意教你怎么连上那台贴着“禁止触碰”胶带的旧数控机床。这时候领导甩来一句话“听说有个叫iotStudio的轻量级工业物联网管理后台三天搭好别用阿里云IoT或ThingsBoard那种‘巨无霸’。”这不是在选一个PaaS平台而是在找一套能绕过IT部门审批、不用写Java后端、不依赖K8s运维、但又能真实看到温度曲线异常、停机超时告警、设备OEE实时计算的现场工具。iotStudio 的核心价值恰恰卡在“轻量级”三个字上它不追求百万设备接入但要求你在Windows笔记本上双击启动、5分钟内把一台Modbus RTU温控器的数据刷进网页表格它不提供AI预测性维护模型但必须让班组长点两下就能导出昨天夜班的故障TOP3清单。本文讲的就是怎么用它真正落地——不是跑通Demo而是让产线工人主动打开浏览器查数据。2. 为什么是 iotStudio从协议兼容性、部署成本到角色权限的真实取舍2.1 协议支持不是“列表越长越好”而是“产线现场有没有人会配”iotStudio 对工业协议的支持逻辑很务实不堆砌OPC UA、MQTT、CoAP等名词而是聚焦三类真实场景中无需额外网关、不改原有PLC程序、不依赖厂商SDK就能直连的协议。我们实测过以下组合协议类型典型设备示例连接方式是否需额外硬件现场配置耗时熟练工Modbus TCP西门子S7-1200开启TCP、汇川H3U网口模式直连IP端口寄存器地址否≤3分钟填4个字段Modbus RTU over TCP研华ADAM-6000串口转以太网模式IP端口串口参数波特率/校验位是需ADAM-6050等串口服务器≤5分钟含串口服务器配置HTTP API自定义旧数控机床配套的Web服务返回JSONURLHeader解析规则XPath/JSONPath否≤8分钟调试返回格式提示iotStudio 不支持纯串口RS485/RS232直连PC——这点必须提前确认。如果你的设备只有物理串口且没配串口服务器要么加硬件要么用另一台树莓派跑个ser2net桥接别指望软件“魔法解决”。我们放弃过两个看似“先进”的协议OPC UA虽然官方文档写了支持但实际需要手动导入证书、配置安全策略、处理匿名用户权限某次在客户现场折腾2小时仍报BadCertificateUseNotAllowed最后换回Modbus TCP直连MQTT对设备端要求高需嵌入MQTT客户端而产线90%的老设备连Telnet都不开强行推MQTT等于让电工去学Python。2.2 部署方案拒绝“云原生玄学”只要一个.exe和一个config.yamliotStudio 的轻量级首先体现在部署形态上。它不提供Docker镜像官方未维护、不依赖PostgreSQL集群、不强制用Nginx反向代理——它的标准交付物就是一个压缩包解压后目录结构如下iotstudio/ ├── iotstudio.exe # Windows主程序Linux版为iotstudio ├── config.yaml # 全局配置数据库路径、端口、日志级别 ├── devices/ # 设备配置文件夹每个设备一个YAML ├── dashboards/ # 看板定义JSON格式 ├── logs/ # 运行日志 └── data/ # SQLite数据库文件默认名iotstudio.db关键事实默认使用 SQLite 存储设备元数据、告警记录、用户权限单文件数据库无安装、无服务注册、无管理员密码初始化流程Web服务端口默认8080可直接在http://localhost:8080访问登录账号密码写在config.yaml里首次启动后自动生成默认admin/admin所有设备连接参数、数据点映射、告警阈值全部通过YAML文件定义不依赖图形化向导——这意味着你可以用Git管理配置变更产线升级时直接git pull覆盖devices/目录。下面是一个真实可用的西门子S7-1200设备配置devices/s7-1200-01.yaml# devices/s7-1200-01.yaml device_id: s7-1200-01 name: 冲压线主控PLC protocol: modbus_tcp host: 192.168.1.101 port: 502 timeout: 5000 scan_interval: 2000 # 每2秒读一次 points: - point_id: motor_temp name: 主电机温度 address: 400001 # Modbus寄存器地址4xxxx格式 type: int16 scale: 0.1 # 原始值×0.1得到摄氏度 unit: ℃ - point_id: cycle_count name: 当日冲压次数 address: 400003 type: uint32 # 32位无符号整数跨2个寄存器 scale: 1 unit: 次 alarms: - alarm_id: temp_high point_id: motor_temp condition: value 85 message: 主电机温度超限当前{{value}}℃ level: critical逻辑说明address: 400001是Modbus标准地址格式对应PLC中DB1.DBW0无需换算成0-based偏移type: int16表示读取1个寄存器2字节uint32表示读取连续2个寄存器4字节iotStudio 自动处理字节序默认大端西门子S7默认一致scale: 0.1是工程单位转换避免前端JS反复计算所有图表、告警、导出都用转换后值condition: value 85支持简单表达式不支持函数调用如max()符合现场“阈值固定、逻辑清晰”的需求。注意scan_interval单位是毫秒设为2000即2秒轮询一次。若设为100100ms多数S7-1200会因响应超时断连——这是产线实测出来的血泪经验不是理论值。3. 从设备上线到看板上线三步完成真实产线数据闭环3.1 第一步让设备“活”起来——验证连接与数据点映射启动 iotStudio 后不要急着打开网页。先看控制台输出Windows双击iotstudio.exe会弹出CMD窗口INFO[0000] Starting iotStudio server... INFO[0000] Using config file: config.yaml INFO[0000] Loading devices from devices/... INFO[0001] Connected to Modbus TCP device s7-1200-01 (192.168.1.101:502) INFO[0001] Registered point: motor_temp (400001, int16) INFO[0001] Registered point: cycle_count (400003, uint32) INFO[0001] Server started on http://localhost:8080如果看到Connected to Modbus TCP device...说明协议层通了。但这不等于数据正确——常见错误是寄存器地址错一位如400001写成40001、类型错int16写成uint16导致负数乱码。此时用内置CLI工具验证# 在iotstudio根目录执行Windows .\iotstudio.exe debug read --device s7-1200-01 --point motor_temp # 输出示例 # point_id: motor_temp # raw_value: 782 # PLC原始值 # value: 78.2 # 经scale转换后值 # timestamp: 2024-06-15T09:23:41Z参数说明--device必须与YAML中device_id完全一致区分大小写--point必须与YAML中point_id一致raw_value是PLC返回的原始整数value是应用scale后的工程值——这是判断scale是否写对的唯一依据。避坑如果raw_value恒为0或-1大概率是PLC未启用Modbus TCP服务S7-1200需在TIA Portal中勾选“允许来自远程对象的PUT/GET通信”并下载如果value明显偏离实际如温度显示-273℃检查type是否应为uint16无符号而非int16有符号。3.2 第二步构建第一个生产看板——用JSON拖拽不如手写dashboardiotStudio 的看板Dashboard本质是JSON文件存于dashboards/目录。它不提供可视化拖拽编辑器官方说“为保证配置可版本化”但提供了足够直观的结构// dashboards/press-line-overview.json { dashboard_id: press-line-overview, name: 冲压线实时看板, layout: grid, // 支持 grid / flex widgets: [ { widget_id: motor-temp-chart, type: line-chart, title: 主电机温度趋势近1小时, data_source: { device_id: s7-1200-01, point_id: motor_temp }, time_range: 1h, refresh_interval: 5000 }, { widget_id: cycle-count-gauge, type: gauge, title: 当日冲压次数, data_source: { device_id: s7-1200-01, point_id: cycle_count }, min: 0, max: 5000, unit: 次 } ] }关键参数解释time_range:1h表示图表显示最近1小时数据支持1d1天、7d7天不支持自定义时间范围选择器需改代码refresh_interval: 单位毫秒设为5000即每5秒刷新图表避免高频轮询拖垮SQLitetype: gauge是仪表盘line-chart是折线图还支持table实时数据表、status设备在线状态灯所有图表数据均从SQLite的history表读取iotStudio 自动按scan_interval写入无需额外配置时序数据库。启动后访问http://localhost:8080/#/dashboard/press-line-overview即可看到实时图表。如果图表空白检查dashboard_id是否与文件名press-line-overview.json一致device_id和point_id是否与devices/下YAML完全匹配SQLite中是否有数据用DB Browser for SQLite打开data/iotstudio.db查history表是否有s7-1200-01_motor_temp记录。3.3 第三步让班组长“真用起来”——告警推送与导出报表光看数据不够得让问题被看见。iotStudio 的告警Alarm设计极简只支持邮件推送SMTP和本地日志不支持微信/钉钉/飞书等IM推送需自行扩展Webhook。我们用企业邮箱配置如下config.yamlalarm: enabled: true smtp: host: smtp.exmail.qq.com port: 465 username: iot-alertyourcompany.com password: your_app_password # 注意用邮箱APP专用密码非登录密码 from: iot-alertyourcompany.com to: [zhangsanyourcompany.com, lisiyourcompany.com]当motor_temp超过85℃时会收到邮件【iotStudio告警】主电机温度超限当前86.3℃设备冲压线主控PLCs7-1200-01时间2024-06-15 09:35:22但更实用的是导出功能——班组长不需要登录系统只要每天上午9点自动发一份PDF报表。我们用Windows任务计划程序curl实现:: export-daily-report.bat echo off set DATESTR%date:~0,4%%date:~5,2%%date:~8,2% curl -X POST http://localhost:8080/api/v1/reports/export ^ -H Content-Type: application/json ^ -d {\dashboard_id\:\press-line-overview\,\format\:\pdf\,\start_time\:\%DATESTR%T00:00:00\,\end_time\:\%DATESTR%T23:59:59\} ^ -o D:\reports\press-line-%DATESTR%.pdf注意start_time/end_time必须是ISO 8601格式YYYY-MM-DDTHH:MM:SS且end_time不能晚于当前时间否则返回400错误。4. 避坑指南产线部署中踩过的5个真实坑省下你两天排查时间4.1 现象设备列表显示“在线”但所有数据点值为0或null原因PLC寄存器地址类型与YAML中type不匹配。例如S7-1200中温度存为REAL32位浮点但YAML写了type: int16导致读取2字节后解析失败。解决用TIA Portal在线监控确认寄存器真实数据类型iotStudio目前不支持REAL类型需在PLC中将REAL转为INT乘10后存YAML中用type: int16scale: 0.1。4.2 现象看板图表加载缓慢Chrome控制台报Failed to load resource: net::ERR_CONNECTION_REFUSED原因config.yaml中server.host设为127.0.0.1导致其他电脑无法访问默认绑定本地回环或防火墙拦截了8080端口。解决将server.host改为0.0.0.0监听所有网卡并在Windows防火墙中放行8080端口入站规则→端口→TCP 8080。4.3 现象修改devices/下YAML后重启iotStudio新设备不出现原因iotStudio 启动时只加载devices/目录下首次启动时已存在的文件后续新增文件需手动触发重载无热加载。解决重启程序或使用API强制重载curl -X POST http://localhost:8080/api/v1/devices/reload。4.4 现象导出PDF报表为空白页或只有标题无图表原因iotStudio 内置PDF生成依赖Chrome Headless若服务器未安装Chrome或路径不对会静默失败。解决在config.yaml中显式指定Chrome路径report: chrome_path: C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe4.5 现象多台设备共用同一IP如ADAM-6050串口服务器下挂多台RTU设备配置后只有第一台能读取原因iotStudio 的Modbus TCP客户端未实现“Unit ID”隔离所有请求默认发Unit ID1而ADAM-6050需为每台设备分配不同Unit ID。解决暂时无法解决官方未开放Unit ID配置项替代方案为每台RTU设备分配独立IP用多个ADAM-6050或改用Modbus RTU over Serial需加USB转RS485适配器。5. 进阶技巧用SQL直接查数据、定制导出模板、以及我坚持的手动配置习惯5.1 绕过API用SQLite直接分析历史数据iotStudio 的data/iotstudio.db是标准SQLite3文件所有历史数据存于history表。表结构如下CREATE TABLE history ( id INTEGER PRIMARY KEY AUTOINCREMENT, device_id TEXT NOT NULL, point_id TEXT NOT NULL, value REAL NOT NULL, -- 已应用scale的工程值 raw_value INTEGER, -- 原始寄存器值 timestamp DATETIME NOT NULL );比如查“昨日主电机温度超80℃的持续时间”SELECT COUNT(*) * 2 AS duration_seconds, -- scan_interval2s每条记录代表2秒 MIN(timestamp) as start_time, MAX(timestamp) as end_time FROM history WHERE device_id s7-1200-01 AND point_id motor_temp AND value 80 AND date(timestamp) date(now, -1 day);提示COUNT(*) * 2是因为scan_interval设为2000ms数据点间隔固定。此SQL可直接粘贴到DB Browser for SQLite中执行结果比调API快10倍。5.2 定制Excel导出模板让班组长拿到的就是“能直接交QC的表”iotStudio 默认导出Excel只含原始数据列timestamp, value, raw_value。但产线需要的是带标题、单位、统计行的正式报表。我们用Python脚本后处理# post-process-export.py import pandas as pd from datetime import datetime # 读取iotStudio导出的CSV假设文件名为export.csv df pd.read_csv(export.csv, parse_dates[timestamp]) # 添加工程列 df[温度(℃)] df[value] df[时间] df[timestamp].dt.strftime(%H:%M:%S) # 计算统计 stats pd.DataFrame({ 项目: [最大值, 最小值, 平均值, 超限次数], 数值: [ f{df[value].max():.1f}℃, f{df[value].min():.1f}℃, f{df[value].mean():.1f}℃, len(df[df[value] 85]) ] }) # 写入Excel分两个sheet with pd.ExcelWriter(press-line-daily-report.xlsx) as writer: df[[时间, 温度(℃)]].to_excel(writer, sheet_name原始数据, indexFalse) stats.to_excel(writer, sheet_name统计摘要, indexFalse, headerFalse)运行后生成的Excel班组长打开就能打印签字——这才是真正的“免培训交付”。5.3 我坚持的手动配置习惯永远用Git管理devices/和dashboards/iotStudio 没有配置版本回滚功能但产线设备增减频繁今天加一台空压机明天拆一台旧传感器。我的做法将整个iotstudio/目录初始化为Git仓库devices/和dashboards/设为跟踪目录data/和logs/加入.gitignore每次设备变更提交时写明变更内容git commit -m add: 空压机PLC(s7-1200-02)监控压力、电流、运行状态 git commit -m fix: s7-1200-01 motor_temp scale from 1 to 0.1 (PLC固件升级后)这样当某天看板数据突变git blame devices/s7-1200-01.yaml一眼看到是谁改了scale值——比翻聊天记录快10倍。最后说一句实在话iotStudio 不是银弹它解决不了设备协议彻底私有、网络完全离线、或需要AI建模的场景。但它精准卡在“产线数字化第一步”的咽喉位置——用最低学习成本、最少硬件投入、最短上线周期把沉默的设备变成会说话的数据源。我见过太多项目死在“先上云平台再慢慢连设备”的宏大叙事里而iotStudio教会我的是先让一台PLC在班组长手机上亮起绿灯再谈下一步。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Python单元测试unittest实战:从核心机制到常见陷阱

Python单元测试unittest实战:从核心机制到常见陷阱

大概四年前的一个深夜,我改了一行订单折扣的判断逻辑,没写单元测试就直接合了代码,结果让一批老订单在用户重新打开订单页时把折扣又算了一遍。那天的复盘会上,我第一次认真看待"Python单元测试(unittest&#xf…

2026/10/10 7:27:21 阅读更多 →
看懂 GitHub 热榜:从日榜中筛选真正值得深入的开源项目

看懂 GitHub 热榜:从日榜中筛选真正值得深入的开源项目

GitHub 热榜这东西,说实话,我基本每天都会刷一遍。尤其是日榜,它不像周榜那样沉淀充分,也不像实时榜那么情绪化,恰恰是那种“刚刚冒头、还没被大多数人发现”的项目最集中的地方。2026-10-03 这天的日榜我照例翻了一遍…

2026/10/10 7:27:21 阅读更多 →
Mailcow 开源邮件服务器部署实战:从 Docker 编排到 DNS 配置与 API 集成

Mailcow 开源邮件服务器部署实战:从 Docker 编排到 DNS 配置与 API 集成

简介:Mailcow 是一套基于 Docker 容器化技术构建的开源邮件服务器解决方案,面向需要自建企业邮箱、替代商业邮件服务的运维人员与开发者。它把 SMTP、IMAP、POP3、Webmail 等邮件服务与反垃圾、反病毒、DKIM、DMARC、SPF 等安全机制整合在一起&#xff0…

2026/10/10 7:26:21 阅读更多 →

最新新闻

API自动化测试质量中枢:从pytest鉴权到LLM接口实践

API自动化测试质量中枢:从pytest鉴权到LLM接口实践

先说个真实场景。你负责的项目上线前一天,运营反馈登录功能大面积报错,点开日志一看——unexpected status 401 unauthorized: incorrect api key provided。再往前追,发现是下游服务换了一套密钥,但配置中心里还留着旧值。这种问…

2026/10/10 8:03:35 阅读更多 →
PCA9422+STM32F746ZG构建硬件级电源管理方案

PCA9422+STM32F746ZG构建硬件级电源管理方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 8:03:35 阅读更多 →
Claude Code魔改指南:从CLAUDE.md到Hooks的四个扩展点

Claude Code魔改指南:从CLAUDE.md到Hooks的四个扩展点

我见过很多人第一次打开 Claude Code,敲两句需求,等它把代码改完,然后关掉终端。这样用当然没问题,但等于你把一台可编程的机器人当成固定电话用。真正让 Claude Code 产生质变的,是那些藏在配置目录里的扩展位——CLA…

2026/10/10 8:03:35 阅读更多 →
高盈利的源头:从ROE、自由现金流到全球配置

高盈利的源头:从ROE、自由现金流到全球配置

做投资这些年,我一直有个习惯:看任何一家公司,先问自己一个问题,它赚的钱到底是从哪来的?这个问题不解决,谈全球视野、谈投资机会,都像在沙子上盖楼。借着《全球视野下的投资机会》第一章“高盈…

2026/10/10 8:03:35 阅读更多 →
Windows下Codex+Superpowers+WSL环境配置避坑指南

Windows下Codex+Superpowers+WSL环境配置避坑指南

1. 从零上手:这套组合到底解决了什么问题第一次接触命令行AI编程助手的人,大概率会在三个地方卡住:工具本身怎么装、插件生态怎么接、Windows下环境怎么配。这三个问题单独拎出来都不算难,但叠在一起就很容易让人在第一步就放弃。…

2026/10/10 8:03:35 阅读更多 →
粒子群优化RBF神经网络:源码解析、参数设置与避坑指南

粒子群优化RBF神经网络:源码解析、参数设置与避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 8:02:35 阅读更多 →

日新闻

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

卫星轨道分类全解析:从LEO到GEO的选型逻辑与工程实践

1. 从“卫星轨道分类”这个标题说起:为什么值得花时间搞懂第一次接触“卫星轨道分类”这个概念,很多人会觉得它离自己很远——不就是天上的星星怎么转吗?但如果你正在做航天任务规划、遥感数据接收、星座设计,甚至只是准备一场航天…

2026/10/10 0:00:39 阅读更多 →
Spring AOP 核心原理与实战:从概念到日志切面落地

Spring AOP 核心原理与实战:从概念到日志切面落地

1. 从一个真实痛点说起:为什么你的代码里到处都是重复逻辑刚入行那会儿,我写过一个用户管理模块,注册、登录、改密码、注销四个接口。每个接口里都塞了几乎一样的日志打印、参数校验、事务开启和提交。当时觉得没什么,能跑就行。直…

2026/10/10 0:00:40 阅读更多 →
Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

Python招聘数据采集与分析可视化:从采集清洗到薪资技能城市可视化全链路

简介:这是一套面向计算机相关专业学生与项目实战学习者的Python数据采集与分析可视化完整项目,以Boss直聘岗位数据为对象,适合用作毕业设计、课程设计或期末大作业。资源包共38个文件,约246KB,以13个py源码文件为核心&…

2026/10/10 0:00:40 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 1:36:08 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 10:11:06 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/10 5:23:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 21:32:20 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 6:17:20 阅读更多 →