Skip to content

功能配置 ​

“功能配置”页面控制已经编译进固件的模块。配置保存于 LittleFS /config/features.json,点击“保存并重启”后生效。

生效条件 ​

text
compiled AND userEnabled AND budgetPassed AND NOT runtimeDisabled
字段含义
compiled有效实现已包含;单独开启保留宏不证明能力已实现
userEnabled用户在本页开启
budgetPassed内部判定:启动时 DRAM/PSRAM 预算通过
runtimeDisabled运行期内存保护临时停用该功能,不等同于用户关闭
active兼容字段:准入门控通过,不代表实例已初始化或设备实际可用
activeMeaning / admissionState新候选明示 admission_only,以及预算/网络/依赖等准入原因
instanceState被动 owner 观察;初始化或服务生命周期,未取得快照为 unobserved
instanceObserved / instanceScope初始化、服务生命周期、命令执行活动或静态资源适用范围;均不是物理健康
instanceReason未编译、无独立 owner、观察者未建立、同步未就绪、忙锁等固定原因;不触发初始化
initializedInstances仅初始化/未初始化状态返回明确数量;未知、忙锁、待清理时不返回
locked编译或分区不支持,运行时不能开启
deferred网络依赖功能,等待网络就绪后初始化
bundleRequired是否为强制组合成员;未实现的可选 otaFs 不锁定 OTA 固件升级父项

内存不足的功能会跳过初始化并记录 [BUDGET] 日志;/api/system/status 对应值为 no-memory。重启后才会重新评估,不要通过反复开关尝试“挤出”内存。

上方公式是简化示意;实际还逐级检查依赖与网络就绪。需要重启的 ioExpander/i2cSensors 使用本次启动快照,保存意图不立即替换快照;缺失或循环依赖拒绝准入。新页面区分“待保存”“重启后启用/停用”“已准入 · 实例状态未确认”,附属能力降级显示在父行。新字段属于 2026-10-01 后续候选,未部署的旧设备不自动获得这些行为。

Flash/RAM 均为静态估算;摘要 resourceAccounting=static_estimate、instanceMemoryMeasured=false。free8KB/最大连续块是独立系统堆指标,不是某一功能的实测占用。关闭选项不能据此宣称已经释放估算 RAM;其余功能观测和实机资源测量仍待完成。

新候选在主准入状态下单独显示“驱动已初始化 × N”“驱动未初始化”“实例观测忙”或“实例清理待重试”。unobserved 不等于 0 个实例;busy 不沿用上次数量;cleanup_pending 说明资源仍保留,需按该驱动的安全维护流程处理,不自动重试危险动作。已初始化也不证明真实模块应答、物理负载动作、网络连通或全部内存释放。观察不会为了查询创建驱动/互斥或触发硬件读写。

状态未覆盖的服务继续明确未知;不得把三个驱动的观测推广成所有功能已实测。43 项本地主机/Node 行为测试通过,当前候选完整构建、设备端显示和实机资源收益仍独立验收。

2026-10-03 的 r18 后继主仓增量进一步接入 OLED/LCD、LCD1602、红外、RF 学习、规则 manager、屏幕任务、DS18B20、NeoPixel 和 TM1637,尚待统一测试,未部署。这批代码不属于 r18 冻结输入,早期 43 项通过不能作为本批通过。服务范围只显示实际 owner 的“实例已分配/运行中/已停止/退出中”,不返回或沿用驱动初始化数量;“已停止”仍可能保留对象、缓存或延迟清理资源。RuleScript 只报告 manager 对象存在(allocated),不根据规则启用数量声称正在执行。屏幕请求停止后保留任务时显示退出中;后台未编入或同步条件缺失时保持未知。IR/RF/TM1637 缺锁时拒绝无锁启动,正常业务获取 owner 可重试分配,状态查询不分配或修复。

DS18B20 从 SensorDriver 真实对象容器读取状态,采样失败但对象仍保留时显示“已分配”,不代表探头存在或读数新鲜。TM1637 和 NeoPixel 也只以实际对象保留证明分配;原驱动应答/初始化与实际显示仍须单独验收。NeoPixel 分配中显示忙、删除过程中显示退出中,查询不读取可被替换的灯带对象、不触发灯珠输出。关闭配置不会把仍保留的对象错误显示成停止。

功能键r18 后继主仓观察覆盖
ds1302、rfid、ethernet、ioExpander、i2cSensors、lcd1602已接线真实初始化快照;不等于当前设备已部署或完成物理验收
lcd、irRemote、rfLearn、screenPanel已接线实际 owner 生命周期;四项均为本批新增,待测试
ruleScript实际静态 manager 对象存在;只报告 allocated
ds18b20、sevenSegment、neopixel实际分配 owner 观察;不报告驱动 initialized,三项均待测试
mdnsr19 后继:同步后的实际 begin/end 后台状态,不调用健康检查/网络查询,待测试
fileLoggingr19 后继:原日志锁下的实际 ring/任务槽,观察不写盘也不清理,待测试
userAdminr19 后继:真实可选用户路由对象的构造/析构,不借常驻认证服务推断,待测试
webServer、modbus、ota、logViewer、ble、cellularr19 后继:实际动态管理器构造/析构的 owner_lifetime;不证明服务运行,待测试
mqttsr19 后继:实际 WiFiClientSecure 和蜂窝 software TLS/QSSL 的 transport_allocation;只证明对象分配,待测试
lcdGb2312、deviceControlstatic_resource/no_dedicated_instance,无独立常驻运行对象;不是瞬态请求不耗内存
commandScriptr19 后继:实际 execute 入口的 execution_activity;running=当前执行中,idle=当前无执行,待测试
otaFs未实现文件系统 OTA writer;旧宏/配置键仍保留,有效 compiled=false/implementation_missing

2026-10-04 的 r19 后继主仓代码中,28 项分为 17 项实际 owner 实例观察、6 项动态管理器寿命观察、1 项 TLS 传输对象分配观察、1 项实际执行活动、2 项无独立实例的静态资源、1 项未实现 otaFs。本批尚未统一测试/部署,分类不是全部服务运行/实物验收。尚未正常创建的已接线 owner 显示 observer_not_registered;缺锁显示 synchronization_unavailable;忙锁显示 observation_busy;不一致快照显示 invalid_snapshot。编译未包含且没有观察者时显示 not_compiled。页面保持用户意图/重启/降级主状态优先,未知不能解释为 0 个实例,也不按静态 RAM 估算声称已释放内存。

动态管理器显示“管理器已创建/销毁中/未创建”。构造、销毁和重叠替换通过静态身份槽观察,不访问可能销毁的对象;构造未完成或并发变更时显示忙,槽容量或身份耗尽保持未知。该状态不能证明 Web 正在监听、Modbus 正在轮询、OTA 写入成功、蓝牙已广播或蜂窝已联网;服务运行和硬件资源归还仍单独验证。

MQTTS 显示“TLS 对象已分配/释放中/未分配”,包括尚未选中的蜂窝 TLS 对象;不证明当前连接、TLS 握手或证书认证成功。WiFi 和蜂窝对象按实际分配/删除路径记录,查询不创建 TLS 或发送网络请求。蜂窝两种 TLS 后端都不可用时拒绝 MQTTS,不再回退普通 Client;此路径可能在实例建立前失败并显示 -11。未标记为可信 TLS provider 的外部 Client 进入 MQTT 客户端安全校验时返回 -15(MQTTS_TRANSPORT_UNAVAILABLE),实例销毁后该实例错误不一定保留。不能用单一错误码判断所有 TLS provider 缺失路径。这些保护为待统一验证的新代码,尚无设备部署结论。

文件日志禁用但缓冲/任务仍保留时显示退出中;查询只归还互斥,不会顺便 flush 或释放 ring。排队 worker 和成功写盘是不同事实。mDNS 查询仅观察已同步的静态启动状态,不保留可能悬空的 DNSManager 指针;running 不证明域名或网络可达。用户管理只报告路由对象分配,不证明 Web 正在监听。命令执行的 idle 不代表代码、对象或全部 RAM 已释放,并发/提前失败退出保持一致计数,溢出时保持未知。

文件系统 OTA 当前没有 writer,启用旧 FASTBEE_ENABLE_OTA_FS 宏不能获得该能力;分区发布声明和旧用户意图继续兼容,没有新增刷写入口。只有规则/命令脚本和日志查看/文件日志是强制组合,未实现 otaFs 不禁用现有固件 OTA 父功能。两项静态资源显示“无独立实例”,不能解释为不占 Flash/RAM;全部设备启停/真实内存/恢复/长稳仍单独验收。

菜单遵循同一能力状态:设备配置、网络配置、功能配置等核心管理菜单始终显示;可选功能菜单只在 compiled !== false 且 active === true 时显示。已编译但未启用的功能不会显示对应菜单,未编译功能在本页锁定并标注“未编译入固件”。

运行时内存降级 ​

2026-10-04 的 r19 后继代码进入 SEVERE 后暂停 MQTTS、Modbus、外设执行 Worker/定时器、脚本和高内存可选外设,优先保留网络与 Web 管理入口。MQTTS 不自动改为 MQTT;持续 CRITICAL 的 MQTT 停止也是本次启动暂停,不再写入 enabled=false。用户协议、端口、凭据及外设/规则配置保持原值。该修复尚待统一测试/部署,旧版本的行为不能据此倒推为已修复。

内存恢复后只按已确认、已启用的安全配置尝试重建;请求排队、堆不足或实例未就绪仍保留暂停/待重试状态,不连接明文备用。memoryDegradation.mqttsPaused 表示 TLS 暂停;兼容字段 mqttsDowngraded 固定为 false。旧磁盘降密标记继续保留,只有明确的原 mqtts 和合法原端口才能安全重建;缺元数据不猜测。旧版本已保存的 MQTT 禁用标记不会自动清除,须用户在协议配置页明确保存并启用。

出厂默认 ​

发布环境共享统一功能基线,但 OTA、红外等硬件能力由具体环境覆盖。出厂只保证 Web 服务和 mDNS 管理入口开启,其余功能按需启用:

分组功能键默认依赖/说明
网络webServer、mdns开启禁用 Web 会失去管理入口;AP 配置模式仍保留入口
外设lcd、neopixel、sevenSegment、ds18b20关闭需要对应硬件
外设screenPanel关闭仅 ESP32-S3:支持的 SPI/RGB 显示与可选 I2C 触摸,见设备屏幕
外设lcdGb2312、i2cSensors、rfid、irRemote、rfLearn、ds1302、lcd1602关闭依赖 LCD、I2C、SPI、RMT 或三线接口
协议modbus、mqtts关闭MQTTS 依赖 MQTT;Modbus 需要 UART/RS485
自动化ruleScript、commandScript关闭commandScript 依赖 ruleScript
系统deviceControl、ota、logViewer、fileLogging、userAdmin关闭OTA 还需要 A/B 分区;文件功能受构建宏控制
网络扩展ethernet、cellular、ble关闭W5500、EC801E-CN 或 BLE 硬件;BLE 暂不属于发布路径

具体编译状态以页面和 /api/features/status 返回为准。esp32s3-F8R8 关闭红外/RF 学习以避免 RMT/库冲突,esp32s3-F16R8 保持启用;4MB 环境的 ota 因分区限制锁定。

当前 esp32-F4R0、esp32c3-F4R0、esp32c6-F4R0 和 esp32c6-F8R0 环境不编译 Ethernet/Cellular;功能页应显示“未编译入固件”并锁定开关,相关可选菜单不会出现。

经典 esp32-F4R0 和 esp32c3-F4R0 的 4 MB Flash 应用分区有限,面板发布目标明确设为 screenPanel=false、screenUi=false、remoteResources=false。经典 ESP32 仍编译 pointHistory=true;C3 为满足单个 0x330000 应用槽进一步设置 pointHistory=false,但实时采集、Modbus、外设执行和普通 Web 保留。不能在功能页打开未编译的模块;支持 PSRAM 且连接匹配显示硬件的 ESP32-S3 更适合设备屏幕。设备屏幕只面向 ESP32-S3;ESP32-C6 与经典 ESP32、C3 均不提供设备屏幕能力。最终能力以发布清单、实际 BIN 和设备 /api/system/capabilities 为准。

esp32s3-F16R8 是完整面板的目标环境,已编入 screenPanel、screenUi、pointHistory 和 remoteResources。这些编译能力不等于任意屏板已经通过实体兼容验收:微雪 Rev4 的 ST7701/GT911 代码已接入,但当前实屏仍自动漂移并出现横向、纵向卷边,物理显示验收未通过。S3 芯片资源也不会自动带来显示控制器兼容性。SPI 预算不含 RGB565 单帧额外的 460,800 字节 PSRAM。

设备屏幕资源口径 ​

指标规划值使用方式
Flash 估算约 80 KiB用于功能页评估,最终差值以发布 BIN 为准
RAM 估算69,632 B(约 68 KiB)包含 snapshot/stripe、任务栈和运行对象
内部 DRAM 启动门槛20 KiB只表示必须保留的内部 8-bit DRAM 余量,不是总 RAM
大缓冲约 48 KiB优先 PSRAM;无 PSRAM 时要求内部连续完整分配

预算不通过时功能状态应为 no-memory,菜单不应出现,已有配置仍保留。即使预算通过,也必须继续观察最大连续块、网络/TLS 峰值和长时间运行情况。

操作步骤 ​

  1. 进入 Web → 功能配置。
  2. 先确认“编译状态”和硬件依赖,再打开需要的功能。
  3. 关闭父功能时,依赖它的子功能会自动关闭(如 lcd → lcdGb2312)。
  4. 点击保存并重启;仅保存配置不会立即初始化驱动。
  5. 重启后先核对准入原因,再查看对应驱动诊断、有效数据或实际读回;active=true 和健康监控本身不证明外设可用。

功能开关只影响运行时初始化,不会减少固件文件大小;要缩减 Flash,必须在 platformio.ini 中关闭对应编译宏并重新构建 Web 资源。

API ​

GET /api/features/status ​

返回功能数组和资源摘要:

json
{
  "success": true,
  "data": {
    "features": [
    {
      "key": "modbus",
      "compiled": true,
      "userEnabled": false,
      "active": false,
      "activeMeaning": "admission_only",
      "admissionState": "user_disabled",
      "instanceState": "unobserved",
      "instanceObserved": false,
      "instanceScope": "owner_lifetime",
      "instanceReason": "observer_not_registered",
      "flashKB": 20,
      "ramB": 1024,
      "deferred": true
    }
    ],
    "summary": {
      "totalFlashKB": 300,
      "activeFlashKB": 0,
      "activeRamB": 0,
      "resourceAccounting": "static_estimate",
      "instanceMemoryMeasured": false,
      "free8KB": 80,
      "largest8KB": 40
    }
  }
}

POST /api/features/config ​

只更新配置,不重启:

json
{
  "features": {
    "modbus": { "enabled": true },
    "mqtts": { "enabled": false }
  }
}

POST /api/features/estimate ​

按提交的开关估算 Flash/RAM,不保存配置。

POST /api/features/apply ​

保存配置并延时重启;客户端应先读到成功响应,再轮询 /api/health。

注意事项 ​

2026-10-01 20:04 后续候选还为 ioExpander 提供真实 provider 初始化快照:最多四个实例,使用外设管理器已有锁零等待观察,不访问 I2C 或改变输出。忙锁显示 busy;任一实例清理未完成显示 cleanup_pending 且不返回数量;用户关闭功能但实例仍保留时继续显示。首次初始化失败不算初始化实例,数据失鲜与实例存在分开。25 项扩大回归及 9 项真实锁/Provider 模拟测试通过,不是现场接线、内存回收或长期稳定性证明;该代码不属于 r5。

2026-10-01 后续候选将 i2cSensors 缓存接入实际实例观察:正常业务创建缓存后才注册,查询不创建驱动/互斥、不访问 I2C;采样锁忙返回 busy,不返回旧数量。只统计该功能组已初始化实例,不混入其他通用传感器。功能准入关闭但实例仍在时如实保留显示;初始化失败/读失败/释放后按实际缓存状态更新。

本地 10 项生产缓存/驱动模拟回归通过,包括 1000 次被动查询、并发采样、失败/释放及容量边界;不是 MCU 内存回收、物理读数或长稳证明。该后续代码不在早先 r4 镜像中,完整新候选门禁另记。

  • 未编译功能不会因修改 features.json 而出现。
  • 网络依赖功能在启动早期显示 deferred 属正常行为。
  • Web 页面、日志接口和定制文件 API 在低内存时可能返回 503,按 Retry-After 退避。
  • features.json 保存完整的用户期望状态;旧版稀疏配置会在首次成功加载时保留已有选择并自动补全。迁移设备时使用配置导入/导出,不要手改运行中的文件。

蜂信物联 | fastbee.cn