A “drop-in” Home Assistant add-on that turns a folder of replay files into Home Assistant button entities.
Drop files into a directory (and optional subfolders), and CatFlap will:
- Publish MQTT Discovery button entities automatically
- Subscribe for button presses (payload
PRESS) - Transmit the selected capture using an RFCat-compatible CC1111 dongle (e.g., Yard Stick One)
You are responsible for complying with all applicable laws and regulations. RF transmission rules vary by country, region, frequency band, power level, and licensing. Only transmit signals you are authorized to transmit, and only on frequencies you are legally allowed to use.
- MQTT Auto-Discovery: Buttons appear automatically in Home Assistant (no YAML).
- Folder → Device grouping:
- Files in the root directory become a “Misc Files” device
- Each subfolder becomes its own device in Home Assistant
- Icons (optional): Set per-folder/per-file MDI icons using
.mdi-iconand.iconfiles (with sensible defaults). - Supported replay formats:
- Flipper Zero Sub-GHz
.subfiles withRAW_Data .rfcat.jsonfor explicit RFCat/rflib settings + payload
- Flipper Zero Sub-GHz
- Retained discovery + cleanup: Removed files are removed from Home Assistant automatically (stale discovery topics are deleted).
- Bridge Status entity: Publishes a “Bridge Status” binary sensor to show when the add-on is running.
-
CatFlap scans
sub_directoryfor supported files (.sub,.rfcat.json). -
For each replay file, CatFlap publishes a Home Assistant MQTT Discovery “button” with a
command_topic. -
When you press a button in Home Assistant, HA publishes
PRESSto that topic. -
CatFlap receives the
PRESS, parses the file, configures RFCat modem settings, and transmits the replay via CC1111.
- Add this repository in Home Assistant:
Settings → Add-ons → Add-on Store → ⋮ → Repositories
-
Install CatFlap, configure MQTT, and start it.
-
Put replay files here:
/share/tx_files
Optional: group into folders:
/share/tx_files/light//share/tx_files/garage//share/tx_files/outlet/
CatFlap reads src/config.json.
- Copy the example config:
cp config.json.example src/config.json
-
Edit
src/config.json(MQTT + folder) -
Run the container with USB access to your CC1111 device.
python -m venv venv
. venv/bin/activate
pip install -r requirements.txt
python -m src.mainIn the add-on UI you’ll set:
mqtt_broker(e.g.core-mosquittoor an IP)mqtt_port(default1883)mqtt_user/mqtt_passwordnode_id(defaultcatflap) — becomes the base MQTT topic (e.g.catflap/...)sub_directory(default/share/tx_files)tx_power(defaultmax) — CC1111 transmit power for all replays:max(or empty): call RFCatsetMaxPower()before transmittingdefault/auto: don’t change power registers (use the dongle’s current setting)- a number like
8or0x08: call RFCatsetPower(<value>)/setTxPower(<value>)
CatFlap supports four transmit-power modes:
tx_power_mode: smart(default) — band + target dBm → PATABLE code using the TI reference table belowtx_power_mode: max— calls rflibsetMaxPower()(quick “just make it work” option)tx_power_mode: default— leaves the dongle’s current power configuration untouchedtx_power_mode: manual— programs FREND0 + PATABLE directly (advanced)
Smart mode is the “human readable” interface:
tx_power_target_dbmpicks a target output level from the TI tabletx_power_band: autoinfers the band bucket (315/433/868/915) from the replay file’s TX frequency
Example:
tx_power_mode: smart
tx_power_target_dbm: 0
tx_power_band: auto
Lookup table (hex value with decimal in parentheses):
| Target output (dBm) | 315 MHz | 433 MHz | 868 MHz | 915 MHz |
|---|---|---|---|---|
| -30 | 0x12 (18) |
0x12 (18) |
0x03 (3) |
0x03 (3) |
| -20 | 0x0D (13) |
0x0E (14) |
0x0E (14) |
0x0D (13) |
| -15 | 0x1C (28) |
0x1D (29) |
0x1E (30) |
0x1D (29) |
| -10 | 0x34 (52) |
0x34 (52) |
0x27 (39) |
0x26 (38) |
| -5 | 0x2B (43) |
0x2C (44) |
0x8F (143) |
0x57 (87) |
| 0 | 0x51 (81) |
0x60 (96) |
0x50 (80) |
0x8E (142) |
| 5 | 0x85 (133) |
0x84 (132) |
0x84 (132) |
0x83 (131) |
| 7 | 0xCB (203) |
0xC8 (200) |
0xCB (203) |
0xC7 (199) |
| 10 | 0xC2 (194) |
0xC0 (192) |
0xC2 (194) |
0xC0 (192) |
Notes:
- Output power is approximate: real dBm depends on band, matching network, antenna, board layout, and supply voltage.
- Some PA settings are discouraged/invalid on certain boards; treat the table as starting points, not a calibrated RF power meter.
Manual mode exposes the CC111x fields that drive TX output:
frend0_pa_power(0–7): sets FREND0.PA_POWER[2:0] (selects the PATABLE index used for TX power)frend0_lodiv_buf_current_tx(0–3): sets FREND0.LODIV_BUF_CURRENT_TX[1:0] (TX LO buffer current)patable: sets PA_TABLE0..7 (PA shaping/ramp and output level codes)
How CatFlap treats patable:
- A single value like
"0xC0"is treated as a convenience “ON level”- For ASK/OOK, CatFlap forces
PA_TABLE0 = 0x00and fills indices1..PA_POWERwith the ON value - For FSK/GFSK/MSK, CatFlap fills indices
0..PA_POWERwith the ON value
- For ASK/OOK, CatFlap forces
- A comma list (up to 8 values) defines an explicit shaping/ramp table
For further information, please refer to cc1110-cc1111 data sheet
Once running, buttons will appear in Home Assistant under MQTT devices.
Expected log snippets:
[MQTT] Connecting to core-mosquitto:1883 ...
[MQTT] Connected
[Files] Mapped 12 replay topics
[MQTT] Trigger: catflap/door/front_door/set
[RfCat] Replaying front_door.sub
[RfCat] Transmission complete
CatFlap can assign Material Design Icons (MDI) to the entities it creates via MQTT Discovery.
Icon resolution order (highest priority first):
- Per-file override: a sidecar icon file next to the replay file
- Per-folder default: a
.mdi-iconfile in the folder (inherited by subfolders) - Name-based defaults: common keywords like
door,garage,gate,light, etc. - Fallback:
mdi:radio-tower
Create a file named .mdi-icon inside /share/tx_files/ or any subfolder. The first line is the icon:
- Either
mdi:garageor justgarage(it will be normalized tomdi:garage)
The nearest .mdi-icon wins, so subfolders inherit the closest parent.
Example:
/share/tx_files/.mdi-icon
/share/tx_files/garage/.mdi-icon
# /share/tx_files/.mdi-icon
mdi:radio-tower
# /share/tx_files/garage/.mdi-icon
mdi:garage
To override one button, create a sidecar file next to the replay file:
front_door.icon(preferred)- or
front_door.sub.icon
Example:
/share/tx_files/doors/front_door.sub
/share/tx_files/doors/front_door.icon
# /share/tx_files/doors/front_door.icon
mdi:door
The gateway’s Bridge Status entity uses device_info.default_entity_icon as its default (fallback: mdi:radio-tower).
If you want the gateway to be a cat while keeping most buttons as radio-tower, set:
device_info.default_entity_icon=mdi:cat- and create
/share/tx_files/.mdi-iconwithmdi:radio-tower
Example config snippet:
{
"device_info": {
"default_entity_icon": "mdi:cat"
}
}CatFlap supports .sub files only when they include Frequency: and RAW_Data:.
Minimal example:
Filetype: Flipper SubGhz Key File
Version: 1
Frequency: 433920000
Protocol: RAW
RAW_Data: 350 -700 350 -700 350 -700
Use this when you want explicit RFCat/rflib settings.
Example:
{
"frequency": 433920000,
"modulation": "ASK_OOK",
"repeat": 5,
"drate": 4800,
"payload_hex": "deadbeef"
}Supported payload inputs (choose one):
payload_hexpayload_b64payload(list of ints 0–255)raw_durations_us(list of pulse durations; positive = high, negative = low)
Optional RF settings:
modulation(ASK_OOK,2FSK,GFSK,MSK)repeat,drate,deviation,syncmode,preamble,manchester,max_powerinvert_level,msb_first,max_gap_us(for raw duration conversion)
No buttons appear
- Confirm the MQTT integration works and you have a broker configured
- Check add-on logs
- Verify the files exist under
/share/tx_files(and have the supported extensions)
“No Dongle Found” / transmit fails
- Confirm the CC1111 dongle is connected and supported by RFCat/rflib
- Restart the add-on after plugging in the dongle
- If you’re running outside HA, make sure the container has USB access
Entities won’t disappear after deleting files
- CatFlap uses retained MQTT discovery and cleans up stale topics automatically
- If you want a clean slate, delete the cache file (if used) and restart:
/share/.discovery_cache.json
CatFlap scans your TX folder and creates Home Assistant button entities for supported files. Pressing a button publishes an MQTT message that triggers CatFlap to transmit the matching signal via your RFCat-compatible dongle.
Supported file types:
.sub— Flipper Zero RAW replays.rfcat.json— CatFlap/RFCat JSON replays.py— optional Python TX “macros” (disabled by default)
You can organize files into subfolders. Each subfolder becomes its own “device” in Home Assistant:
/share/tx_files/
garage/
open.sub
close.rfcat.json
lights/
porch.sub
You can create a .py file to run multi-step sequences (macros), delays, or conditional logic.
.py buttons unless you explicitly enable them.
In the add-on config:
allow_python_scripts: truepython_timeout_s: 30(script execution timeout)
Example:
allow_python_scripts: true
python_timeout_s: 30A TX script can work in any of these ways:
- Define
run(ctx)ormain(ctx)(recommended):
def run(ctx):
ctx.tx_file("open.rfcat.json", repeat=3)
ctx.sleep(0.25)
ctx.tx_file("open.rfcat.json", repeat=3)- Export
TX = {...}orTX = [{...}, {...}]
Each dict is passed to the transmitter (and merged with your global RF power settings):
TX = [
{"freq": 433920000, "payload_hex": "A1B2C3D4", "repeat": 5},
{"freq": 433920000, "payload_hex": "A1B2C3D5", "repeat": 2}
]- Use
ctxhelpers directly (norun()needed)
A globalctxis available while the script runs.
ctx.log("message")ctx.sleep(seconds)ctx.tx_file("relative/or/absolute/path.sub", repeat=3, ...)ctx.tx_hex(freq_hz, "A1B2C3...", repeat=3, ...)ctx.tx_b64(freq_hz, "base64...", repeat=3, ...)
Paths in ctx.tx_file() are relative to the script’s folder, so you can build macros next to the files they replay.