
Wrapper CLI Python para Flipper Zero
Wrapper Python para CLI do Flipper Zero

Esta versão alinha o wrapper com a CLI atual do Flipper Zero (validado em hardware real, firmware unlshd-089e):
info: flipper.info.device_info() / power_info() / power_debug_info() (os comandos modernos info device / info power).power info → info power: flipper.power.info() continua funcionando e agora lê info power internamente. Adicionado flipper.power.otg_on()/otg_off().date: use flipper.date.datetime(); a análise foi corrigida para o formato de saída atual.KB quanto KiB, read() agora retorna o conteúdo completo do arquivo em várias linhas, e cartões exFAT / sem rótulo são analisados corretamente (corrige #21).NECext, Kaseikyo, RCA, Pioneer, … são suportados automaticamente (corrige #15). Novo flipper.ir.protocols().debug → sysctl debug, subghz tx/rx ganhou o argumento device obrigatório, bt hci_info inalterado.scan, dump, emulate, field, apdu, raw, mfu) com auxiliares de cache de chave Mifare Classic por 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')
# Informações (no firmware atual, isto lê `info power` internamente)
info = flipper.power.info()
# Desligar
flipper.power.off()
# Reiniciar
flipper.power.reboot()
# Reiniciar no modo DFU
flipper.power.reboot2dfu()
# Alternar o pino OTG de 5V no cabeçalho GPIO
flipper.power.otg_on()
flipper.power.otg_off()
# Instalar atualização de arquivo .fuf
flipper.update.install(fuf_file="/ext/update.fuf")
# Fazer backup do Flipper para arquivo .tar
flipper.update.backup(dest_tar_file="/ext/backup.tar")
# Restaurar Flipper do arquivo .tar de backup
flipper.update.restore(bak_tar_file="/ext/backup.tar")
# Listar aplicativos instalados
apps = flipper.loader.list()
# Abrir aplicativo
flipper.loader.open(app_name="Clock")
# Obter data do flipper (objeto datetime)
date = flipper.date.datetime()
# Obter timestamp do flipper
timestamp = flipper.date.timestamp()
# Obter dicionário de informações do dispositivo (firmware atual `info device`, chaves separadas por ponto)
device_info = flipper.info.device_info()
# Obter dicionário de informações de energia (firmware atual `info power`)
power_info = flipper.info.power_info()
# Informações estendidas de depuração de energia/medidor
power_debug = flipper.info.power_debug_info()
# Comando legado `device_info` (chaves separadas por sublinhado, ainda suportado)
legacy_info = flipper.device_info.info()
# Obter dicionário de informações de heap
heap = flipper.free.info()
# Obter string free_blocks
free_blocks = flipper.free.blocks()
# Obter informações do Bluetooth
bt_info = flipper.bt.info()
Compatibilidade de firmware. Esta biblioteca agora tem como alvo a CLI atual do Flipper Zero (firmware 1.x, verificado contra Unleashed
unlshd-089e). Alguns comandos legados foram removidos do firmware oficial e, portanto, não estão mais disponíveis:ps(substituído pelotopinterativo),music_playerenfc detect(NFC agora é um sub-shell interativo).power infofoi movido parainfo power,debugfoi movido parasysctl debugestorageagora relata tamanhos emKiB— tudo tratado de forma transparente pelos wrappers acima.
# Obter informações do sistema de arquivos de armazenamento
ext_info = flipper.storage.info(fs="/ext")
# Obter dicionário do armazenamento /ext
ext_list = flipper.storage.list(path="/ext")
# Obter dicionário da árvore do armazenamento /ext
ext_tree = flipper.storage.tree(path="/ext")
# Obter informações do arquivo
file_info = flipper.storage.stat(file="/ext/foo/bar.txt")
# Criar diretório
flipper.storage.mkdir(new_dir="/ext/foo")
# Ler arquivo
plain_text = flipper.storage.read(file="/ext/foo/bar.txt")
# Remover arquivo
flipper.storage.remove(file="/ext/foo/bar.txt")
# Copiar arquivo
flipper.storage.copy(src="/ext/foo/source.txt", dest="/ext/bar/destination.txt")
# Renomear arquivo
flipper.storage.rename(file="/ext/foo/bar.txt", new_file="/ext/foo/rab.txt")
# Arquivo de hash MD5
md5_hash = flipper.storage.md5(file="/ext/foo/bar.txt")
# Escrever arquivo de uma vez
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)
# Escrever arquivo usando um 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()
# Definir led genérico ligado (r,b,g,bl)
flipper.led.set(led='r', value=255)
# Desligar led azul
flipper.led.blue(value=0)
# Definir valor do led verde
flipper.led.green(value=175)
# Ligar retroiluminação
flipper.led.backlight_on()
# Desligar retroiluminação
flipper.led.backlight_off()
# Desligar led
flipper.led.off()
# Definir vibro Verdadeiro ou Falso
flipper.vibro.set(True)
# Ligar vibro
flipper.vibro.on()
# Desligar vibro
flipper.vibro.off()
# Definir modo gpio: 0 - entrada, 1 - saída
flipper.gpio.mode(pin_name=PIN_NAME, value=1)
# Definir valor do pino gpio: 0 - desligado, 1 - ligado
flipper.gpio.set(pin_name=PIN_NAME, value=1)
# Ler valor do pino gpio
flipper.gpio.read(pin_name=PIN_NAME)
⚠️ Removido do firmware oficial. O comando CLI
music_playerfoi removido do firmware padrão (o aplicativo agora é um.fapseparado). Essas chamadas ainda funcionam em firmwares personalizados que mantêm o comando (por exemplo, compilações Unleashed / RogueMaster que o incluem); no firmware oficial, elas retornam uma resposta "comando não encontrado".
# 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)
No firmware atual, o NFC é um sub-shell interativo (scanner, dump, emulate, field, apdu, raw, mfu). Este wrapper entra no sub-shell, executa um comando e sai novamente, portanto cada método é uma chamada de bloqueio normal. detect() é mantido como um alias de scan().
# Detectar o tipo de tag -> {'protocols': ['Mifare Classic'], 'raw': '...'} or None
tag = flipper.nfc.scan(timeout=5)
# Ligar o campo NFC por alguns segundos
flipper.nfc.field(timeout=3)
# Enviar um APDU (ISO14443-4 / ISO15693-3); protocolo auto-detectado se omitido
resp = flipper.nfc.apdu(["00A4 04 00", "A0 00"], protocol="14_4a")
# Enviar bytes brutos com CRC anexado
flipper.nfc.raw("93 20", protocol="14a", crc=True)
# Auxiliares Mifare Ultralight
info = flipper.nfc.mfu_info()
block4 = flipper.nfc.mfu_read_block(4)
flipper.nfc.mfu_write_block(4, "00 01 02 03")
# Emular um arquivo .nfc salvo
flipper.nfc.emulate(file="/ext/nfc/mycard.nfc", timeout=10)
O dump da CLI não executa um ataque de dicionário: ele lê as chaves de um cache por UID em /ext/nfc/.cache/<UID>.keys (o arquivo que a GUI escreve após uma leitura bem-sucedida). Se esse cache estiver ausente, dump retorna "falha ao ler". Você pode (re)criá-lo a partir de um despejo .nfc existente do Flipper — as chaves são obtidas de cada setor trailer:
# Carregar chaves de um despejo .nfc nativo para o cache de chave por UID
uid, cache_path = flipper.nfc.import_nfc_keys("/path/to/card.nfc")
# Agora o dump da CLI pode ler o cartão (tokens de protocolo: mfc, mfu, 14_4a, ...)
flipper.nfc.dump(protocol="mfc", file="/ext/nfc/card_dump.nfc")
# Timeout síncrono padrão de 5 segundos
# Ler RFID
rfid = flipper.rfid.read()
# Emular RFID
emulated = flipper.rfid.emulate(key_type="EM4100", key_data="5500824806")
# Escrever RFID
written = flipper.rfid.write(key_type="EM4100", key_data="5500824806")
# Transmitir hex_key N vezes (padrão count=10, device=0 -> CC1101_INT, 1 -> CC1101_EXT)
flipper.subghz.tx(hex_key="DEADBEEF", frequency=433920000, count=5, device=0)
# Receber (padrão frequency=433920000 device=0 raw=False timeout=5 segundos)
received = flipper.subghz.rx(frequency=433920000, device=0, raw=True, timeout=10)
# Reproduzir transmissão gravada
flipper.subghz.tx_from_file("/ext/subghz/foo.sub")
# Decodificar arquivo .sub bruto
decoded = flipper.subghz.decode_raw(sub_file="/ext/subghz/foo.sub")
# Listar os protocolos suportados pelo firmware conectado (lido ao vivo da ajuda do `ir`)
protocols = flipper.ir.protocols()
# Transmitir hex_address e hex_command selecionando um protocolo
flipper.ir.tx(protocol="Samsung32", hex_address="C000FFEE", hex_command="DEADBEEF")
# NECext agora é suportado (lista de protocolos é lida do firmware, não codificada)
flipper.ir.tx(protocol="NECext", hex_address="EF00", hex_command="FD02")
# Amostras de transmissão bruta
flipper.ir.tx_raw(frequency=38000, duty_cycle=0.33, samples=[1337, 8888, 3000, 5555])
# Timeout síncrono padrão de 5 segundos
# Receber tx
r = flipper.ir.rx(timeout=10)
# Ler (timeout padrão de 5 segundos)
ikey = flipper.ikey.read()
# Escrever (timeout padrão de 5 segundos)
flipper.ikey.write(key_type="Dallas", key_data="DEADBEEFCOOOFFEE")
# Emular (timeout padrão de 5 segundos)
flipper.ikey.emulate(key_type="Dallas", key_data="DEADBEEFCOOOFFEE")
# Anexar registrador de eventos (timeout padrão de 10 segundos)
logs = flipper.log.attach()
# Ativar modo de depuração (emite `sysctl debug 1` no firmware atual)
flipper.debug.on()
# Desativar modo de depuração
flipper.debug.off()
# Pesquisar
response = flipper.onewire.search()
# Obter
response = flipper.i2c.get()
# Despejo de entrada
dump = flipper.input.dump()
# Enviar entrada
flipper.input.send("up", "press")
O conjunto é dividido em dois:
test_serial_wrapper.py, test_commands.py) executam em qualquer lugar — eles direcionam a biblioteca contra uma porta serial simulada (tests/fake_serial.py) que reproduz o enquadramento da CLI do Flipper, portanto nenhum dispositivo é necessário. Estes são executados no CI.test_hardware.py) conversam com um Flipper real e são pulados automaticamente quando nenhum dispositivo está conectado. Defina FLIPPER_COM=/dev/ttyACM0 para fixar uma porta específica.# 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
Sinta-se à vontade para contribuir de qualquer forma
ZEC: zs13zdde4mu5rj5yjm2kt6al5yxz2qjjjgxau9zaxs6np9ldxj65cepfyw55qvfp9v8cvd725f7tz7
ETH: 0xef3cF1Eb85382EdEEE10A2df2b348866a35C6A54
BTC: 15umRZXBzgUacwLVgpLPoa2gv7MyoTrKat