# PyFlipper
Unoffical Flipper Zero cli wrapper written in Python
![](https://thumb.tildacdn.com/tild3332-3839-4061-b663-363464303432/-/resize/214x/-/format/webp/noroot.png)
## Articles
- [How to hack a restaurant](https://medium.com/@nic_whr/how-to-hack-a-restaurant-5d394be105a9)
## Functions and characteristics:
- [x] Flipper serial CLI wrapper
- [x] Websocket client interface
## Setup instructions:
```bash
$ pip install pyflipper
```
### Tested on:
- [x] Python 3.8.10 on Linux 5.4.0 x86_64
- [x] Python 3.9.10 on Windows 10
- [x] Python 3.10.5 on Android 12 (Termux + [OTGSerial2WebSocket](https://play.google.com/store/apps/details?id=com.wh00hw.serial2websocket) NO ROOT REQUIRED)
## Usage/Examples
### Connection
```python
from pyflipper.pyflipper import PyFlipper
#Local serial port
flipper = PyFlipper(com="/dev/ttyACM0")
#OR
#Remote serial2websocket server
flipper = PyFlipper(ws="ws://192.168.1.5:1337")
```
### Power
```python
#Info
info = flipper.power.info()
#Poweroff
flipper.power.off()
#Reboot
flipper.power.reboot()
#Reboot in DFU mode
flipper.power.reboot2dfu()
```
### Update/Backup
```python
#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")
```
### Loader
```python
#List installed apps
apps = flipper.loader.list()
#Open app
flipper.loader.open(app_name="Clock")
```
### Flipper Info
```python
#Get flipper date
date = flipper.date.date()
#Get flipper timestamp
timestamp = flipper.date.timestamp()
#Get the processes dict list
ps = flipper.ps.list()
#Get device info dict
device_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()
```
### Storage
#### Filesystem Info
```python
#Get the storage filesystem info
ext_info = flipper.storage.info(fs="/ext")
```
#### Explorer
```python
#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")
```
#### Files
```python
#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(file, 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()
```
### LED/Backlight
```python
#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()
```
### Vibro
```python
#Set vibro True or False
flipper.vibro.set(True)
#Set vibro on
flipper.vibro.on()
#Set vibro off
flipper.vibro.off()
```
### GPIO
```python
#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)
```
### MusicPlayer
```python
#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)
```
### NFC
```python
#Synchronous default timeout 5 seconds
#Detect NFC
nfc_detected = flipper.nfc.detect()
#Emulate NFC
flipper.nfc.emulate()
#Activate field
flipper.nfc.field()
```
### RFID
```python
#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")
```
### SubGhz
```python
#Transmit hex_key N times(default count = 10)
flipper.subghz.tx(hex_key="DEADBEEF", frequency=433920000, count=5)
#Receive (default frequency=433920000 raw=False timeout=5 seconds)
received = flipper.subghz.rx(frequency="433920000", raw=True, timeout=10)
#Decode raw .sub file
decoded = flipper.subghz.decode_raw(sub_file="/ext/subghz/foo.sub")
```
### Infrared
```python
#Transmit hex_address and hex_command selecting a protocol
flipper.ir.tx(protocol="Samsung32", hex_address="C000FFEE", hex_command="DEADBEEF")
#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)
```
### IKEY
```python
#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")
```
### Log
```python
#Attach event logger (default timeout 10 seconds)
logs = flipper.log.attach()
```
### Debug
```python
#Activate debug mode
flipper.debug.on()
#Deactivate debug mode
flipper.debug.off()
```
### Onewire
```python
#Search
response = flipper.onewire.search()
```
### I2C
```python
#Get
response = flipper.i2c.get()
```
### Input
```python
#Input dump
dump = flipper.input.dump()
#Send input
flipper.input.send("up", "press")
```
## Optimizations
Feel free to contribute in any way
- [ ] Queue Thread orchestrator
- [ ] Implement all the cli functions
- [ ] Async SubGhz Chat
## License
[MIT](https://choosealicense.com/licenses/mit/)
## Buy me a pint
**ZEC:** zs13zdde4mu5rj5yjm2kt6al5yxz2qjjjgxau9zaxs6np9ldxj65cepfyw55qvfp9v8cvd725f7tz7
**ETH:** 0xef3cF1Eb85382EdEEE10A2df2b348866a35C6A54
**BTC:** 15umRZXBzgUacwLVgpLPoa2gv7MyoTrKat
## Contacts
- **Discord**: white_rabbit#4124
- **Twitter**: @nic_whr
- **GPG**: 0x94EDEADC
Raw data
{
"_id": null,
"home_page": "https://github.com/wh00hw/pyFlipper",
"name": "pyflipper",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "flipper,wrapper,module",
"author": "wh00hw",
"author_email": "white_rabbit@autistici.org",
"download_url": "https://files.pythonhosted.org/packages/9c/3c/bac47fc70c9b74ad32e8eb11da478de270f861373812ba88e5ccabf05555/pyflipper-0.18.tar.gz",
"platform": null,
"description": "# PyFlipper\n\nUnoffical Flipper Zero cli wrapper written in Python\n\n![](https://thumb.tildacdn.com/tild3332-3839-4061-b663-363464303432/-/resize/214x/-/format/webp/noroot.png)\n\n## Articles\n- [How to hack a restaurant](https://medium.com/@nic_whr/how-to-hack-a-restaurant-5d394be105a9)\n\n## Functions and characteristics:\n - [x] Flipper serial CLI wrapper\n - [x] Websocket client interface\n\n## Setup instructions:\n\n```bash\n$ pip install pyflipper\n```\n### Tested on:\n - [x] Python 3.8.10 on Linux 5.4.0 x86_64\n - [x] Python 3.9.10 on Windows 10\n - [x] Python 3.10.5 on Android 12 (Termux + [OTGSerial2WebSocket](https://play.google.com/store/apps/details?id=com.wh00hw.serial2websocket) NO ROOT REQUIRED)\n\n## Usage/Examples\n\n### Connection\n\n```python\nfrom pyflipper.pyflipper import PyFlipper\n\n#Local serial port\nflipper = PyFlipper(com=\"/dev/ttyACM0\")\n\n#OR \n\n#Remote serial2websocket server\nflipper = PyFlipper(ws=\"ws://192.168.1.5:1337\")\n```\n### Power\n\n```python\n#Info\ninfo = flipper.power.info()\n\n#Poweroff\nflipper.power.off()\n\n#Reboot\nflipper.power.reboot()\n\n#Reboot in DFU mode\nflipper.power.reboot2dfu()\n```\n### Update/Backup\n\n```python\n#Install update from .fuf file\nflipper.update.install(fuf_file=\"/ext/update.fuf\")\n\n#Backup Flipper to .tar file\nflipper.update.backup(dest_tar_file=\"/ext/backup.tar\")\n\n#Restore Flipper from backup .tar file\nflipper.update.restore(bak_tar_file=\"/ext/backup.tar\")\n```\n### Loader\n\n```python\n#List installed apps\napps = flipper.loader.list()\n\n#Open app\nflipper.loader.open(app_name=\"Clock\")\n```\n\n### Flipper Info\n\n```python\n#Get flipper date\ndate = flipper.date.date()\n\n#Get flipper timestamp\ntimestamp = flipper.date.timestamp()\n\n#Get the processes dict list\nps = flipper.ps.list()\n\n#Get device info dict\ndevice_info = flipper.device_info.info()\n\n#Get heap info dict\nheap = flipper.free.info()\n\n#Get free_blocks string\nfree_blocks = flipper.free.blocks()\n\n#Get bluetooth info\nbt_info = flipper.bt.info()\n```\n### Storage\n\n#### Filesystem Info\n```python\n#Get the storage filesystem info\next_info = flipper.storage.info(fs=\"/ext\")\n```\n#### Explorer\n```python\n#Get the storage /ext dict\next_list = flipper.storage.list(path=\"/ext\")\n\n#Get the storage /ext tree dict\next_tree = flipper.storage.tree(path=\"/ext\")\n\n#Get file info\nfile_info = flipper.storage.stat(file=\"/ext/foo/bar.txt\")\n\n#Make directory\nflipper.storage.mkdir(new_dir=\"/ext/foo\")\n```\n#### Files\n\n```python\n#Read file\nplain_text = flipper.storage.read(file=\"/ext/foo/bar.txt\")\n\n#Remove file \nflipper.storage.remove(file=\"/ext/foo/bar.txt\")\n\n#Copy file \nflipper.storage.copy(src=\"/ext/foo/source.txt\", dest=\"/ext/bar/destination.txt\")\n\n#Rename file \nflipper.storage.rename(file=\"/ext/foo/bar.txt\", new_file=\"/ext/foo/rab.txt\")\n\n#MD5 Hash file \nmd5_hash = flipper.storage.md5(file=\"/ext/foo/bar.txt\")\n\n#Write file in one chunk\nfile = \"/ext/bar.txt\"\n\ntext = \"\"\"There are many variations of passages of Lorem Ipsum available, \nbut the majority have suffered alteration in some form, by injected humour, \nor randomised words which don't look even slightly believable. \nIf you are going to use a passage of Lorem Ipsum, \nyou need to be sure there isn't anything embarrassing hidden in the middle of text. \n\"\"\"\n\nflipper.storage.write.file(file, text)\n\n#Write file using a listener\nfile = \"/ext/foo.txt\"\n\ntext_one = \"\"\"There are many variations of passages of Lorem Ipsum available, \nbut the majority have suffered alteration in some form, by injected humour, \nor randomised words which don't look even slightly believable. \nIf you are going to use a passage of Lorem Ipsum, \nyou need to be sure there isn't anything embarrassing hidden in the middle of text. \n\"\"\"\n\nflipper.storage.write.start(file)\n\ntime.sleep(2)\n\nflipper.storage.write.send(text_one)\n\ntext_two = \"\"\"All the Lorem Ipsum generators on the Internet tend to repeat predefined chunks as \nnecessary, making this the first true generator on the Internet.\n It uses a dictionary of over 200 Latin words, combined with a handful of \n model sentence structures, to generate Lorem Ipsum which looks reasonable. \nThe generated Lorem Ipsum is therefore always free from repetition, injected humour, or non-characteristic words etc.\n\"\"\"\nflipper.storage.write.send(text_two)\n\ntime.sleep(3)\n\n#Don't forget to stop\nflipper.storage.write.stop()\n```\n### LED/Backlight\n\n```python\n#Set generic led on (r,b,g,bl)\nflipper.led.set(led='r', value=255)\n\n#Set blue led off\nflipper.led.blue(value=0)\n\n#Set green led value\nflipper.led.green(value=175)\n\n#Set backlight on\nflipper.led.backlight_on()\n\n#Set backlight off\nflipper.led.backlight_off()\n\n#Turn off led\nflipper.led.off()\n\n```\n### Vibro\n\n```python\n#Set vibro True or False\nflipper.vibro.set(True)\n\n#Set vibro on\nflipper.vibro.on()\n\n#Set vibro off\nflipper.vibro.off()\n```\n### GPIO\n\n```python\n#Set gpio mode: 0 - input, 1 - output\nflipper.gpio.mode(pin_name=PIN_NAME, value=1)\n\n#Set gpio pin value: 0 - off, 1 - on\nflipper.gpio.set(pin_name=PIN_NAME, value=1)\n\n#Read gpio pin value\nflipper.gpio.read(pin_name=PIN_NAME)\n```\n\n### MusicPlayer\n\n```python\n#Play song in RTTTL format\nrttl_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\"\n\n#Play in loop\nflipper.music_player.play(rtttl_code=rttl_song)\n\n#Stop loop\nflipper.music_player.stop()\n\n#Play for 20 seconds\nflipper.music_player.play(rtttl_code=rttl_song, duration=20)\n\n#Beep\nflipper.music_player.beep()\n\n#Beep for 5 seconds\nflipper.music_player.beep(duration=5)\n```\n### NFC\n\n```python\n#Synchronous default timeout 5 seconds\n\n#Detect NFC \nnfc_detected = flipper.nfc.detect()\n\n#Emulate NFC\nflipper.nfc.emulate()\n\n#Activate field\nflipper.nfc.field()\n```\n\n### RFID\n\n```python\n#Synchronous default timeout 5 seconds\n\n#Read RFID \nrfid = flipper.rfid.read()\n\n#Emulate RFID \nemulated = flipper.rfid.emulate(key_type=\"EM4100\", key_data=\"5500824806\")\n\n#Write RFID \nwritten = flipper.rfid.write(key_type=\"EM4100\", key_data=\"5500824806\")\n\n\n```\n\n### SubGhz\n\n```python\n#Transmit hex_key N times(default count = 10)\nflipper.subghz.tx(hex_key=\"DEADBEEF\", frequency=433920000, count=5)\n\n#Receive (default frequency=433920000 raw=False timeout=5 seconds)\nreceived = flipper.subghz.rx(frequency=\"433920000\", raw=True, timeout=10)\n\n#Decode raw .sub file\ndecoded = flipper.subghz.decode_raw(sub_file=\"/ext/subghz/foo.sub\")\n```\n### Infrared\n\n```python\n#Transmit hex_address and hex_command selecting a protocol\nflipper.ir.tx(protocol=\"Samsung32\", hex_address=\"C000FFEE\", hex_command=\"DEADBEEF\")\n\n#Raw Transmit samples\nflipper.ir.tx_raw(frequency=38000, duty_cycle=0.33, samples=[1337, 8888, 3000, 5555])\n\n#Synchronous default timeout 5 seconds\n#Receive tx \nr = flipper.ir.rx(timeout=10)\n```\n\n### IKEY\n\n```python\n#Read (default timeout 5 seconds)\nikey = flipper.ikey.read()\n\n#Write (default timeout 5 seconds)\nflipper.ikey.write(key_type=\"Dallas\", key_data=\"DEADBEEFCOOOFFEE\")\n\n#Emulate (default timeout 5 seconds)\nflipper.ikey.emulate(key_type=\"Dallas\", key_data=\"DEADBEEFCOOOFFEE\")\n```\n\n### Log\n\n```python\n#Attach event logger (default timeout 10 seconds)\nlogs = flipper.log.attach()\n```\n\n### Debug\n\n```python\n#Activate debug mode\nflipper.debug.on()\n\n#Deactivate debug mode\nflipper.debug.off()\n```\n\n### Onewire\n\n```python\n#Search\nresponse = flipper.onewire.search()\n```\n\n### I2C\n\n```python\n#Get\nresponse = flipper.i2c.get()\n```\n\n### Input\n\n```python\n#Input dump\ndump = flipper.input.dump()\n\n#Send input\nflipper.input.send(\"up\", \"press\")\n```\n\n## Optimizations\n\nFeel free to contribute in any way\n\n- [ ] Queue Thread orchestrator\n- [ ] Implement all the cli functions\n- [ ] Async SubGhz Chat\n\n## License\n\n[MIT](https://choosealicense.com/licenses/mit/)\n\n\n## Buy me a pint\n\n**ZEC:** zs13zdde4mu5rj5yjm2kt6al5yxz2qjjjgxau9zaxs6np9ldxj65cepfyw55qvfp9v8cvd725f7tz7\n\n**ETH:** 0xef3cF1Eb85382EdEEE10A2df2b348866a35C6A54\n\n**BTC:** 15umRZXBzgUacwLVgpLPoa2gv7MyoTrKat\n\n## Contacts\n\n - **Discord**: white_rabbit#4124\n - **Twitter**: @nic_whr\n - **GPG**: 0x94EDEADC\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Unoffical Flipper Zero cli wrapper",
"version": "0.18",
"project_urls": {
"Bug Reports": "https://github.com/wh00hw/pyFlipper/issues",
"Documentation": "https://github.com/wh00hw/pyFlipper/blob/master/README.md",
"Homepage": "https://github.com/wh00hw/pyFlipper",
"Source Code": "https://github.com/wh00hw/pyFlipper"
},
"split_keywords": [
"flipper",
"wrapper",
"module"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9c3cbac47fc70c9b74ad32e8eb11da478de270f861373812ba88e5ccabf05555",
"md5": "b81b6a98edb479a8709031a62b0121c6",
"sha256": "4594f24b3e299115d2725aa6a3aa2964a30f77b91cea5218fb59ca9abb682353"
},
"downloads": -1,
"filename": "pyflipper-0.18.tar.gz",
"has_sig": false,
"md5_digest": "b81b6a98edb479a8709031a62b0121c6",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 15595,
"upload_time": "2023-05-26T12:09:45",
"upload_time_iso_8601": "2023-05-26T12:09:45.841529Z",
"url": "https://files.pythonhosted.org/packages/9c/3c/bac47fc70c9b74ad32e8eb11da478de270f861373812ba88e5ccabf05555/pyflipper-0.18.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-05-26 12:09:45",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "wh00hw",
"github_project": "pyFlipper",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pyflipper"
}