
Wrapper CLI Python per Flipper Zero
Wrapper CLI Python per Flipper Zero

Questa release allinea il wrapper alla CLI corrente di Flipper Zero (validato su hardware reale, firmware unlshd-089e):
info: flipper.info.device_info() / power_info() / power_debug_info() (i comandi moderni info device / info power).power info → info power: flipper.power.info() continua a funzionare e ora legge info power internamente. Aggiunto flipper.power.otg_on()/otg_off().date: usa flipper.date.datetime(); il parsing è stato corretto per il formato di output corrente.KB che KiB, read() ora restituisce il contenuto completo del file su più righe, e le schede exFAT / con etichetta vuota vengono interpretate correttamente (risolve #21).NECext, Kaseikyo, RCA, Pioneer, … sono supportati automaticamente (risolve #15). Nuovo flipper.ir.protocols().debug → sysctl debug, subghz tx/rx ha acquisito l'argomento device richiesto, bt hci_info invariato.scan, dump, emulate, field, apdu, raw, mfu) con helper per la cache delle chiavi Mifare Classic per UID (import_nfc_keys, write_key_cache).ps (→ top), music_player, nfc detect.$ pip install pyflipper
unlshd-089e)from pyflipper import PyFlipper
# Local serial port
flipper = PyFlipper(com="/dev/ttyACM0")
# OR
# Remote serial2websocket server
flipper = PyFlipper(ws="ws://192.168.1.5:1337")
# TCP
flipper = PyFlipper(tcp='192.168.89.222:22170')
# Info (on current firmware this reads `info power` under the hood)
info = flipper.power.info()
# Poweroff
flipper.power.off()
# Reboot
flipper.power.reboot()
# Reboot in DFU mode
flipper.power.reboot2dfu()
# Toggle the 5V OTG pin on the GPIO header
flipper.power.otg_on()
flipper.power.otg_off()
# Install update from .fuf file
flipper.update.install(fuf_file="/ext/update.fuf")
# Backup Flipper to .tar file
flipper.update.backup(dest_tar_file="/ext/backup.tar")
# Restore Flipper from backup .tar file
flipper.update.restore(bak_tar_file="/ext/backup.tar")
# List installed apps
apps = flipper.loader.list()
# Open app
flipper.loader.open(app_name="Clock")
# Get flipper date (datetime object)
date = flipper.date.datetime()
# Get flipper timestamp
timestamp = flipper.date.timestamp()
# Get device info dict (current firmware `info device`, dot-separated keys)
device_info = flipper.info.device_info()
# Get power info dict (current firmware `info power`)
power_info = flipper.info.power_info()
# Extended power/gauge debug info
power_debug = flipper.info.power_debug_info()
# Legacy `device_info` command (underscore-separated keys, still supported)
legacy_info = flipper.device_info.info()
# Get heap info dict
heap = flipper.free.info()
# Get free_blocks string
free_blocks = flipper.free.blocks()
# Get bluetooth info
bt_info = flipper.bt.info()
Compatibilità firmware. Questa libreria è ora pensata per la CLI corrente di Flipper Zero (firmware 1.x, verificata su Unleashed
unlshd-089e). Alcuni comandi legacy sono stati rimossi dal firmware ufficiale e quindi non sono più disponibili:ps(sostituito datopinterattivo),music_playerenfc detect(NFC è ora una sub-shell interattiva).power infoè stato spostato suinfo power,debugsusysctl debugestorageora riporta le dimensioni inKiB— tutto gestito in modo trasparente dai wrapper sopra.
# Get the storage filesystem info
ext_info = flipper.storage.info(fs="/ext")
# Get the storage /ext dict
ext_list = flipper.storage.list(path="/ext")
# Get the storage /ext tree dict
ext_tree = flipper.storage.tree(path="/ext")
# Get file info
file_info = flipper.storage.stat(file="/ext/foo/bar.txt")
# Make directory
flipper.storage.mkdir(new_dir="/ext/foo")
# Read file
plain_text = flipper.storage.read(file="/ext/foo/bar.txt")
# Remove file
flipper.storage.remove(file="/ext/foo/bar.txt")
# Copy file
flipper.storage.copy(src="/ext/foo/source.txt", dest="/ext/bar/destination.txt")
# Rename file
flipper.storage.rename(file="/ext/foo/bar.txt", new_file="/ext/foo/rab.txt")
# MD5 Hash file
md5_hash = flipper.storage.md5(file="/ext/foo/bar.txt")
# Write file in one chunk
file = "/ext/bar.txt"
text = """There are many variations of passages of Lorem Ipsum available,
but the majority have suffered alteration in some form, by injected humour,
or randomised words which don't look even slightly believable.
If you are going to use a passage of Lorem Ipsum,
you need to be sure there isn't anything embarrassing hidden in the middle of text.
"""
flipper.storage.write.file(path=file, text=text)
# Write file using a listener
file = "/ext/foo.txt"
text_one = """There are many variations of passages of Lorem Ipsum available,
but the majority have suffered alteration in some form, by injected humour,
or randomised words which don't look even slightly believable.
If you are going to use a passage of Lorem Ipsum,
you need to be sure there isn't anything embarrassing hidden in the middle of text.
"""
flipper.storage.write.start(file)
time.sleep(2)
flipper.storage.write.send(text_one)
text_two = """All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as
necessary, making this the first true generator on the Internet.
It uses a dictionary of over 200 Latin words, combined with a handful of
model sentence structures, to generate Lorem Ipsum which looks reasonable.
The generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.
"""
flipper.storage.write.send(text_two)
time.sleep(3)
# Don't forget to stop
flipper.storage.write.stop()
# Set generic led on (r,b,g,bl)
flipper.led.set(led='r', value=255)
# Set blue led off
flipper.led.blue(value=0)
# Set green led value
flipper.led.green(value=175)
# Set backlight on
flipper.led.backlight_on()
# Set backlight off
flipper.led.backlight_off()
# Turn off led
flipper.led.off()
# Set vibro True or False
flipper.vibro.set(True)
# Set vibro on
flipper.vibro.on()
# Set vibro off
flipper.vibro.off()
# Set gpio mode: 0 - input, 1 - output
flipper.gpio.mode(pin_name=PIN_NAME, value=1)
# Set gpio pin value: 0 - off, 1 - on
flipper.gpio.set(pin_name=PIN_NAME, value=1)
# Read gpio pin value
flipper.gpio.read(pin_name=PIN_NAME)
⚠️ Rimosso dal firmware ufficiale. Il comando CLI
music_playerè stato eliminato dal firmware stock (l'app è ora un.fapseparato). Queste chiamate funzionano ancora su firmware personalizzati che mantengono il comando (ad es. versioni Unleashed / RogueMaster che lo includono); sul firmware stock restituiscono una risposta "comando non trovato".
# Play song in RTTTL format
rttl_song = "Littleroot Town - Pokemon:d=4,o=5,b=100:8c5,8f5,8g5,4a5,8p,8g5,8a5,8g5,8a5,8a#5,8p,4c6,8d6,8a5,8g5,8a5,8c#6,4d6,4e6,4d6,8a5,8g5,8f5,8e5,8f5,8a5,4d6,8d5,8e5,2f5,8c6,8a#5,8a#5,8a5,2f5,8d6,8a5,8a5,8g5,2f5,8p,8f5,8d5,8f5,8e5,4e5,8f5,8g5"
# Play in loop
flipper.music_player.play(rtttl_code=rttl_song)
# Stop loop
flipper.music_player.stop()
# Play for 20 seconds
flipper.music_player.play(rtttl_code=rttl_song, duration=20)
# Beep
flipper.music_player.beep()
# Beep for 5 seconds
flipper.music_player.beep(duration=5)
Sul firmware corrente, NFC è una sub-shell interattiva (scanner, dump, emulate, field, apdu, raw, mfu). Questo wrapper entra nella sub-shell, esegue un comando e ne esce nuovamente, quindi ogni metodo è una normale chiamata bloccante. detect() è mantenuto come alias di scan().
# Detect the tag type -> {'protocols': ['Mifare Classic'], 'raw': '...'} or None
tag = flipper.nfc.scan(timeout=5)
# Turn the NFC field on for a few seconds
flipper.nfc.field(timeout=3)
# Send an APDU (ISO14443-4 / ISO15693-3); protocol auto-detected if omitted
resp = flipper.nfc.apdu(["00A4 04 00", "A0 00"], protocol="14_4a")
# Send raw bytes with CRC appended
flipper.nfc.raw("93 20", protocol="14a", crc=True)
# Mifare Ultralight helpers
info = flipper.nfc.mfu_info()
block4 = flipper.nfc.mfu_read_block(4)
flipper.nfc.mfu_write_block(4, "00 01 02 03")
# Emulate a saved .nfc file
flipper.nfc.emulate(file="/ext/nfc/mycard.nfc", timeout=10)
Il comando CLI dump non esegue un attacco dizionario: legge le chiavi da una cache per UID in /ext/nfc/.cache/<UID>.keys (il file che la GUI scrive dopo una lettura riuscita). Se quella cache è assente, dump restituisce "failed to read". Puoi (ri)crearla partendo da un dump .nfc esistente di Flipper — le chiavi vengono prese dal trailer di ogni settore:
# Load keys from a native .nfc dump into the per-UID key cache
uid, cache_path = flipper.nfc.import_nfc_keys("/path/to/card.nfc")
# Now the CLI dump can read the card (protocol tokens: mfc, mfu, 14_4a, ...)
flipper.nfc.dump(protocol="mfc", file="/ext/nfc/card_dump.nfc")
# Synchronous default timeout 5 seconds
# Read RFID
rfid = flipper.rfid.read()
# Emulate RFID
emulated = flipper.rfid.emulate(key_type="EM4100", key_data="5500824806")
# Write RFID
written = flipper.rfid.write(key_type="EM4100", key_data="5500824806")
# Transmit hex_key N times (default count=10, device=0 -> CC1101_INT, 1 -> CC1101_EXT)
flipper.subghz.tx(hex_key="DEADBEEF", frequency=433920000, count=5, device=0)
# Receive (default frequency=433920000 device=0 raw=False timeout=5 seconds)
received = flipper.subghz.rx(frequency=433920000, device=0, raw=True, timeout=10)
# Replay recorded transmission
flipper.subghz.tx_from_file("/ext/subghz/foo.sub")
# Decode raw .sub file
decoded = flipper.subghz.decode_raw(sub_file="/ext/subghz/foo.sub")
# List the protocols supported by the connected firmware (read live from `ir` help)
protocols = flipper.ir.protocols()
# Transmit hex_address and hex_command selecting a protocol
flipper.ir.tx(protocol="Samsung32", hex_address="C000FFEE", hex_command="DEADBEEF")
# NECext is now supported (protocol list is read from the firmware, not hardcoded)
flipper.ir.tx(protocol="NECext", hex_address="EF00", hex_command="FD02")
# Raw Transmit samples
flipper.ir.tx_raw(frequency=38000, duty_cycle=0.33, samples=[1337, 8888, 3000, 5555])
# Synchronous default timeout 5 seconds
# Receive tx
r = flipper.ir.rx(timeout=10)
# Read (default timeout 5 seconds)
ikey = flipper.ikey.read()
# Write (default timeout 5 seconds)
flipper.ikey.write(key_type="Dallas", key_data="DEADBEEFCOOOFFEE")
# Emulate (default timeout 5 seconds)
flipper.ikey.emulate(key_type="Dallas", key_data="DEADBEEFCOOOFFEE")
# Attach event logger (default timeout 10 seconds)
logs = flipper.log.attach()
# Activate debug mode (issues `sysctl debug 1` on current firmware)
flipper.debug.on()
# Deactivate debug mode
flipper.debug.off()
# Search
response = flipper.onewire.search()
# Get
response = flipper.i2c.get()
# Input dump
dump = flipper.input.dump()
# Send input
flipper.input.send("up", "press")
La suite è divisa in due:
test_serial_wrapper.py, test_commands.py) funzionano ovunque — guidano la libreria contro una porta seriale simulata (tests/fake_serial.py) che riproduce il framing della CLI di Flipper, quindi non è richiesto alcun dispositivo. Questi vengono eseguiti in CI.test_hardware.py) comunicano con un Flipper reale e vengono saltati automaticamente quando nessun dispositivo è connesso. Imposta FLIPPER_COM=/dev/ttyACM0 per fissare una porta specifica.# Everything (hardware tests self-skip if no Flipper is attached)
python -m unittest discover -s tests -p "test_*.py" -v
# Only the hardware-free tests
python -m unittest tests.test_serial_wrapper tests.test_commands -v
Sentiti libero di contribuire in qualsiasi modo
ZEC: zs13zdde4mu5rj5yjm2kt6al5yxz2qjjjgxau9zaxs6np9ldxj65cepfyw55qvfp9v8cvd725f7tz7
ETH: 0xef3cF1Eb85382EdEEE10A2df2b348866a35C6A54
BTC: 15umRZXBzgUacwLVgpLPoa2gv7MyoTrKat