Flipper Zero 万能遥控器库扩展指南:为电视、音响、投影仪与空调录制并提交 IR 信号
【免费下载链接】flipperzero-firmwareFlipper Zero firmware source code项目地址: https://gitcode.com/GitHub_Trending/fl/flipperzero-firmware
本文以 Flipper Zero 固件仓库中的 UniversalRemotes.md 为骨架,讲解如何将你自己的电视、音响(音频播放器)、投影仪和空调遥控器信号录入 Flipper Zero 的"万能遥控器"(Universal Remote)库。读完本文,你将掌握每一类设备的标准信号命名规范、逐键录制流程、空调这类"状态型"设备的特殊录制手法,以及如何把录制结果追加到.ir资产文件并提交 Pull Request,让固件内置的 Universal Remote 界面能直接驱动你的家电。
背景:什么是 Flipper Zero 的 Universal Remote
Flipper Zero 的红外(IR)应用内置了一个"万能遥控器"入口,它不是一个单一的学习遥控器,而是一个信号库 + 暴力遍历(brute force)发送器:库中按设备类别存放了大量品牌型号的红外信号,界面以按钮面板(Button Panel)呈现,逐个尝试库中的信号直到命中。
- 固件侧,每个类别对应一个场景文件,例如 infrared_scene_universal_tv.c、infrared_scene_universal_ac.c 等;
- 场景通过
infrared_brute_force_set_db_filename()指向对应的资产文件,例如EXT_PATH("infrared/assets/tv.ir")(见 infrared_scene_universal_tv.c); - 随后通过多次
infrared_brute_force_add_record(brute_force, i++, "Power")之类的调用,按固定顺序注册按钮面板上的信号名(同一文件内可见Power、Mute、Vol_up、Ch_next等)。
因此,本文介绍的工作流的本质是:用 Flipper 的学习功能录下你家设备的信号,把结果以规定的格式追加到对应类别的.ir库文件中,从而扩充固件内置的万能遥控库。资产文件位于 applications/main/infrared/resources/infrared/assets/ 目录,共四类:
| 设备类别 | 资产文件 |
|---|---|
| 电视 TV | tv.ir |
| 音频播放器 Audio | audio.ir |
| 投影仪 Projector | projector.ir |
| 空调 A/C | ac.ir |
通用录制流程与信号命名规则
无论哪种设备,录制的基本操作都是一致的(对应学习场景的实现见 infrared_scene_learn.c,其中通过infrared_worker_rx_start()启动红外接收、弹出提示 "Point the remote at IR port and push the button"):
- 拿起原装遥控器,将其发射窗口对准 Flipper 的 IR 接收口;
- 若是录制的第一个按键,选择"开始学习新遥控器";否则按
+添加新按键; - 按下遥控器上的目标按键,并在弹出的命名界面中将其保存为规定的信号名(如
Power); - 重复第 2、3 步直到全部所需信号录制完毕。
信号名是"见名知义"的,且每个信号都必须实测验证——确认按下 Flipper 上对应按钮后,家电确实执行了该动作(开机、静音、换台……),再继续下一步。全部验证通过后,将这批信号追加到对应类别资产文件的末尾(追加而非插入,顺序无关紧要,详见后文"最终提交步骤")。
从库文件格式上看,信号有两种保存形态,两种都会被 Universal Remote 正常加载:
- parsed(已解析):记录
protocol(如NEC、SIRC、Samsung32、RC5、RC6、Kaseikyo、NECext等)、address与command,体积小、可重复发射; - raw(原始时序):记录
frequency、duty_cycle和一段data脉冲序列,用于无法匹配已知协议的信号。
以 tv.ir 开头部分为例,典型的 parsed 条目如下:
# name: Power type: parsed protocol: SIRC address: 01 00 00 00 command: 15 00 00 00raw 条目则形如:
# name: Power type: raw frequency: 38000 duty_cycle: 0.330000 data: 634 2571 505 519 ...两类条目均由#分隔;文件头部固定为:
Filetype: IR library file Version: 1提示:如果你只是临时测试,也可以完全不碰文件——用 CLI 的
ir rx直接看 Flipper 能否识别信号。详见文末"用 CLI 辅助验证"一节。
电视(Televisions):6 个标准信号
给电视添加万能遥控信号非常简单直接。最多可以录制 6 个信号,其中任一信号在电视不支持时都可以省略:
| 信号名 | 含义 |
|---|---|
Power | 电源开关 |
Mute | 静音 |
Vol_up | 音量加 |
Vol_dn | 音量减 |
Ch_next | 频道下一个 |
Ch_prev | 频道上一个 |
按通用流程录完后,把信号追加到 tv.ir 文件末尾。
从源码看,这个 6 键布局与场景实现完全对应:infrared_scene_universal_tv.c 中依次注册了Power、Mute、Vol_up、Ch_next、Vol_dn、Ch_prev六个记录名(见该文件的infrared_brute_force_add_record调用),界面采用 2 行 × 3 列的按钮面板布局。也就是说,你追加到库里的每个命名信号,都会被绑定到 Universal Remote 电视界面上的固定位置。
音频播放器(Audio Players):8 个标准信号
音频播放器(功放、回音壁、CD 机等)的录制方法与电视完全相同,最多 8 个信号,任一不支持时均可省略:
| 信号名 | 含义 |
|---|---|
Power | 电源开关 |
Play | 播放 |
Pause | 暂停 |
Vol_up | 音量加 |
Vol_dn | 音量减 |
Next | 下一曲 |
Prev | 上一曲 |
Mute | 静音 |
这里有一个常见的实际场景:很多遥控器的Play键同时兼任Pause(播放/暂停二合一)。文档明确要求此时只录成Play,省略Pause,不要重复录制同一个物理按键。
源码中,infrared_scene_universal_audio.c 注册的顺序为Power、Mute、Play、Pause、Prev、Next、Vol_dn、Vol_up。库文件里也确实能看到大量"同键兼任"的注释,例如 audio.ir 中某型号注释为# Also Pause,Play与Pause共用同一组address/command;另一处 Panasonic 型号的注释为# CD play/pause, tape play also exists but probably less commonly used,Play与Pause使用了完全相同的 Kaseikyo 协议地址命令对。这说明"播放/暂停合并"是真实存在的普遍现象,录制时遵循"录Play、略Pause"即可。
同样,验证每个信号的实际功能后,将信号追加到 audio.ir 文件末尾。
投影仪(Projectors):4 个标准信号
投影仪更简单,最多 4 个信号,任一不支持时均可省略:
| 信号名 | 含义 |
|---|---|
Power | 电源开关 |
Mute | 静音 |
Vol_up | 音量加 |
Vol_dn | 音量减 |
文档特别提醒:请确保每个录制信号都已按规范命名,以节省后续排查时间;而对于只提供上述 4 键的投影仪,省略其中不支持的按键一般不会带来问题。录制完成后追加到 projector.ir 末尾。场景侧 infrared_scene_universal_projector.c 注册的顺序即Power、Mute、Vol_up、Vol_dn。
空调(Air Conditioners):状态型设备的特殊录制
空调与大多数红外设备有一个本质区别:它的运行状态由遥控器自身维护。大多数空调遥控器带有一块小显示屏,显示当前模式、设定温度等参数;用户每按一次键,遥控器会把"一整组参数"打包发射给室内机,这些参数必须整体录制、整体使用,不能只录单个键码。
因此空调的录制流程完全不同,需要先"摆好状态",再按下 POWER 让遥控器把整组状态发射出来。要加入万能空调遥控,需录制 6 个信号:Off、Dh、Cool_hi、Cool_lo、Heat_hi、Heat_lo。
除Off外的 5 个信号:按模式逐项录制
对每个信号(除Off)按下述算法操作:
- 拿起遥控器,先按POWER键,使遥控器显示屏显示空调处于开机(ON)状态;
- 将空调设置到下表对应的模式,其余参数(如风速、导风板)若可调则保持在AUTO(自动);
- 按POWER键将空调切换到关机(OFF)状态;
- 在 Flipper 上开始学习新信号(第一个按键时),或按
+添加新按键; - 按提示将遥控器对准 Flipper 的 IR 接收口,再次按下POWER键;
- 将捕获到的信号保存为下表中对应的名称;
- 对下表中每个信号重复步骤 2–6。
| 信号名 | 模式 | 温度 | 备注 |
|---|---|---|---|
Dh | 除湿 Dehumidify | 不适用 N/A | |
Cool_hi | 制冷 Cooling | 见备注 | 制冷模式下可设的最低温度 |
Cool_lo | 制冷 Cooling | 23°C | |
Heat_hi | 制热 Heating | 见备注 | 制热模式下可设的最高温度 |
Heat_lo | 制热 Heating | 23°C |
要点解释:
- 为什么按 POWER 而不按其他键?因为状态型遥控器只有发射瞬间才会把"当前显示屏上整组状态"打包发出,POWER 键是在保持状态不变的情况下触发一次完整发射的最便捷方式。步骤 3 先关机、步骤 5 再开机,是为了让 Flipper 接收到的正是"目标状态"对应的那组参数。
- 温度基准:
Cool_hi/Heat_hi分别取制冷最低温、制热最高温,从而与"强制冷/强制热"的语义对应;Cool_lo/Heat_lo统一用 23°C 作为基准温度。
最后的Off信号
完成上表后,再单独录制Off信号:
- 确认遥控器显示屏显示空调为开机(ON)状态;
- 在 Flipper 上开始学习新信号,将遥控器对准 IR 接收口;
- 按下POWER键,使遥控器切换到关机(OFF)状态;
- 将捕获到的信号保存为
Off。
收尾:6 信号齐备后的验证
录制完毕后,该遥控器在库中应包含6 个信号。你可以省略其中任意一个,但省略后对应功能将无法通过 Flipper 的万能遥控界面使用。请务必对着真实设备逐一测试,确认每个信号都执行了预期动作;全部通过后,将这些信号追加到 ac.ir 文件末尾。
从源码结构看,空调场景 infrared_scene_universal_ac.c 注册的顺序是Off、Dh、Cool_hi、Heat_hi、Cool_lo、Heat_lo,与文档列出的 6 个信号完全一致;而 ac.ir 中每个型号也是以Off、Dh、Cool_hi、Cool_lo、Heat_hi、Heat_lo为一组(个别型号可能缺Dh),且大量条目以 raw 形式保存——这正印证了空调遥控器发射的是"整组参数包",多数情况下无法被简单解析成单一协议码,只能以原始时序存储。
最终提交步骤:注释、追加与 Pull Request
当四类设备中任何一类录制验证完毕,按以下步骤将信号并入固件库:
信号顺序不重要,但每组信号必须用一行注释打头,注明设备型号,以便库保持条理:
# Model: <你的设备型号>例如 audio.ir 中就有
# Model: Yamaha RAV15 and NoName Unknown Audio remote、# Model: Samsung HW-K450 Soundbar、# Model: Panasonic SA-PM193等注释;projector.ir 中也有# Model: Smart、# Model: Epson、# Model: Hitatchi等。注意注释行应紧跟该型号的第一条信号之前,形成"型号注释 + 一组信号"的组织单元。将录得的信号追加到对应类别资产文件的末尾:
- 电视 → tv.ir
- 音频播放器 → audio.ir
- 投影仪 → projector.ir
- 空调 → ac.ir
打开一个包含该变更文件的 Pull Request提交给固件仓库。
需要说明的是:这些.ir资产文件在固件构建期会被打包进 Flipper 的存储镜像(红外应用还通过fap_libs=["assets", "infrared"]依赖资产库,见 application.fam),随固件刷写后位于设备存储的infrared/assets/目录下(场景代码中统一使用EXT_PATH("infrared/assets/xxx.ir")引用)。因此提交 PR 后,你的设备型号会出现在后续固件版本的 Universal Remote 中,供所有用户直接使用。
用 CLI 辅助验证与排查
除了图形界面,固件还提供了ir命令行工具(实现于 infrared_cli.c),可在录制前后快速验证信号,帮助你完成文档要求"确认每个信号做了该做的事"的步骤:
ir rx # 接收并尝试解码信号,输出解析结果 ir rx raw # 接收原始脉冲时序(不进行解码) ir decode <input_file> [<output_file>] # 把 raw 信号文件解码为 parsed 信号 ir universal <remote_name> <signal_name> # 在指定万能遥控库中遍历发送某个信号 ir universal list <remote_name> # 列出指定库文件中存在的全部信号名ir rx内部通过InfraredWorker接收信号,默认启用解码;加raw参数则关闭解码,直接输出原始时序(见 infrared_cli.c);ir universal list会打开EXT_PATH("infrared/assets")/<remote_name>.ir(INFRARED_ASSETS_FOLDER宏定义见 infrared_cli.c),统计并列出其中所有出现过的name字段——用它可以快速核对你的库文件中是否缺少某个规定信号名;ir decode要求输入文件头为IR且Version: 1(校验逻辑见 infrared_cli.c),与资产文件的头格式一致。
借助ir universal list tv之类的命令,你可以在提交 PR 前确认tv.ir中确实包含新追加的型号注释与信号条目,避免把格式错误的文件合入仓库。
附:录制前需要注意的实践要点
- 命名严格一致:追加到库文件中的
name字段必须与文档规定的信号名完全一致(如Vol_up不能写成Volume_up),因为 Universal Remote 场景代码通过infrared_brute_force_add_record()以这些名字为键来遍历库文件;名字对不上,信号将永远不会被发送。 - 格式字段完整:parsed 条目需同时给出
protocol、address、command;raw 条目需给出frequency、duty_cycle、data。Flipper 的库加载器依赖这些字段,缺失或拼写错误会导致条目被跳过。 - 实测优先:文档反复强调"make sure that every signal does what it's supposed to",因为部分遥控器按键存在复用(如 Play/Pause 合一)或"伪按键"(如某些 A/C 遥控器的灯效键与状态无关),仅凭录制成功不能保证功能正确。
遵循以上流程,你就能为 Flipper Zero 的万能遥控器持续贡献新的设备型号,让电视、音响、投影仪与空调的"通用遥控"覆盖越来越广。
【免费下载链接】flipperzero-firmwareFlipper Zero firmware source code项目地址: https://gitcode.com/GitHub_Trending/fl/flipperzero-firmware
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考