
Flipper Zero Python CLI 래퍼
Flipper Zero Python CLI 래퍼

이번 릴리스는 래퍼를 현재 Flipper Zero CLI에 맞게 업데이트합니다
(실제 하드웨어, 펌웨어 unlshd-089e에서 검증됨):
info 모듈: flipper.info.device_info() / power_info() /
power_debug_info() (최신 info device / info power 명령어).power info → info power: flipper.power.info()는 계속 작동하며 이제
내부적으로 info power를 읽습니다. flipper.power.otg_on()/otg_off() 추가됨.date: flipper.date.datetime() 사용; 현재 출력 형식에 맞춰 파싱이 수정됨.KB와 KiB 모두로 파싱되며, read()는 이제
여러 줄의 전체 파일 내용을 반환하고, exFAT / 빈 레이블 카드도 올바르게 파싱됩니다
(#21 수정).NECext,
Kaseikyo, RCA, Pioneer, … 등이 자동으로 지원됩니다 (#15 수정). 새로운
flipper.ir.protocols().debug → sysctl debug, **subghz tx/rx**에 device 인수가
필수로 추가됨, **bt hci_info**는 변경 없음.scan, dump,
emulate, field, apdu, raw, mfu)용으로, UID별 Mifare Classic 키
캐시 헬퍼(import_nfc_keys, write_key_cache) 포함.ps (→ top), music_player, nfc detect.$ pip install pyflipper
unlshd-089e)from pyflipper import PyFlipper
# 로컬 시리얼 포트
flipper = PyFlipper(com="/dev/ttyACM0")
# 또는
# 원격 serial2websocket 서버
flipper = PyFlipper(ws="ws://192.168.1.5:1337")
# TCP
flipper = PyFlipper(tcp='192.168.89.222:22170')
# 정보 (현재 펌웨어에서는 내부적으로 `info power`를 읽음)
info = flipper.power.info()
# 전원 끄기
flipper.power.off()
# 재부팅
flipper.power.reboot()
# DFU 모드로 재부팅
flipper.power.reboot2dfu()
# GPIO 헤더의 5V OTG 핀 토글
flipper.power.otg_on()
flipper.power.otg_off()
# .fuf 파일에서 업데이트 설치
flipper.update.install(fuf_file="/ext/update.fuf")
# Flipper를 .tar 파일로 백업
flipper.update.backup(dest_tar_file="/ext/backup.tar")
# 백업 .tar 파일에서 Flipper 복원
flipper.update.restore(bak_tar_file="/ext/backup.tar")
# 설치된 앱 목록
apps = flipper.loader.list()
# 앱 열기
flipper.loader.open(app_name="Clock")
# Flipper 날짜 가져오기 (datetime 객체)
date = flipper.date.datetime()
# Flipper 타임스탬프 가져오기
timestamp = flipper.date.timestamp()
# 장치 정보 딕셔너리 가져오기 (현재 펌웨어 `info device`, 점으로 구분된 키)
device_info = flipper.info.device_info()
# 전원 정보 딕셔너리 가져오기 (현재 펌웨어 `info power`)
power_info = flipper.info.power_info()
# 확장 전원/게이지 디버그 정보
power_debug = flipper.info.power_debug_info()
# 레거시 `device_info` 명령어 (밑줄로 구분된 키, 계속 지원됨)
legacy_info = flipper.device_info.info()
# 힙 정보 딕셔너리 가져오기
heap = flipper.free.info()
# free_blocks 문자열 가져오기
free_blocks = flipper.free.blocks()
# 블루투스 정보 가져오기
bt_info = flipper.bt.info()
펌웨어 호환성. 이 라이브러리는 이제 현재 Flipper Zero CLI (펌웨어 1.x, Unleashed
unlshd-089e에서 검증됨)를 대상으로 합니다. 몇 가지 레거시 명령어가 공식 펌웨어에서 제거되었으므로 더 이상 사용할 수 없습니다:ps(대화형top으로 대체),music_player,nfc detect(NFC는 이제 대화형 하위 셸입니다).power info는info power로 이동했고,debug는sysctl debug로 이동했으며,storage는 이제 크기를KiB단위로 보고합니다 — 모두 위의 래퍼에서 투명하게 처리됩니다.
# 저장소 파일 시스템 정보 가져오기
ext_info = flipper.storage.info(fs="/ext")
# 저장소 /ext 딕셔너리 가져오기
ext_list = flipper.storage.list(path="/ext")
# 저장소 /ext 트리 딕셔너리 가져오기
ext_tree = flipper.storage.tree(path="/ext")
# 파일 정보 가져오기
file_info = flipper.storage.stat(file="/ext/foo/bar.txt")
# 디렉토리 만들기
flipper.storage.mkdir(new_dir="/ext/foo")
# 파일 읽기
plain_text = flipper.storage.read(file="/ext/foo/bar.txt")
# 파일 제거
flipper.storage.remove(file="/ext/foo/bar.txt")
# 파일 복사
flipper.storage.copy(src="/ext/foo/source.txt", dest="/ext/bar/destination.txt")
# 파일 이름 변경
flipper.storage.rename(file="/ext/foo/bar.txt", new_file="/ext/foo/rab.txt")
# MD5 해시 파일
md5_hash = flipper.storage.md5(file="/ext/foo/bar.txt")
# 한 번에 파일 쓰기
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)
# 리스너를 사용하여 파일 쓰기
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)
# 중지를 잊지 마세요
flipper.storage.write.stop()
# 일반 LED 설정 켜기 (r,b,g,bl)
flipper.led.set(led='r', value=255)
# 파란 LED 끄기
flipper.led.blue(value=0)
# 녹색 LED 값 설정
flipper.led.green(value=175)
# 백라이트 켜기
flipper.led.backlight_on()
# 백라이트 끄기
flipper.led.backlight_off()
# LED 끄기
flipper.led.off()
# 진동 True 또는 False 설정
flipper.vibro.set(True)
# 진동 켜기
flipper.vibro.on()
# 진동 끄기
flipper.vibro.off()
# GPIO 모드 설정: 0 - 입력, 1 - 출력
flipper.gpio.mode(pin_name=PIN_NAME, value=1)
# GPIO 핀 값 설정: 0 - 꺼짐, 1 - 켜짐
flipper.gpio.set(pin_name=PIN_NAME, value=1)
# GPIO 핀 값 읽기
flipper.gpio.read(pin_name=PIN_NAME)
⚠️ 공식 펌웨어에서 제거됨.
music_playerCLI 명령어가 기본 펌웨어에서 제거되었습니다 (이제 앱은 별도의.fap입니다). 이 호출은 명령어를 유지하는 커스텀 펌웨어(예: Unleashed / RogueMaster 빌드)에서 여전히 작동합니다. 기본 펌웨어에서는 "명령어를 찾을 수 없음" 응답을 반환합니다.
# RTTTL 형식으로 노래 재생
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"
# 반복 재생
flipper.music_player.play(rtttl_code=rttl_song)
# 반복 중지
flipper.music_player.stop()
# 20초 동안 재생
flipper.music_player.play(rtttl_code=rttl_song, duration=20)
# 비프음
flipper.music_player.beep()
# 5초 동안 비프음
flipper.music_player.beep(duration=5)
현재 펌웨어에서 NFC는 대화형 하위 셸입니다 (scanner, dump,
emulate, field, apdu, raw, mfu). 이 래퍼는 하위 셸에 진입하여
하나의 명령어를 실행하고 다시 빠져나오므로 각 메서드는 일반적인 블로킹 호출입니다.
detect()는 scan()의 별칭으로 유지됩니다.
# 태그 유형 감지 -> {'protocols': ['Mifare Classic'], 'raw': '...'} 또는 None
tag = flipper.nfc.scan(timeout=5)
# NFC 필드를 몇 초 동안 켜기
flipper.nfc.field(timeout=3)
# APDU 전송 (ISO14443-4 / ISO15693-3); 생략 시 프로토콜 자동 감지
resp = flipper.nfc.apdu(["00A4 04 00", "A0 00"], protocol="14_4a")
# CRC가 추가된 원시 바이트 전송
flipper.nfc.raw("93 20", protocol="14a", crc=True)
# Mifare Ultralight 헬퍼
info = flipper.nfc.mfu_info()
block4 = flipper.nfc.mfu_read_block(4)
flipper.nfc.mfu_write_block(4, "00 01 02 03")
# 저장된 .nfc 파일 에뮬레이션
flipper.nfc.emulate(file="/ext/nfc/mycard.nfc", timeout=10)
CLI dump는 사전 공격을 실행하지 않습니다: UID별 캐시
/ext/nfc/.cache/<UID>.keys (GUI가 성공적인 읽기 후 기록하는 파일)에서 키를 읽습니다.
해당 캐시가 없으면 dump는 *"읽기 실패"*를 반환합니다.
기존 Flipper .nfc 덤프에서 (재)생성할 수 있습니다 — 키는 각 섹터 트레일러에서 가져옵니다:
# 기본 .nfc 덤프에서 UID별 키 캐시로 키 로드
uid, cache_path = flipper.nfc.import_nfc_keys("/path/to/card.nfc")
# 이제 CLI dump가 카드를 읽을 수 있습니다 (프로토콜 토큰: mfc, mfu, 14_4a, ...)
flipper.nfc.dump(protocol="mfc", file="/ext/nfc/card_dump.nfc")
# 동기 기본 타임아웃 5초
# RFID 읽기
rfid = flipper.rfid.read()
# RFID 에뮬레이션
emulated = flipper.rfid.emulate(key_type="EM4100", key_data="5500824806")
# RFID 쓰기
written = flipper.rfid.write(key_type="EM4100", key_data="5500824806")
# hex_key를 N번 전송 (기본 count=10, device=0 -> CC1101_INT, 1 -> CC1101_EXT)
flipper.subghz.tx(hex_key="DEADBEEF", frequency=433920000, count=5, device=0)
# 수신 (기본 frequency=433920000 device=0 raw=False timeout=5초)
received = flipper.subghz.rx(frequency=433920000, device=0, raw=True, timeout=10)
# 기록된 전송 재생
flipper.subghz.tx_from_file("/ext/subghz/foo.sub")
# 원시 .sub 파일 디코딩
decoded = flipper.subghz.decode_raw(sub_file="/ext/subghz/foo.sub")
# 연결된 펌웨어가 지원하는 프로토콜 나열 (도움말에서 실시간 읽기)
protocols = flipper.ir.protocols()
# 프로토콜을 선택하여 hex_address 및 hex_command 전송
flipper.ir.tx(protocol="Samsung32", hex_address="C000FFEE", hex_command="DEADBEEF")
# NECext가 이제 지원됩니다 (프로토콜 목록은 펌웨어에서 읽어오며, 하드코딩되지 않음)
flipper.ir.tx(protocol="NECext", hex_address="EF00", hex_command="FD02")
# 원시 전송 샘플
flipper.ir.tx_raw(frequency=38000, duty_cycle=0.33, samples=[1337, 8888, 3000, 5555])
# 동기 기본 타임아웃 5초
# 수신 tx
r = flipper.ir.rx(timeout=10)
# 읽기 (기본 타임아웃 5초)
ikey = flipper.ikey.read()
# 쓰기 (기본 타임아웃 5초)
flipper.ikey.write(key_type="Dallas", key_data="DEADBEEFCOOOFFEE")
# 에뮬레이션 (기본 타임아웃 5초)
flipper.ikey.emulate(key_type="Dallas", key_data="DEADBEEFCOOOFFEE")
# 이벤트 로거 연결 (기본 타임아웃 10초)
logs = flipper.log.attach()
# 디버그 모드 활성화 (현재 펌웨어에서 `sysctl debug 1` 실행)
flipper.debug.on()
# 디버그 모드 비활성화
flipper.debug.off()
# 검색
response = flipper.onewire.search()
# 가져오기
response = flipper.i2c.get()
# 입력 덤프
dump = flipper.input.dump()
# 입력 보내기
flipper.input.send("up", "press")
테스트 스위트는 두 부분으로 나뉩니다:
test_serial_wrapper.py, test_commands.py)는
어디서나 실행됩니다 — Flipper CLI 프레이밍을 재현한 시뮬레이션된 시리얼 포트
(tests/fake_serial.py)를 통해 라이브러리를 구동하므로 장치가 필요 없습니다.
CI에서 실행됩니다.test_hardware.py)는 실제 Flipper와 통신하며
장치가 연결되지 않으면 자동으로 건너뜁니다.
FLIPPER_COM=/dev/ttyACM0을 설정하여 특정 포트를 지정할 수 있습니다.# 모든 테스트 (하드웨어 테스트는 Flipper가 연결되지 않으면 자동으로 건너뜀)
python -m unittest discover -s tests -p "test_*.py" -v
# 하드웨어 없는 테스트만
python -m unittest tests.test_serial_wrapper tests.test_commands -v
어떤 방식으로든 기여해 주시기 바랍니다
ZEC: zs13zdde4mu5rj5yjm2kt6al5yxz2qjjjgxau9zaxs6np9ldxj65cepfyw55qvfp9v8cvd725f7tz7
ETH: 0xef3cF1Eb85382EdEEE10A2df2b348866a35C6A54
BTC: 15umRZXBzgUacwLVgpLPoa2gv7MyoTrKat