news 2026/9/18 14:16:27

Serial Studio 扩展机制完全指南:从 Extension Manager 到自建扩展仓库

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Serial Studio 扩展机制完全指南:从 Extension Manager 到自建扩展仓库

Serial Studio 扩展机制完全指南:从 Extension Manager 到自建扩展仓库

【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio

Serial Studio 的扩展(Extensions)机制允许用户在官方遥测仪表盘的基础上追加主题、帧解析器、项目模板、QML 仪表组件与外部插件,从而为 UART、BLE、MQTT、Modbus、CAN Bus 等数据源定制化处理与可视化。本文以官方文档 Extensions.md 为骨架,结合仓库中的 ExtensionManager、ExtensionHandler 与 ExtensionCatalog 等实现,完整讲解扩展的安装、运行、卸载、更新、仓库管理、info.json元数据格式、插件状态持久化以及 API 编程接口,读完即可在真实项目中使用或自行发布扩展。

扩展类型总览

Serial Studio 共支持五种扩展类型,覆盖从外观到数据处理的全链路定制:

类型作用落地形态
Themes定制整套界面外观,包括代码编辑器的语法配色主题 JSON 文件 + 编辑器 XML 配色
Frame parsers用 JavaScript 函数把自定义二进制或文本协议解码为结构化数据复制到工作区 Extensions 文件夹的.js文件
Project templates面向常见传感器配置的现成.ssproj项目文件复制到工作区 Extensions 文件夹的.ssproj文件
Widgets用 QML 编写、像内置组件一样渲染实时数据的仪表可视化随实体类型注册到项目编辑器 Widget 列表
Plugins连接 Serial Studio API 服务器的外部程序(Python、原生二进制等)独立外部进程

关键区别在于Widgets 运行在 Serial Studio 进程内部,拥有与应用本身相同的权限;而Plugins 是独立的外部进程,通过 API 服务器与主程序通信。两者在文档中各有独立篇幅:Widget-Extension-Development.md 与 Plugin-Development.md。

所有扩展都从在线仓库下载并安装到本地,通过Extension Manager(扩展管理器)对话框完成浏览、安装、更新与卸载。

打开扩展管理器

点击工具栏中的Extensions按钮即可打开扩展管理器,它包含三个视图:

  • 网格视图(Grid view):浏览可用扩展,支持搜索与类型筛选。
  • 详情视图(Detail view):展示 README、元数据、截图,以及安装/卸载控制按钮。
  • 仓库设置(Repository settings):管理仓库 URL(仅 Pro 版本提供)。

从源码看,这个界面由Misc::ExtensionManager单例驱动,该类通过一组 Q_PROPERTY 向 QML 暴露状态:count(当前筛选后的扩展数量)、extensions(网格视图数据)、selectedExtension(选中项)、searchFilter/filterCategory/filterType(三类筛选条件)、downloadProgress(下载进度 0.0–1.0)、runningPlugins(运行中的插件)等,见 ExtensionManager.h。类型筛选中使用的友好名称由friendlyTypeName()映射(如frame-parser→ "Frame Parser"),见 ExtensionManager.cpp。

安装扩展

完整安装流程如下:

  1. 打开扩展管理器。
  2. 点击Refresh拉取最新目录(对应源码中的refreshRepositories(),它并行请求所有仓库的manifest.json并合并结果,见 ExtensionManager.cpp)。
  3. 浏览或搜索扩展,使用类型下拉框按 Themes、Plugins 等筛选。
  4. 点击扩展卡片进入详情视图。
  5. 点击Install,进度条会显示下载状态。
  6. 安装完成后,不同类型的扩展按各自方式生效:
    • Themes:出现在 Preferences(偏好设置)的主题下拉框中。
    • Plugins:可从详情视图的Run按钮启动。
    • Frame parsers:被复制为.js文件到工作区的 Extensions 文件夹;在帧解析器编辑器的工具栏使用Open按钮(导入外部脚本文件)即可加载到项目。
    • Project templates:被复制为.ssproj文件到工作区的 Extensions 文件夹;在工具栏使用Open Project加载。
    • Widgets:重启后出现在项目编辑器的 Widget 列表中(按其声明的实体类型归类);首次渲染时 Serial Studio 会询问是否允许其运行。

安装操作的底层实现在installExtension():它会先读取m_installer.installedInfo(),若扩展已安装则保留其本地记录的type(避免更新时把新版本写到旧目录旁导致卸载残留),然后交给ExtensionInstaller::install()完成下载与落盘,见 ExtensionManager.cpp。下载超时被设置为 15 秒(m_nam.setTransferTimeout(15 * 1000),见 ExtensionManager.cpp),网络不可用时管理器会快速失败而不是长时间挂起。

卸载扩展

  1. 打开扩展管理器,找到已安装的扩展(卡片上有Installed徽标)。
  2. 点击卡片,然后点击Uninstall
  3. 对于插件:若正在运行,请先停止它。
  4. 若卸载的正是当前主题,Serial Studio 会自动回退到Default主题。

注意:卸载是不可逆的破坏性操作——安装文件会被彻底删除。源码中的uninstallExtension()在删除前会校验扩展确实已安装(isInstalled(id)),删除后还会校验isInstalled(id)以确认删除成功,见 ExtensionHandler.cpp。API 层还支持dryRun: true预览将要删除的内容而不真正提交(详见下文 API 章节)。

更新扩展

当仓库中存在更新版本时,扩展卡片会显示Update徽标。点击卡片后按Install即可完成更新。版本判断使用数值化比较:ExtensionCatalog::compareVersions()对远程版本与本地已安装版本做严格大于比较,避免字符串比较把1.10.0误判为比1.9.0新(见 ExtensionManager.cpp)。

此外仓库还实现了扩展自动更新组件 ExtensionAutoUpdater,通过updateCheckEnabledautomaticUpdates两个属性控制是否检查更新、是否静默安装可用更新。

插件:外部进程实时接入

插件是连接到 Serial Studio 以接收实时数据、计算统计信息、显示自定义可视化的外部进程,支持两种连接方式:

  • gRPC(端口 8888):高性能二进制流,推荐用于实时帧数据,详见 gRPC-Server.md。
  • TCP/JSON(端口 7777):基于 JSON 的协议,详见 API-Reference.md。

运行插件

  1. 从扩展管理器安装插件。
  2. 点击插件卡片打开详情视图。
  3. 点击Run,插件启动,其输出出现在日志面板中(源码通过PluginRunneroutputChanged信号把子进程 stdout/stderr 转发给 UI,见 PluginRunner.h)。
  4. 点击Stop终止插件。

插件运行前置条件

  • 必须启用 API 服务器(若未启用,Serial Studio 会弹出提示)。launchPlugin()前的checkLaunchPreconditions()会先校验 API 服务器状态,gRPC 插件还会走ensureApiServerForLaunch()单独确认 8888 端口可用,见 ExtensionManager.h。
  • Python 插件需要 Python 3.6+。
  • 使用 gRPC 的插件需要grpcioPython 包;仓库中的插件自带启动脚本,首次运行时会在本地虚拟环境中自动安装它。
  • Serial Studio 退出时会自动停止所有运行中的插件(stopAllPlugins(),见 ExtensionManager.h)。

平台支持

插件可以在元数据中用platforms字段声明针对不同操作系统与 CPU 架构的专属入口。Serial Studio 会根据当前平台自动选择正确的二进制或脚本。平台键使用os/archos/*格式(*表示通用构建):

  • macOSdarwin/*(始终为通用构建)。
  • Linuxlinux/x86_64linux/arm64
  • Windowswindows/*windows/x86_64

平台判定由ExtensionCatalog::currentPlatformKey()完成,platformSupported()resolvePlatform()负责过滤与覆盖合并,见 ExtensionCatalog.h。若插件不支持当前平台,Install 按钮会被禁用并显示Unavailable徽标。

想自己开发插件?参见 Plugin-Development.md,其中包含完整的info.json字段参考、代码示例、状态持久化与分发说明。

仓库管理

仓库(Repository)是一个指向manifest.json文件的 URL,该文件列出了仓库内所有可用的扩展。Serial Studio 自带一个默认社区仓库(源码中的kDefaultRepoUrl,见 ExtensionManager.cpp)。仓库 URL 列表持久化在 QSettings 的ExtensionRepositories键中,首次启动为空时自动填充默认仓库。

管理仓库(Pro)

自定义仓库管理仅在 Serial Studio Pro 中提供,可支持:

  • 公司内部扩展:在内网或私有仓库托管私有扩展。
  • 社区合集:托管在任意位置的第三方扩展集合。
  • 本地开发:开发扩展时指向本地文件夹。

管理步骤:

  1. 打开扩展管理器。
  2. 点击工具栏中的Repos按钮。
  3. 添加 URL、浏览选择本地文件夹,或移除已有条目。
  4. 点击Reset恢复默认社区仓库。

安全性方面,addRepository()会先调用ExtensionCatalog::isTrustedRepoUrl()校验——仓库必须是本地文件夹或 https:// URL,否则直接拒绝并弹窗警告(见 ExtensionManager.cpp)。resetRepositories()在恢复默认仓库前会先停止所有插件并卸载全部扩展(见 ExtensionManager.cpp)。本地仓库通过browseLocalRepo()弹出目录选择器加入,且本地仓库的 manifest 由loadLocalManifest()直接读取文件而非走网络请求(见 ExtensionManager.cpp)。

创建扩展:目录结构与元数据

仓库目录结构

一个典型的扩展仓库如下:

my-repo/ manifest.json theme/my-theme/ info.json my-theme.json code-editor/my-theme.xml plugin/my-plugin/ info.json plugin.py run.sh run.cmd frame-parser/my-parser/ info.json my-parser.js widget/com.example.level-bar/ info.json LevelBar.qml

manifest.json

manifest 列出仓库内每个扩展info.json的相对路径:

{ "version": 1, "repository": "My Extensions", "extensions": [ "theme/my-theme/info.json", "plugin/my-plugin/info.json" ] }

info.json基础格式

每个扩展都有一份包含元数据的info.json

{ "id": "my-theme", "type": "theme", "title": "My Custom Theme", "description": "A dark theme with company branding.", "author": "Your Name", "version": "1.0.0", "license": "MIT", "category": "Dark", "screenshot": "screenshot.png", "files": [ "info.json", "my-theme.json", "code-editor/my-theme.xml" ] }
插件info.json

插件在基础字段上增加entryruntime,可选增加platformsgrpc字段。完整字段参考与示例见 Plugin-Development.md。

Widgetinfo.json

组件(Widget)额外包含一个widget块,声明实体作用域、QML 入口文件、接受的数据以及设置项。仓库自带的示例扩展 examples/widget-extension/info.json 展示了完整结构——包括apiVersionhostCompat(宿主版本兼容范围)、scope(实体作用域,如dataset)、qml入口、accepts(接受的数据集数量与值类型)、defaultSize以及config设置数组(支持choicebool等类型,每个设置项含idtypelabeldescriptiondefault与可选options)。完整参考、数据模型与信任模型见 Widget-Extension-Development.md。

字段参考表
字段必填说明
id唯一标识符(小写、连字符)。
typethemeframe-parserproject-templatewidgetplugin
title扩展管理器中显示的名称。
description显示在卡片上的简短描述。
author作者名或组织名。
version语义化版本字符串(例如"1.0.0")。
license许可证标识符(例如"MIT")。
category用于筛选的分类。
screenshot预览图的相对路径。
files要下载/安装的相对文件路径数组。
entry插件脚本或二进制的入口点。
runtime插件解释器命令(例如"python3")。原生二进制留空。
terminal插件设为true在系统终端窗口中启动。
grpc插件设为true表示插件使用 gRPC 流式传输(端口 8888)而非 TCP/JSON。
platforms插件按平台覆盖entryruntimefiles

从实现看,files列表在 catalog v2 条目中还可附带 sha256 摘要与文件大小:ExtensionCatalog::parseFileList()会校验每个文件的路径组件是否安全(isSafePathComponent()/isPathSafe()防止路径逃逸出扩展目录),下载后通过digestMatches()校验摘要,见 ExtensionCatalog.h。这意味着扩展安装具备完整性校验与路径安全防护。

托管方式

GitHub:创建仓库并分享 manifest 的 raw URL:

https://raw.githubusercontent.com/your-org/extensions/main/manifest.json

本地文件夹:在 Repository Settings 中使用 Browse 选择包含manifest.json的文件夹。

任意 Web 服务器:通过 HTTP(S) 托管文件。files中的相对路径会基于info.json的 URL 解析(resolveFileUrl(),见 ExtensionCatalog.h)。

插件状态持久化

插件状态(打开的窗口、设置、配置)保存在项目文件中,与组件布局数据并列。这意味着不同项目可以拥有不同的插件配置。

Serial Studio 永远不会自行调用extensions.saveState插件必须显式调用它(典型时机:设备断开时、插件自身停止时、或 Serial Studio 退出前)状态才会持久化。状态在插件启动或新设备连接时恢复。Serial Studio 关闭时仍在运行的插件,会在下次仪表盘可用时(设备连接或文件播放器打开)被自动重新启动,除非用户手动停止过它们。

从源码看,这一机制由ProjectModel::savePluginState()/pluginState()落到项目文件,API 层extensions.saveState/extensions.loadState命令分别调用二者,见 ExtensionHandler.cpp。PluginRunner通过restorableIds()记录可恢复的插件,restoreRunningPlugins()在仪表盘就绪时恢复它们,见 PluginRunner.h。

代码层面的状态持久化 API 用法详见 Plugin-Development.md。

API 访问:用命令管理扩展

扩展管理器可通过 TCP 端口 7777 的 API 或端口 8888 的 gRPC 访问。这些命令由 ExtensionHandler.cpp 在命令注册表中统一注册:

命令说明
extensions.list列出所有可用扩展。返回countaddons数组,见 ExtensionHandler.cpp。
extensions.getInfo获取指定扩展的详细信息(参数extensionId)。返回结果附带installedupdateAvailableinstalledVersion字段,见 ExtensionHandler.cpp。
extensions.install按索引安装扩展(参数addonIndex)。
extensions.uninstall按索引卸载扩展(参数addonIndex)。破坏性操作:不可逆地删除扩展文件。传dryRun:true可预览删除内容而不实际提交——dry run 返回willRemove: true与警告信息,见 ExtensionHandler.cpp。
extensions.refresh从所有仓库刷新目录。
extensions.saveState保存插件状态到项目(参数pluginIdstate)。
extensions.loadState从项目加载插件状态(参数pluginId)。
extensions.listRepositories列出仓库 URL(仅 Pro)。
extensions.addRepository添加仓库 URL(仅 Pro,参数url)。
extensions.removeRepository按索引移除仓库(仅 Pro,参数index)。

注意仓库相关命令(listRepositories/addRepository/removeRepository)被#ifdef BUILD_COMMERCIAL包裹,仅编译进 Pro 构建,见 ExtensionHandler.cpp。

已安装扩展的存放位置

扩展安装在工作区文件夹的Extensions/子目录下(默认是 Documents/Serial Studio,可在设置中修改):

~/Documents/Serial Studio/Extensions/ installed.json theme/my-theme/ info.json my-theme.json code-editor/my-theme.xml plugin/my-plugin/ info.json plugin.py run.sh

installed.json记录安装清单,由ExtensionInstaller维护(工作区路径由 WorkspaceManager 提供,ExtensionManager通过Core::services().workspaceManager获取)。框架解析器与项目模板正是从该目录被复制到工作区 Extensions 文件夹后供编辑器加载的。

结语

Serial Studio 的扩展体系把"界面定制、协议解析、可视化组件、外部处理进程"四类需求统一收敛到一套仓库 +info.json元数据的机制中:用户侧通过扩展管理器即可完成浏览、安装、运行、更新、卸载的完整生命周期管理,开发者侧则可用几行 JSON 元数据 + 一个 manifest 发布自己的扩展。若深入阅读 ExtensionManager.cpp、ExtensionCatalog.h 与 ExtensionInstaller.h,还能看到版本数值比较、路径安全校验、下载摘要校验、插件进程生命周期管理、状态按项目持久化等工程细节——这些正是从"能用"走向"可靠分发"的关键设计。

【免费下载链接】Serial-StudioOpen-source telemetry dashboard. Supports UART, BLE, MQTT, Modbus, CAN Bus and more.项目地址: https://gitcode.com/GitHub_Trending/se/Serial-Studio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/18 14:16:00

智能爬虫Crawl4AI:本地大模型解决动态网页抓取难题

1. 项目背景与核心价值最近在开发一个需要大量数据采集的项目时,发现传统爬虫方案存在几个痛点:一是反爬策略越来越复杂,二是动态渲染页面难以处理,三是数据清洗环节耗时费力。于是我开始探索结合AI能力的智能爬虫方案&#xff0c…

作者头像 李华
网站建设 2026/9/18 14:14:00

实时特征平台架构:美团配送的分钟级统一与Flink动态计算实践

简介:一份美团配送实时特征平台建设实践的技术分享PDF,面向大数据实时计算开发者、平台架构师与算法工程同学。内容紧扣配送业务分钟级实时特征需求,系统梳理从平台目标、整体架构到稳定性建设、规模化的完整演进路径。包内共1个PDF文件&…

作者头像 李华
网站建设 2026/9/18 14:12:45

五周 2 万 Star 的 AnyDoc,TaoToken 发 Key 给 LLM

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

作者头像 李华
网站建设 2026/9/18 14:12:25

PyWxDump 实战指南:微信数据库解密与微信密钥获取

PyWxDump 实战指南:微信数据库解密与微信密钥获取 【免费下载链接】PyWxDump 删库 项目地址: https://gitcode.com/GitHub_Trending/py/PyWxDump 一条命令,微信数据库密钥到手,MSG.db 里的聊天记录、群信息、文件索引全部能解开。PyWx…

作者头像 李华
网站建设 2026/9/18 14:11:47

OTDR与GIS融合的光纤智能监控:从长度域到地理域的故障定位实践

简介:一份面向光纤网络运维与智能监控方向的研究文献,内容聚焦基于GIS和OTDR的光纤智能监控系统设计,尤其针对航天发射场等关键场景的光纤线路维护需求。系统将地理信息系统的空间定位能力与OTDR实时监测能力结合,实现光纤故障快速…

作者头像 李华