mirror of
https://github.com/jayofelony/pwnagotchi.git
synced 2025-07-01 18:37:27 -04:00
Compare commits
49 Commits
Author | SHA1 | Date | |
---|---|---|---|
4e07fbf1aa | |||
b3e81a95c8 | |||
050966215b | |||
fef442edbb | |||
1064936503 | |||
a762a7f763 | |||
8fd0e358a9 | |||
9a941c1d46 | |||
ead5a3baac | |||
ac2973889d | |||
8991dd6811 | |||
415e5cd551 | |||
47705ba1a2 | |||
7c7bbc770b | |||
ab83de4905 | |||
8f7741cd9e | |||
835886e6f6 | |||
6b2039a8e6 | |||
d53d0c7841 | |||
6c40998b51 | |||
a71a90ba3d | |||
b03f6f747b | |||
a8ba88c9cc | |||
f597bd6d29 | |||
a3f103ac06 | |||
e0a068e51d | |||
dc1b3c7635 | |||
3657859a73 | |||
33ff5a0bf8 | |||
666f65c640 | |||
84d45a0d45 | |||
06a4491008 | |||
5485f83ca6 | |||
ab541458fa | |||
ac345c2ee7 | |||
468cfd9f4f | |||
d6bc5c0e66 | |||
4905eb6b26 | |||
697a7778b1 | |||
9287283ee7 | |||
8013109ef7 | |||
f140fe1a2d | |||
8fe503c67d | |||
d81013412e | |||
3c701822bd | |||
2f5ddb492a | |||
9e3324221d | |||
b069b82984 | |||
cb7d965271 |
3
.github/FUNDING.yml
vendored
3
.github/FUNDING.yml
vendored
@ -1,4 +1,3 @@
|
|||||||
# These are supported funding model platforms
|
# These are supported funding model platforms
|
||||||
|
|
||||||
github: jayofelony
|
github: jayofelony
|
||||||
custom: https://tikkie.me/pay/dubcto94hnskg539kar0
|
|
20
.github/workflows/publish.yml
vendored
20
.github/workflows/publish.yml
vendored
@ -20,21 +20,6 @@ jobs:
|
|||||||
VERSION=$(cut -d "'" -f2 < pwnagotchi/_version.py)
|
VERSION=$(cut -d "'" -f2 < pwnagotchi/_version.py)
|
||||||
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
echo "VERSION=$VERSION" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Get latest tag
|
|
||||||
uses: actions-ecosystem/action-get-latest-tag@v1
|
|
||||||
id: get-latest-tag
|
|
||||||
|
|
||||||
- name: Set LAST_VERSION as an environment variable
|
|
||||||
run: echo "LAST_VERSION=${{ steps.get-latest-tag.outputs.tag }}" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Generate release notes
|
|
||||||
id: generate_release_notes
|
|
||||||
run: |
|
|
||||||
COMMITS=$(git log --merges --pretty=format:"* %s" $LAST_VERSION--$VERSION | sed 's/$/\\n/g')
|
|
||||||
CONTRIBUTORS=$(git shortlog -sn $LAST_VERSION--$VERSION | awk '{print "* @" $2}' | sed 's/$/\\n/g')
|
|
||||||
RELEASE_BODY="**Full Changelog**: https://github.com/jayofelony/pwnagotchi/compare/$LAST_VERSION...$VERSION"
|
|
||||||
echo "RELEASE_BODY=$RELEASE_BODY" >> $GITHUB_ENV
|
|
||||||
|
|
||||||
- name: Install qemu dependencies
|
- name: Install qemu dependencies
|
||||||
run: sudo apt update && sudo apt install qemu-user-static qemu-utils xz-utils -y
|
run: sudo apt update && sudo apt install qemu-user-static qemu-utils xz-utils -y
|
||||||
|
|
||||||
@ -63,10 +48,11 @@ jobs:
|
|||||||
- name: Release
|
- name: Release
|
||||||
uses: softprops/action-gh-release@v2
|
uses: softprops/action-gh-release@v2
|
||||||
with:
|
with:
|
||||||
prerelease: true
|
prerelease: false
|
||||||
|
make_latest: true
|
||||||
tag_name: v${{ env.VERSION }}
|
tag_name: v${{ env.VERSION }}
|
||||||
name: Pwnagotchi v${{ env.VERSION }}
|
name: Pwnagotchi v${{ env.VERSION }}
|
||||||
files: |
|
files: |
|
||||||
pwnagotchi-${{ env.VERSION }}-32bit.img.xz
|
pwnagotchi-${{ env.VERSION }}-32bit.img.xz
|
||||||
pwnagotchi-${{ env.VERSION }}-64bit.img.xz
|
pwnagotchi-${{ env.VERSION }}-64bit.img.xz
|
||||||
body: ${{ env.RELEASE_BODY }}
|
generate_release_notes: true
|
@ -1 +0,0 @@
|
|||||||
bluez-tools
|
|
@ -237,7 +237,7 @@ def pwnagotchi_cli():
|
|||||||
f.write("ui.display.enabled = true\n")
|
f.write("ui.display.enabled = true\n")
|
||||||
pwn_display_type = input("What display do you use?\n\n"
|
pwn_display_type = input("What display do you use?\n\n"
|
||||||
"Be sure to check for the correct display type @ \n"
|
"Be sure to check for the correct display type @ \n"
|
||||||
"https://github.com/jayofelony/pwnagotchi/blob/master/pwnagotchi/utils.py#L240-L431\n\n"
|
"https://github.com/jayofelony/pwnagotchi/blob/master/pwnagotchi/utils.py#L240-L501\n\n"
|
||||||
"Display type: ")
|
"Display type: ")
|
||||||
if pwn_display_type != "":
|
if pwn_display_type != "":
|
||||||
f.write(f"ui.display.type = \"{pwn_display_type}\"\n")
|
f.write(f"ui.display.type = \"{pwn_display_type}\"\n")
|
||||||
@ -264,8 +264,7 @@ def pwnagotchi_cli():
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
if args.donate:
|
if args.donate:
|
||||||
print("Donations can made @ \n "
|
print("Donations can be made @ \n "
|
||||||
"https://www.patreon.com/pwnagotchi_torch \n "
|
|
||||||
"https://github.com/sponsors/jayofelony \n\n"
|
"https://github.com/sponsors/jayofelony \n\n"
|
||||||
"But only if you really want to!")
|
"But only if you really want to!")
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -278,8 +277,7 @@ def pwnagotchi_cli():
|
|||||||
local = version_to_tuple(pwnagotchi.__version__)
|
local = version_to_tuple(pwnagotchi.__version__)
|
||||||
remote = version_to_tuple(latest_ver)
|
remote = version_to_tuple(latest_ver)
|
||||||
if remote > local:
|
if remote > local:
|
||||||
user_input = input("There is a new version available! Update from v%s to v%s?\n[Y/N] "
|
user_input = input("There is a new version available! Update from v%s to v%s?\n[Y/N] " % (pwnagotchi.__version__, latest_ver))
|
||||||
% (pwnagotchi.__version__, latest_ver))
|
|
||||||
# input validation
|
# input validation
|
||||||
if user_input.lower() in ('y', 'yes'):
|
if user_input.lower() in ('y', 'yes'):
|
||||||
if os.path.exists('/root/.auto-update'):
|
if os.path.exists('/root/.auto-update'):
|
||||||
@ -334,5 +332,6 @@ def pwnagotchi_cli():
|
|||||||
else:
|
else:
|
||||||
do_auto_mode(agent)
|
do_auto_mode(agent)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
pwnagotchi_cli()
|
pwnagotchi_cli()
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
# For more options and information see
|
|
||||||
# http://rptl.io/configtxt
|
|
||||||
# Some settings may impact device functionality. See link above for details
|
|
||||||
|
|
||||||
# Uncomment some or all of these to enable the optional hardware interfaces
|
|
||||||
#dtparam=i2c_arm=on
|
|
||||||
#dtparam=i2s=on
|
|
||||||
#dtparam=spi=on
|
|
||||||
|
|
||||||
# Enable audio (loads snd_bcm2835)
|
|
||||||
dtparam=audio=on
|
|
||||||
|
|
||||||
# Additional overlays and parameters are documented
|
|
||||||
# /boot/overlays/README
|
|
||||||
|
|
||||||
# Automatically load overlays for detected cameras
|
|
||||||
camera_auto_detect=1
|
|
||||||
|
|
||||||
# Automatically load overlays for detected DSI displays
|
|
||||||
display_auto_detect=1
|
|
||||||
|
|
||||||
# Automatically load initramfs files, if found
|
|
||||||
auto_initramfs=1
|
|
||||||
|
|
||||||
# Enable DRM VC4 V3D driver
|
|
||||||
dtoverlay=vc4-kms-v3d
|
|
||||||
max_framebuffers=2
|
|
||||||
|
|
||||||
# Don't have the firmware create an initial video= setting in cmdline.txt.
|
|
||||||
# Use the kernel's default instead.
|
|
||||||
disable_fw_kms_setup=1
|
|
||||||
|
|
||||||
# Run in 64-bit mode
|
|
||||||
arm_64bit=0
|
|
||||||
|
|
||||||
# Disable compensation for displays with overscan
|
|
||||||
disable_overscan=1
|
|
||||||
|
|
||||||
# Run as fast as firmware / board allows
|
|
||||||
arm_boost=1
|
|
||||||
|
|
||||||
[cm4]
|
|
||||||
# Enable host mode on the 2711 built-in XHCI USB controller.
|
|
||||||
# This line should be removed if the legacy DWC2 controller is required
|
|
||||||
# (e.g. for USB device mode) or if USB support is not required.
|
|
||||||
otg_mode=1
|
|
||||||
|
|
||||||
[all]
|
|
||||||
dtoverlay=dwc2
|
|
||||||
dtparam=i2c1=on
|
|
||||||
dtparam=i2c_arm=on
|
|
||||||
dtparam=spi=on
|
|
||||||
gpu_mem=1
|
|
||||||
dtoverlay=dwc2
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi0]
|
|
||||||
dtoverlay=spi1-3cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi3]
|
|
||||||
dtoverlay=spi1-3cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi4]
|
|
||||||
dtoverlay=spi1-3cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
@ -20,6 +20,7 @@ echo " I'm managed by systemd. Here are some basic commands."
|
|||||||
echo
|
echo
|
||||||
echo " If you want to know what I'm doing, you can check my logs with the command"
|
echo " If you want to know what I'm doing, you can check my logs with the command"
|
||||||
echo " - pwnlog"
|
echo " - pwnlog"
|
||||||
|
echo " - sudo pwnagotchi --wizard, to help set up a config.toml"
|
||||||
echo " - sudo pwnagotchi --version, to check the current version"
|
echo " - sudo pwnagotchi --version, to check the current version"
|
||||||
echo " - sudo pwnagotchi --donate, to see how you can donate to this project"
|
echo " - sudo pwnagotchi --donate, to see how you can donate to this project"
|
||||||
echo " - sudo pwnagotchi --check-update, to see if there is a new version available"
|
echo " - sudo pwnagotchi --check-update, to see if there is a new version available"
|
||||||
@ -30,4 +31,4 @@ echo
|
|||||||
echo " You can restart me using"
|
echo " You can restart me using"
|
||||||
echo " pwnkill"
|
echo " pwnkill"
|
||||||
echo
|
echo
|
||||||
echo " You learn more about me at https://pwnagotchi.ai/"
|
echo " You can learn more about me at https://pwnagotchi.org/"
|
@ -32,6 +32,7 @@ start_monitor_interface() {
|
|||||||
ifconfig wlan0 down
|
ifconfig wlan0 down
|
||||||
ifconfig wlan0mon up
|
ifconfig wlan0mon up
|
||||||
iw dev wlan0mon set power_save off
|
iw dev wlan0mon set power_save off
|
||||||
|
iw dev wlan0 del
|
||||||
}
|
}
|
||||||
|
|
||||||
# stops mon0
|
# stops mon0
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
# For more options and information see
|
|
||||||
# http://rptl.io/configtxt
|
|
||||||
# Some settings may impact device functionality. See link above for details
|
|
||||||
|
|
||||||
# Uncomment some or all of these to enable the optional hardware interfaces
|
|
||||||
#dtparam=i2c_arm=on
|
|
||||||
#dtparam=i2s=on
|
|
||||||
#dtparam=spi=on
|
|
||||||
|
|
||||||
# Enable audio (loads snd_bcm2835)
|
|
||||||
dtparam=audio=on
|
|
||||||
|
|
||||||
# Additional overlays and parameters are documented
|
|
||||||
# /boot/firmware/overlays/README
|
|
||||||
|
|
||||||
# Automatically load overlays for detected cameras
|
|
||||||
camera_auto_detect=1
|
|
||||||
|
|
||||||
# Automatically load overlays for detected DSI displays
|
|
||||||
display_auto_detect=1
|
|
||||||
|
|
||||||
# Automatically load initramfs files, if found
|
|
||||||
auto_initramfs=1
|
|
||||||
|
|
||||||
# Enable DRM VC4 V3D driver
|
|
||||||
dtoverlay=vc4-kms-v3d
|
|
||||||
max_framebuffers=2
|
|
||||||
|
|
||||||
# Don't have the firmware create an initial video= setting in cmdline.txt.
|
|
||||||
# Use the kernel's default instead.
|
|
||||||
disable_fw_kms_setup=1
|
|
||||||
|
|
||||||
# Run in 64-bit mode
|
|
||||||
arm_64bit=1
|
|
||||||
|
|
||||||
# Disable compensation for displays with overscan
|
|
||||||
disable_overscan=1
|
|
||||||
|
|
||||||
# Run as fast as firmware / board allows
|
|
||||||
arm_boost=1
|
|
||||||
|
|
||||||
[cm4]
|
|
||||||
# Enable host mode on the 2711 built-in XHCI USB controller.
|
|
||||||
# This line should be removed if the legacy DWC2 controller is required
|
|
||||||
# (e.g. for USB device mode) or if USB support is not required.
|
|
||||||
otg_mode=1
|
|
||||||
|
|
||||||
[all]
|
|
||||||
dtparam=i2c1=on
|
|
||||||
dtparam=i2c_arm=on
|
|
||||||
dtparam=spi=on
|
|
||||||
gpu_mem=1
|
|
||||||
dtoverlay=dwc2
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi0]
|
|
||||||
dtoverlay=spi0-0cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi3]
|
|
||||||
dtoverlay=spi0-0cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi4]
|
|
||||||
dtoverlay=spi0-0cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
||||||
|
|
||||||
[pi5]
|
|
||||||
dtoverlay=spi0-0cs
|
|
||||||
#dtoverlay=disable-wifi
|
|
@ -2,7 +2,7 @@
|
|||||||
_hostname=$(hostname)
|
_hostname=$(hostname)
|
||||||
_version=$(cut -d"'" -f2 < /usr/local/lib/python3.11/dist-packages/pwnagotchi/_version.py)
|
_version=$(cut -d"'" -f2 < /usr/local/lib/python3.11/dist-packages/pwnagotchi/_version.py)
|
||||||
echo
|
echo
|
||||||
echo "(☉_☉ ) $_hostname"
|
echo "(◕‿‿◕) $_hostname"
|
||||||
echo
|
echo
|
||||||
echo " Hi! I'm a pwnagotchi $_version, please take good care of me!"
|
echo " Hi! I'm a pwnagotchi $_version, please take good care of me!"
|
||||||
echo " Here are some basic things you need to know to raise me properly!"
|
echo " Here are some basic things you need to know to raise me properly!"
|
||||||
|
@ -26,6 +26,7 @@ start_monitor_interface() {
|
|||||||
ifconfig wlan0 down
|
ifconfig wlan0 down
|
||||||
ifconfig wlan0mon up
|
ifconfig wlan0mon up
|
||||||
iw dev wlan0mon set power_save off
|
iw dev wlan0mon set power_save off
|
||||||
|
iw dev wlan0 del
|
||||||
}
|
}
|
||||||
|
|
||||||
# stops mon0
|
# stops mon0
|
||||||
|
@ -62,7 +62,7 @@
|
|||||||
source: "https://github.com/jayofelony/bettercap.git"
|
source: "https://github.com/jayofelony/bettercap.git"
|
||||||
url: "https://github.com/jayofelony/bettercap/releases/download/2.32.2/bettercap-2.32.2-armhf.zip"
|
url: "https://github.com/jayofelony/bettercap/releases/download/2.32.2/bettercap-2.32.2-armhf.zip"
|
||||||
ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip"
|
ui: "https://github.com/bettercap/ui/releases/download/v1.3.0/ui.zip"
|
||||||
opwngrid:
|
pwngrid:
|
||||||
source: "https://github.com/jayofelony/pwngrid.git"
|
source: "https://github.com/jayofelony/pwngrid.git"
|
||||||
url: "https://github.com/jayofelony/pwngrid/releases/download/v1.10.7/pwngrid-1.10.7-armhf.zip"
|
url: "https://github.com/jayofelony/pwngrid/releases/download/v1.10.7/pwngrid-1.10.7-armhf.zip"
|
||||||
torch:
|
torch:
|
||||||
@ -123,6 +123,7 @@
|
|||||||
- libc-ares-dev
|
- libc-ares-dev
|
||||||
- libc6-dev
|
- libc6-dev
|
||||||
- libcpuinfo-dev
|
- libcpuinfo-dev
|
||||||
|
- libcurl4-openssl-dev
|
||||||
- libdbus-1-dev
|
- libdbus-1-dev
|
||||||
- libdbus-glib-1-dev
|
- libdbus-glib-1-dev
|
||||||
- libeigen3-dev
|
- libeigen3-dev
|
||||||
@ -151,6 +152,7 @@
|
|||||||
- libsleef-dev
|
- libsleef-dev
|
||||||
- libsqlite3-dev
|
- libsqlite3-dev
|
||||||
- libssl-dev
|
- libssl-dev
|
||||||
|
- libssl-ocaml-dev
|
||||||
- libswscale5
|
- libswscale5
|
||||||
- libtiff5
|
- libtiff5
|
||||||
- libtool
|
- libtool
|
||||||
@ -206,6 +208,30 @@
|
|||||||
state: present
|
state: present
|
||||||
when: hostname.changed
|
when: hostname.changed
|
||||||
|
|
||||||
|
- name: setup /boot/config.txt
|
||||||
|
blockinfile:
|
||||||
|
path: /boot/config.txt
|
||||||
|
insertafter: EOF
|
||||||
|
block: |
|
||||||
|
dtparam=i2c1=on
|
||||||
|
dtparam=i2c_arm=on
|
||||||
|
dtparam=spi=on
|
||||||
|
gpu_mem=1
|
||||||
|
dtoverlay=dwc2
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi0]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi3]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi4]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
- name: Create custom plugin directory
|
- name: Create custom plugin directory
|
||||||
file:
|
file:
|
||||||
path: '{{ pwnagotchi.custom_plugin_dir }}'
|
path: '{{ pwnagotchi.custom_plugin_dir }}'
|
||||||
@ -264,6 +290,24 @@
|
|||||||
dest: /usr/local/lib/libpcap.so.0.8
|
dest: /usr/local/lib/libpcap.so.0.8
|
||||||
state: link
|
state: link
|
||||||
|
|
||||||
|
# install latest hcxtools
|
||||||
|
|
||||||
|
#- name: clone hcxtools
|
||||||
|
# git:
|
||||||
|
# repo: https://github.com/ZerBea/hcxtools.git
|
||||||
|
# dest: /usr/local/src/hcxtools
|
||||||
|
|
||||||
|
#- name: install hcxtools
|
||||||
|
# shell: "make && make install"
|
||||||
|
# args:
|
||||||
|
# executable: /bin/bash
|
||||||
|
# chdir: /usr/local/src/hcxtools
|
||||||
|
|
||||||
|
#- name: remove hcxtools directory
|
||||||
|
# file:
|
||||||
|
# state: absent
|
||||||
|
# path: /usr/local/src/hcxtools
|
||||||
|
|
||||||
###############################################################
|
###############################################################
|
||||||
# Install nexmon to fix wireless scanning (takes 2.5G of space)
|
# Install nexmon to fix wireless scanning (takes 2.5G of space)
|
||||||
###############################################################
|
###############################################################
|
||||||
@ -374,21 +418,36 @@
|
|||||||
when: golang.changed
|
when: golang.changed
|
||||||
|
|
||||||
- name: download pwngrid
|
- name: download pwngrid
|
||||||
unarchive:
|
git:
|
||||||
remote_src: yes
|
repo: "{{ packages.pwngrid.source }}"
|
||||||
src: "{{ packages.opwngrid.url }}"
|
dest: /usr/local/src/pwngrid
|
||||||
dest: /usr/local/bin/
|
|
||||||
mode: 0755
|
|
||||||
|
|
||||||
- name: download and install bettercap
|
- name: install pwngrid
|
||||||
unarchive:
|
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go mod tidy && make && make install"
|
||||||
src: "{{ packages.bettercap.url }}"
|
args:
|
||||||
dest: /usr/local/bin
|
executable: /bin/bash
|
||||||
remote_src: yes
|
chdir: /usr/local/src/pwngrid
|
||||||
exclude:
|
|
||||||
- README.md
|
- name: remove pwngrid folder
|
||||||
- LICENSE.md
|
file:
|
||||||
mode: 0755
|
state: absent
|
||||||
|
path: /usr/local/src/pwngrid
|
||||||
|
|
||||||
|
- name: download bettercap
|
||||||
|
git:
|
||||||
|
repo: "{{ packages.bettercap.source }}"
|
||||||
|
dest: /usr/local/src/bettercap
|
||||||
|
|
||||||
|
- name: install bettercap 2.32.4
|
||||||
|
shell: "export GOPATH=$HOME/go && export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin && go mod tidy && make && make install"
|
||||||
|
args:
|
||||||
|
executable: /bin/bash
|
||||||
|
chdir: /usr/local/src/bettercap
|
||||||
|
|
||||||
|
- name: remove bettercap folder
|
||||||
|
file:
|
||||||
|
state: absent
|
||||||
|
path: /usr/local/src/bettercap
|
||||||
|
|
||||||
- name: clone bettercap caplets
|
- name: clone bettercap caplets
|
||||||
git:
|
git:
|
||||||
@ -559,4 +618,4 @@
|
|||||||
handlers:
|
handlers:
|
||||||
- name: reload systemd services
|
- name: reload systemd services
|
||||||
systemd:
|
systemd:
|
||||||
daemon_reload: yes
|
daemon_reload: yes
|
||||||
|
@ -211,6 +211,34 @@
|
|||||||
regexp: '(.*)$'
|
regexp: '(.*)$'
|
||||||
line: '\1 modules-load=dwc2,g_ether'
|
line: '\1 modules-load=dwc2,g_ether'
|
||||||
|
|
||||||
|
- name: setup /boot/firmware/config.txt
|
||||||
|
blockinfile:
|
||||||
|
path: /boot/firmware/config.txt
|
||||||
|
insertafter: EOF
|
||||||
|
block: |
|
||||||
|
dtparam=i2c1=on
|
||||||
|
dtparam=i2c_arm=on
|
||||||
|
dtparam=spi=on
|
||||||
|
gpu_mem=1
|
||||||
|
dtoverlay=dwc2
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi0]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi3]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi4]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
|
[pi5]
|
||||||
|
dtoverlay=spi0-0cs
|
||||||
|
#dtoverlay=disable-wifi
|
||||||
|
|
||||||
- name: change hostname
|
- name: change hostname
|
||||||
lineinfile:
|
lineinfile:
|
||||||
dest: /etc/hostname
|
dest: /etc/hostname
|
||||||
|
@ -1 +1 @@
|
|||||||
__version__ = '2.8.8'
|
__version__ = '2.9.0'
|
||||||
|
Binary file not shown.
@ -1,260 +1,260 @@
|
|||||||
# SOME DESCRIPTIVE TITLE.
|
# pwnagotchi Brazilian Portuguese translation file.
|
||||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
# Copyright (C) 2024
|
||||||
# This file is distributed under the same license as the PACKAGE package.
|
# This file is distributed under the same license as the pwnagotchi package.
|
||||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
# Fabiano F O <fabfernandes@hotmail.com>, 2024.
|
||||||
#
|
#
|
||||||
|
|
||||||
msgid ""
|
msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-11-17 15:46+0100\n"
|
"POT-Creation-Date: 2024-03-25 22:30+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: Foxy <EMAIL@ADDRESS>\n"
|
"Last-Translator: Fabiano F O <fabfernandes@hotmail.com>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: Portuguese (Brazil)\n"
|
"Language: Brazilian Portuguese\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=utf-8\n"
|
"Content-Type: text/plain; charset=utf-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
msgid "ZzzzZZzzzzZzzz"
|
msgid "ZzzzZZzzzzZzzz"
|
||||||
msgstr "ZzzzZZzzzzZzzz"
|
msgstr "ZzzzZZzzzzZzzz"
|
||||||
|
|
||||||
msgid "Hi, I'm Pwnagotchi! Starting ..."
|
msgid "Hi, I'm Pwnagotchi! Starting ..."
|
||||||
msgstr "Olá, Eu sou Pwnagotchi! Iniciando ..."
|
msgstr "Olá, sou Pwnagotchi! Iniciando ..."
|
||||||
|
|
||||||
msgid "New day, new hunt, new pwns!"
|
msgid "New day, new hunt, new pwns!"
|
||||||
msgstr "Um novo dia, Uma nova caça e novos pwns!"
|
msgstr "Novo dia, Nova caçada, Novos pwns!"
|
||||||
|
|
||||||
msgid "Hack the Planet!"
|
msgid "Hack the Planet!"
|
||||||
msgstr "Burle o Planeta!"
|
msgstr "Hackeie o Planeta!"
|
||||||
|
|
||||||
msgid "AI ready."
|
msgid "AI ready."
|
||||||
msgstr "IA pronta."
|
msgstr "IA pronta."
|
||||||
|
|
||||||
msgid "The neural network is ready."
|
msgid "The neural network is ready."
|
||||||
msgstr "A rede neural está pronta."
|
msgstr "A rede neural está pronta."
|
||||||
|
|
||||||
msgid "Generating keys, do not turn off ..."
|
msgid "Generating keys, do not turn off ..."
|
||||||
msgstr "Criando chaves, não desligue o sistema ..."
|
msgstr "Gerando chaves, não desligue ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
||||||
msgstr "Ei, canal {channel} está livre! Seu AP vai agradecer."
|
msgstr "Ei, o canal {channel} está livre! Seu AP vai agradecer."
|
||||||
|
|
||||||
msgid "Reading last session logs ..."
|
msgid "Reading last session logs ..."
|
||||||
msgstr "Lendo os logs da ultima sessão"
|
msgstr "Lendo os logs da última sessão ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Read {lines_so_far} log lines so far ..."
|
msgid "Read {lines_so_far} log lines so far ..."
|
||||||
msgstr "Leia {lines_so_far} linha de logs até agora ..."
|
msgstr "Li {lines_so_far} linhas de logs até agora ..."
|
||||||
|
|
||||||
msgid "I'm bored ..."
|
msgid "I'm bored ..."
|
||||||
msgstr "Eu estou entediado ..."
|
msgstr "Estou entediado ..."
|
||||||
|
|
||||||
msgid "Let's go for a walk!"
|
msgid "Let's go for a walk!"
|
||||||
msgstr "Vamos ir numa caminhada!"
|
msgstr "Vamos dar um passeio!"
|
||||||
|
|
||||||
msgid "This is the best day of my life!"
|
msgid "This is the best day of my life!"
|
||||||
msgstr "Esse é o melhor dia da minha vida!"
|
msgstr "Este é o melhor dia da minha vida!"
|
||||||
|
|
||||||
msgid "Shitty day :/"
|
msgid "Shitty day :/"
|
||||||
msgstr "Dia ruim :/"
|
msgstr "Que dia ruim :/"
|
||||||
|
|
||||||
msgid "I'm extremely bored ..."
|
msgid "I'm extremely bored ..."
|
||||||
msgstr "Eu estou extremamente entediado ..."
|
msgstr "Estou extremamente entediado ..."
|
||||||
|
|
||||||
msgid "I'm very sad ..."
|
msgid "I'm very sad ..."
|
||||||
msgstr "Eu estou muito triste ..."
|
msgstr "Estou muito triste ..."
|
||||||
|
|
||||||
msgid "I'm sad"
|
msgid "I'm sad"
|
||||||
msgstr "Eu estou triste"
|
msgstr "Estou triste"
|
||||||
|
|
||||||
msgid "Leave me alone ..."
|
msgid "Leave me alone ..."
|
||||||
msgstr "Me deixe em paz ..."
|
msgstr "Me deixe em paz ..."
|
||||||
|
|
||||||
msgid "I'm mad at you!"
|
msgid "I'm mad at you!"
|
||||||
msgstr "Eu estou bravo com você!"
|
msgstr "Estou bravo com você!"
|
||||||
|
|
||||||
msgid "I'm living the life!"
|
msgid "I'm living the life!"
|
||||||
msgstr "Eu estou vivendo a vida!"
|
msgstr "Estou aproveitando a vida!"
|
||||||
|
|
||||||
msgid "I pwn therefore I am."
|
msgid "I pwn therefore I am."
|
||||||
msgstr "Eu pwn então Eu sou."
|
msgstr "Eu pwn, logo existo."
|
||||||
|
|
||||||
msgid "So many networks!!!"
|
msgid "So many networks!!!"
|
||||||
msgstr "Tantas redes!!!"
|
msgstr "Uau! Quantas redes!!"
|
||||||
|
|
||||||
msgid "I'm having so much fun!"
|
msgid "I'm having so much fun!"
|
||||||
msgstr "Eu estou tendo muita diversão"
|
msgstr "Estou me divertindo muito!"
|
||||||
|
|
||||||
msgid "My crime is that of curiosity ..."
|
msgid "My crime is that of curiosity ..."
|
||||||
msgstr "Meu crime é de curiosidade ..."
|
msgstr "Meu crime é a curiosidade ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hello {name}! Nice to meet you."
|
msgid "Hello {name}! Nice to meet you."
|
||||||
msgstr "Olá {name}! É bom em conhecê-lo"
|
msgstr "Olá {name}! Prazer em conhecê-lo."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Yo {name}! Sup?"
|
msgid "Yo {name}! Sup?"
|
||||||
msgstr "Ei {name}! Como vai?"
|
msgstr "Ei {name}! Como vai?"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey {name} how are you doing?"
|
msgid "Hey {name} how are you doing?"
|
||||||
msgstr "Ei {name} como você está indo?"
|
msgstr "Ei {name}, como você está?"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unit {name} is nearby!"
|
msgid "Unit {name} is nearby!"
|
||||||
msgstr ""
|
msgstr "A unidade {name} está próxima!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Uhm ... goodbye {name}"
|
msgid "Uhm ... goodbye {name}"
|
||||||
msgstr ""
|
msgstr "Hmm ... tchau {name}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{name} is gone ..."
|
msgid "{name} is gone ..."
|
||||||
msgstr ""
|
msgstr "{name} desapareceu ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Whoops ... {name} is gone."
|
msgid "Whoops ... {name} is gone."
|
||||||
msgstr ""
|
msgstr "Oops ... {name} desapareceu."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{name} missed!"
|
msgid "{name} missed!"
|
||||||
msgstr "{name} errou!"
|
msgstr "Perdi {name}!"
|
||||||
|
|
||||||
msgid "Missed!"
|
msgid "Missed!"
|
||||||
msgstr "Errei!"
|
msgstr "Perdi!"
|
||||||
|
|
||||||
msgid "Good friends are a blessing!"
|
msgid "Good friends are a blessing!"
|
||||||
msgstr "Bom amigos são uma bensão!"
|
msgstr "Bons amigos são uma bênção!"
|
||||||
|
|
||||||
msgid "I love my friends!"
|
msgid "I love my friends!"
|
||||||
msgstr "Eu amo meus amigos!"
|
msgstr "Eu amo meus amigos!"
|
||||||
|
|
||||||
msgid "Nobody wants to play with me ..."
|
msgid "Nobody wants to play with me ..."
|
||||||
msgstr "Ninguém quer brincar comigo ..."
|
msgstr "Ninguém quer brincar comigo ..."
|
||||||
|
|
||||||
msgid "I feel so alone ..."
|
msgid "I feel so alone ..."
|
||||||
msgstr "Estou me sentindo sozinho"
|
msgstr "Me sinto tão sozinho ..."
|
||||||
|
|
||||||
msgid "Where's everybody?!"
|
msgid "Where's everybody?!"
|
||||||
msgstr "Onde está todo mundo?!"
|
msgstr "Onde está todo mundo?!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Napping for {secs}s ..."
|
msgid "Napping for {secs}s ..."
|
||||||
msgstr "Tirando uma soneca por {secs}s ..."
|
msgstr "Tirando uma soneca por {secs}s ..."
|
||||||
|
|
||||||
msgid "Zzzzz"
|
msgid "Zzzzz"
|
||||||
msgstr "Zzzzz"
|
msgstr "Zzzzz"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "ZzzZzzz ({secs}s)"
|
msgid "ZzzZzzz ({secs}s)"
|
||||||
msgstr "ZzzZzzz ({secs}s)"
|
msgstr "ZzzZzzz ({secs}s)"
|
||||||
|
|
||||||
msgid "Good night."
|
msgid "Good night."
|
||||||
msgstr "Boa noite."
|
msgstr "Boa noite."
|
||||||
|
|
||||||
msgid "Zzz"
|
msgid "Zzz"
|
||||||
msgstr "Zzz"
|
msgstr "Zzz"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Waiting for {secs}s ..."
|
msgid "Waiting for {secs}s ..."
|
||||||
msgstr "Esperando por {secs}s ..."
|
msgstr "Aguardando {secs}s ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Looking around ({secs}s)"
|
msgid "Looking around ({secs}s)"
|
||||||
msgstr "Olhando por volta ({secs}s)"
|
msgstr "Olhando em volta ... ({secs}s)"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey {what} let's be friends!"
|
msgid "Hey {what} let's be friends!"
|
||||||
msgstr "Ei {what} vamos ser amigos!"
|
msgstr "Ei {what}, vamos ser amigos!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Associating to {what}"
|
msgid "Associating to {what}"
|
||||||
msgstr "Associando para {what}"
|
msgstr "Associando a {what}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Yo {what}!"
|
msgid "Yo {what}!"
|
||||||
msgstr "Ei {what}!"
|
msgstr "Olá {what}!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Just decided that {mac} needs no WiFi!"
|
msgid "Just decided that {mac} needs no WiFi!"
|
||||||
msgstr "Apenas decidindo que {mac} não precisa de WiFi!"
|
msgstr "Acabei de decidir que {mac} não precisa de WiFi!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Deauthenticating {mac}"
|
msgid "Deauthenticating {mac}"
|
||||||
msgstr "Desautenticando {mac}"
|
msgstr "Desautenticando {mac}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kickbanning {mac}!"
|
msgid "Kickbanning {mac}!"
|
||||||
msgstr "Banindo {mac}!"
|
msgstr "Banindo {mac}!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cool, we got {num} new handshake{plural}!"
|
msgid "Cool, we got {num} new handshake{plural}!"
|
||||||
msgstr "Legal, conseguimos {num} novos handshake{plural}!"
|
msgstr "Legal, conseguimos {num} novo{plural} handshake{plural}!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "You have {count} new message{plural}!"
|
msgid "You have {count} new message{plural}!"
|
||||||
msgstr "Você tem {count} novas messagem{plural}!"
|
msgstr "Você tem {count} nova{plural} messagem{plural}!"
|
||||||
|
|
||||||
msgid "Oops, something went wrong ... Rebooting ..."
|
msgid "Oops, something went wrong ... Rebooting ..."
|
||||||
msgstr "Oops, algo deu errado ... Reiniciando ..."
|
msgstr "Oops, algo deu errado ... Reiniciando ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Uploading data to {to} ..."
|
msgid "Uploading data to {to} ..."
|
||||||
msgstr "Enviando dados para {to} ..."
|
msgstr "Enviando dados para {to} ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Downloading from {name} ..."
|
msgid "Downloading from {name} ..."
|
||||||
msgstr "Instalando para {name} ..."
|
msgstr "Baixando de {name} ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kicked {num} stations\n"
|
msgid "Kicked {num} stations\n"
|
||||||
msgstr "Expulsei {num} estações\n"
|
msgstr "Expulsei {num} estações\n"
|
||||||
|
|
||||||
msgid "Made >999 new friends\n"
|
msgid "Made >999 new friends\n"
|
||||||
msgstr "Fiz >999 novos amigos\n"
|
msgstr "Fiz >999 novos amigos\n"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Made {num} new friends\n"
|
msgid "Made {num} new friends\n"
|
||||||
msgstr "Fiz {num} novos amigos\n"
|
msgstr "Fiz {num} novos amigos\n"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Got {num} handshakes\n"
|
msgid "Got {num} handshakes\n"
|
||||||
msgstr "Peguei {num} handshakes\n"
|
msgstr "Peguei {num} handshakes\n"
|
||||||
|
|
||||||
msgid "Met 1 peer"
|
msgid "Met 1 peer"
|
||||||
msgstr "Encontrei 1 pessoa"
|
msgstr "Conheci 1 peer"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Met {num} peers"
|
msgid "Met {num} peers"
|
||||||
msgstr "Encontrei {num} pessoas"
|
msgstr "Conheci {num} peers"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
|
"I've been pwning for {duration} and kicked {deauthed} clients! I've also met "
|
||||||
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
|
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
|
||||||
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Estou navegando há {duration} e expulsei {deauthed} clientes! Também conheci "
|
"Estou pwning há {duration} e expulsei {deauthed} clientes! Também conheci "
|
||||||
"{associamos} novos amigos e comi {handshakes} handshakes! #pwnagotchi "
|
"{associated} novos amigos e comi {handshakes} handshakes! #pwnagotchi "
|
||||||
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
||||||
|
|
||||||
msgid "hours"
|
msgid "hours"
|
||||||
msgstr "horas"
|
msgstr "horas"
|
||||||
|
|
||||||
msgid "minutes"
|
msgid "minutes"
|
||||||
msgstr "minutos"
|
msgstr "minutos"
|
||||||
|
|
||||||
msgid "seconds"
|
msgid "seconds"
|
||||||
msgstr "segundos"
|
msgstr "segundos"
|
||||||
|
|
||||||
msgid "hour"
|
msgid "hour"
|
||||||
msgstr "hora"
|
msgstr "hora"
|
||||||
|
|
||||||
msgid "minute"
|
msgid "minute"
|
||||||
msgstr "minuto"
|
msgstr "minuto"
|
||||||
|
|
||||||
msgid "second"
|
msgid "second"
|
||||||
msgstr "segundo"
|
msgstr "segundo"
|
Binary file not shown.
@ -9,8 +9,8 @@ msgstr ""
|
|||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2023-11-16 21:10+0100\n"
|
"POT-Creation-Date: 2023-11-16 21:10+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: 2024-03-27 18:40+0800\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: AlanLeung <admin@mcnot.pro>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
"Language: Twi\n"
|
"Language: Twi\n"
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
@ -18,218 +18,218 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
msgid "ZzzzZZzzzzZzzz"
|
msgid "ZzzzZZzzzzZzzz"
|
||||||
msgstr ""
|
msgstr "ZzzzZZzzzzZzzz"
|
||||||
|
|
||||||
msgid "Hi, I'm Pwnagotchi! Starting ..."
|
msgid "Hi, I'm Pwnagotchi! Starting ..."
|
||||||
msgstr ""
|
msgstr "HI!我是Pwnagotchi!\n程式啟動..."
|
||||||
|
|
||||||
msgid "New day, new hunt, new pwns!"
|
msgid "New day, new hunt, new pwns!"
|
||||||
msgstr ""
|
msgstr "新的一天!\n新的狩獵!新的入侵!"
|
||||||
|
|
||||||
msgid "Hack the Planet!"
|
msgid "Hack the Planet!"
|
||||||
msgstr ""
|
msgstr "我要駭入\n地球的所有人!"
|
||||||
|
|
||||||
msgid "AI ready."
|
msgid "AI ready."
|
||||||
msgstr ""
|
msgstr "人工智慧已啟動。"
|
||||||
|
|
||||||
msgid "The neural network is ready."
|
msgid "The neural network is ready."
|
||||||
msgstr ""
|
msgstr "神經網路已啟動。"
|
||||||
|
|
||||||
msgid "Generating keys, do not turn off ..."
|
msgid "Generating keys, do not turn off ..."
|
||||||
msgstr ""
|
msgstr "產生金鑰中,\n請勿關閉..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
msgid "Hey, channel {channel} is free! Your AP will say thanks."
|
||||||
msgstr ""
|
msgstr "嘿,{channel}很順暢!\n你的WIFI會感謝你的。"
|
||||||
|
|
||||||
msgid "Reading last session logs ..."
|
msgid "Reading last session logs ..."
|
||||||
msgstr ""
|
msgstr "正在閱讀最後的會話紀錄..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Read {lines_so_far} log lines so far ..."
|
msgid "Read {lines_so_far} log lines so far ..."
|
||||||
msgstr ""
|
msgstr "目前已經閱讀了 {lines_so_far} 行的紀錄..."
|
||||||
|
|
||||||
msgid "I'm bored ..."
|
msgid "I'm bored ..."
|
||||||
msgstr ""
|
msgstr "我好無聊..."
|
||||||
|
|
||||||
msgid "Let's go for a walk!"
|
msgid "Let's go for a walk!"
|
||||||
msgstr ""
|
msgstr "我們! 散步! 散步散步散步散步"
|
||||||
|
|
||||||
msgid "This is the best day of my life!"
|
msgid "This is the best day of my life!"
|
||||||
msgstr ""
|
msgstr "這是我生命中最棒的一天!"
|
||||||
|
|
||||||
msgid "Shitty day :/"
|
msgid "Shitty day :/"
|
||||||
msgstr ""
|
msgstr "糟糕的一天 :/"
|
||||||
|
|
||||||
msgid "I'm extremely bored ..."
|
msgid "I'm extremely bored ..."
|
||||||
msgstr ""
|
msgstr "我超無聊的...炒雞 炒雞的那種"
|
||||||
|
|
||||||
msgid "I'm very sad ..."
|
msgid "I'm very sad ..."
|
||||||
msgstr ""
|
msgstr "我好難過..."
|
||||||
|
|
||||||
msgid "I'm sad"
|
msgid "I'm sad"
|
||||||
msgstr ""
|
msgstr "嗚嗚嗚...."
|
||||||
|
|
||||||
msgid "Leave me alone ..."
|
msgid "Leave me alone ..."
|
||||||
msgstr ""
|
msgstr "尼奏凱啦臭臭"
|
||||||
|
|
||||||
msgid "I'm mad at you!"
|
msgid "I'm mad at you!"
|
||||||
msgstr ""
|
msgstr "喔氣氣氣氣氣ˋ^ˊ"
|
||||||
|
|
||||||
msgid "I'm living the life!"
|
msgid "I'm living the life!"
|
||||||
msgstr ""
|
msgstr "真是充實的一生!"
|
||||||
|
|
||||||
msgid "I pwn therefore I am."
|
msgid "I pwn therefore I am."
|
||||||
msgstr ""
|
msgstr "我駭故我在."
|
||||||
|
|
||||||
msgid "So many networks!!!"
|
msgid "So many networks!!!"
|
||||||
msgstr ""
|
msgstr "好多網路啊!!!吃! 吃他! 吃光光!!!"
|
||||||
|
|
||||||
msgid "I'm having so much fun!"
|
msgid "I'm having so much fun!"
|
||||||
msgstr ""
|
msgstr "我玩的超級開心!"
|
||||||
|
|
||||||
msgid "My crime is that of curiosity ..."
|
msgid "My crime is that of curiosity ..."
|
||||||
msgstr ""
|
msgstr "我的缺點就是\n太好奇了..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hello {name}! Nice to meet you."
|
msgid "Hello {name}! Nice to meet you."
|
||||||
msgstr ""
|
msgstr "尼豪{name}!\n很高興認識你!!!!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Yo {name}! Sup?"
|
msgid "Yo {name}! Sup?"
|
||||||
msgstr ""
|
msgstr "嗨 {name}! 你來攻打我的村莊?"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey {name} how are you doing?"
|
msgid "Hey {name} how are you doing?"
|
||||||
msgstr ""
|
msgstr "嗨 {name} 你最近過得如何˙ˇ˙?"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Unit {name} is nearby!"
|
msgid "Unit {name} is nearby!"
|
||||||
msgstr ""
|
msgstr "{name}\n就在附近!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Uhm ... goodbye {name}"
|
msgid "Uhm ... goodbye {name}"
|
||||||
msgstr ""
|
msgstr "哦嗚 ... \n拜拜{name}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{name} is gone ..."
|
msgid "{name} is gone ..."
|
||||||
msgstr ""
|
msgstr "{name}\n不見了 ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Whoops ... {name} is gone."
|
msgid "Whoops ... {name} is gone."
|
||||||
msgstr ""
|
msgstr "哦歐...\n{name}\n不見了。"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "{name} missed!"
|
msgid "{name} missed!"
|
||||||
msgstr ""
|
msgstr "我剛剛錯過了{name}!"
|
||||||
|
|
||||||
msgid "Missed!"
|
msgid "Missed!"
|
||||||
msgstr ""
|
msgstr "又錯過了!"
|
||||||
|
|
||||||
msgid "Good friends are a blessing!"
|
msgid "Good friends are a blessing!"
|
||||||
msgstr ""
|
msgstr "有個好朋友\n真幸福!"
|
||||||
|
|
||||||
msgid "I love my friends!"
|
msgid "I love my friends!"
|
||||||
msgstr ""
|
msgstr "我喜歡\n我的朋友!"
|
||||||
|
|
||||||
msgid "Nobody wants to play with me ..."
|
msgid "Nobody wants to play with me ..."
|
||||||
msgstr ""
|
msgstr "沒人想跟我玩..."
|
||||||
|
|
||||||
msgid "I feel so alone ..."
|
msgid "I feel so alone ..."
|
||||||
msgstr ""
|
msgstr "我覺得好孤單..."
|
||||||
|
|
||||||
msgid "Where's everybody?!"
|
msgid "Where's everybody?!"
|
||||||
msgstr ""
|
msgstr "大家都去哪裡了?!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Napping for {secs}s ..."
|
msgid "Napping for {secs}s ..."
|
||||||
msgstr ""
|
msgstr "我想瞇{secs}秒一下..."
|
||||||
|
|
||||||
msgid "Zzzzz"
|
msgid "Zzzzz"
|
||||||
msgstr ""
|
msgstr "Zzzzz"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "ZzzZzzz ({secs}s)"
|
msgid "ZzzZzzz ({secs}s)"
|
||||||
msgstr ""
|
msgstr "ZzzZzzz({secs}秒)"
|
||||||
|
|
||||||
msgid "Good night."
|
msgid "Good night."
|
||||||
msgstr ""
|
msgstr "晚安!"
|
||||||
|
|
||||||
msgid "Zzz"
|
msgid "Zzz"
|
||||||
msgstr ""
|
msgstr "Zzz"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Waiting for {secs}s ..."
|
msgid "Waiting for {secs}s ..."
|
||||||
msgstr ""
|
msgstr "等我{secs}秒..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Looking around ({secs}s)"
|
msgid "Looking around ({secs}s)"
|
||||||
msgstr ""
|
msgstr "環顧四周({secs}秒)"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Hey {what} let's be friends!"
|
msgid "Hey {what} let's be friends!"
|
||||||
msgstr ""
|
msgstr "嗨\n{what}\n讓我們來當朋友吧!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Associating to {what}"
|
msgid "Associating to {what}"
|
||||||
msgstr ""
|
msgstr "正在連接\n{what}"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Yo {what}!"
|
msgid "Yo {what}!"
|
||||||
msgstr ""
|
msgstr "喲,\n{what}!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Just decided that {mac} needs no WiFi!"
|
msgid "Just decided that {mac} needs no WiFi!"
|
||||||
msgstr ""
|
msgstr "我要讓\n{mac}\n斷線!\n他不需要上網!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Deauthenticating {mac}"
|
msgid "Deauthenticating {mac}"
|
||||||
msgstr ""
|
msgstr "解除\n{mac}\n的授權中"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kickbanning {mac}!"
|
msgid "Kickbanning {mac}!"
|
||||||
msgstr ""
|
msgstr "把\n{mac}\n踢出中!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Cool, we got {num} new handshake{plural}!"
|
msgid "Cool, we got {num} new handshake{plural}!"
|
||||||
msgstr ""
|
msgstr "酷耶,我們抓到{num}個\n新的握手包{plural}!"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "You have {count} new message{plural}!"
|
msgid "You have {count} new message{plural}!"
|
||||||
msgstr ""
|
msgstr "你有{count}個新訊息{plural}!"
|
||||||
|
|
||||||
msgid "Oops, something went wrong ... Rebooting ..."
|
msgid "Oops, something went wrong ... Rebooting ..."
|
||||||
msgstr ""
|
msgstr "哦歐,有些地方出錯了...\n重新啟動中..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Uploading data to {to} ..."
|
msgid "Uploading data to {to} ..."
|
||||||
msgstr ""
|
msgstr "正在上傳資料到 {to} ..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Downloading from {name} ..."
|
msgid "Downloading from {name} ..."
|
||||||
msgstr ""
|
msgstr "正在從 {name} 下載資料..."
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Kicked {num} stations\n"
|
msgid "Kicked {num} stations\n"
|
||||||
msgstr ""
|
msgstr "踢了 {num} 個設備\n"
|
||||||
|
|
||||||
msgid "Made >999 new friends\n"
|
msgid "Made >999 new friends\n"
|
||||||
msgstr ""
|
msgstr "交了 >999 個新朋友\n"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Made {num} new friends\n"
|
msgid "Made {num} new friends\n"
|
||||||
msgstr ""
|
msgstr "交了 {num} 個新朋友\n"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Got {num} handshakes\n"
|
msgid "Got {num} handshakes\n"
|
||||||
msgstr ""
|
msgstr "捕獲了 {num} 個握手包\n"
|
||||||
|
|
||||||
msgid "Met 1 peer"
|
msgid "Met 1 peer"
|
||||||
msgstr ""
|
msgstr "遇到了 1 個同好"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid "Met {num} peers"
|
msgid "Met {num} peers"
|
||||||
msgstr ""
|
msgstr "遇到了 {num} 個同好"
|
||||||
|
|
||||||
#, python-brace-format
|
#, python-brace-format
|
||||||
msgid ""
|
msgid ""
|
||||||
@ -237,21 +237,24 @@ msgid ""
|
|||||||
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
|
"{associated} new friends and ate {handshakes} handshakes! #pwnagotchi "
|
||||||
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
"#pwnlog #pwnlife #hacktheplanet #skynet"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
"我花了{duration}的時間\n駭入和踢了{deauthed}好多設備."
|
||||||
|
"我還交了好多{associated}新朋友,\n而且抓到了{handshakes}握手包!"
|
||||||
|
"#pwnagotchi#入侵日志 #駭客人生 #入侵整個星球 #天網 #我好棒˙ˇ˙"
|
||||||
|
|
||||||
msgid "hours"
|
msgid "hours"
|
||||||
msgstr ""
|
msgstr "時"
|
||||||
|
|
||||||
msgid "minutes"
|
msgid "minutes"
|
||||||
msgstr ""
|
msgstr "分"
|
||||||
|
|
||||||
msgid "seconds"
|
msgid "seconds"
|
||||||
msgstr ""
|
msgstr "秒"
|
||||||
|
|
||||||
msgid "hour"
|
msgid "hour"
|
||||||
msgstr ""
|
msgstr "時"
|
||||||
|
|
||||||
msgid "minute"
|
msgid "minute"
|
||||||
msgstr ""
|
msgstr "分"
|
||||||
|
|
||||||
msgid "second"
|
msgid "second"
|
||||||
msgstr ""
|
msgstr "秒"
|
||||||
|
@ -230,7 +230,7 @@ class AutoUpdate(plugins.Plugin):
|
|||||||
if num_installed > 0:
|
if num_installed > 0:
|
||||||
display.update(force=True, new_data={'status': 'Rebooting ...'})
|
display.update(force=True, new_data={'status': 'Rebooting ...'})
|
||||||
time.sleep(3)
|
time.sleep(3)
|
||||||
os.system("service pwnagotchi restart")
|
pwnagotchi.reboot()
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.error("[update] %s" % e)
|
logging.error("[update] %s" % e)
|
||||||
|
@ -5,7 +5,6 @@ import time
|
|||||||
import random
|
import random
|
||||||
from io import TextIOWrapper
|
from io import TextIOWrapper
|
||||||
import os
|
import os
|
||||||
import platform
|
|
||||||
|
|
||||||
import pwnagotchi
|
import pwnagotchi
|
||||||
from pwnagotchi import plugins
|
from pwnagotchi import plugins
|
||||||
@ -36,6 +35,7 @@ class FixServices(plugins.Plugin):
|
|||||||
self.pattern4 = re.compile(r'error 400: could not find interface wlan0mon')
|
self.pattern4 = re.compile(r'error 400: could not find interface wlan0mon')
|
||||||
self.pattern5 = re.compile(r'fatal error: concurrent map iteration and map write')
|
self.pattern5 = re.compile(r'fatal error: concurrent map iteration and map write')
|
||||||
self.pattern6 = re.compile(r'panic: runtime error')
|
self.pattern6 = re.compile(r'panic: runtime error')
|
||||||
|
self.pattern7 = re.compile(r'ieee80211 phy0: _brcmf_set_multicast_list: Setting allmulti failed, -110')
|
||||||
self.isReloadingMon = False
|
self.isReloadingMon = False
|
||||||
self.connection = None
|
self.connection = None
|
||||||
self.LASTTRY = 0
|
self.LASTTRY = 0
|
||||||
@ -112,54 +112,49 @@ class FixServices(plugins.Plugin):
|
|||||||
logging.debug("[Fix_Services]**** epoch")
|
logging.debug("[Fix_Services]**** epoch")
|
||||||
if time.time() - self.LASTTRY > 180:
|
if time.time() - self.LASTTRY > 180:
|
||||||
# get last 10 lines
|
# get last 10 lines
|
||||||
display = None
|
display = agent.view()
|
||||||
|
|
||||||
logging.debug("[Fix_Services]**** checking")
|
logging.debug("[Fix_Services]**** checking")
|
||||||
|
|
||||||
# Look for pattern 1
|
# Look for pattern 1
|
||||||
if platform.machine().startswith('arm'):
|
if len(self.pattern.findall(last_lines)) >= 3:
|
||||||
if len(self.pattern.findall(last_lines)) >= 3:
|
logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines)
|
||||||
logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines)
|
if hasattr(agent, 'view'):
|
||||||
if hasattr(agent, 'view'):
|
display.set('status', 'Blind-Bug detected. Restarting.')
|
||||||
display = agent.view()
|
display.update(force=True)
|
||||||
display.set('status', 'Blind-Bug detected. Restarting.')
|
logging.debug('[Fix_Services] Blind-Bug detected. Restarting.')
|
||||||
display.update(force=True)
|
try:
|
||||||
logging.debug('[Fix_Services] Blind-Bug detected. Restarting.')
|
self._tryTurningItOffAndOnAgain(agent)
|
||||||
try:
|
except Exception as err:
|
||||||
self._tryTurningItOffAndOnAgain(agent)
|
logging.warning("[Fix_Services] TTOAOA: %s" % repr(err))
|
||||||
except Exception as err:
|
|
||||||
logging.warning("[Fix_Services] TTOAOA: %s" % repr(err))
|
|
||||||
|
|
||||||
# Look for pattern 2
|
# Look for pattern 2
|
||||||
elif len(self.pattern2.findall(other_last_lines)) >= 5:
|
elif len(self.pattern2.findall(other_last_lines)) >= 5:
|
||||||
if platform.machine().startswith('arm'):
|
logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines)
|
||||||
logging.debug("[Fix_Services]**** Should trigger a reload of the wlan0mon device:\n%s" % last_lines)
|
if hasattr(agent, 'view'):
|
||||||
if hasattr(agent, 'view'):
|
display.set('status', 'Wifi channel stuck. Restarting recon.')
|
||||||
display = agent.view()
|
display.update(force=True)
|
||||||
display.set('status', 'Wifi channel stuck. Restarting recon.')
|
logging.debug('[Fix_Services] Wifi channel stuck. Restarting recon.')
|
||||||
display.update(force=True)
|
|
||||||
logging.debug('[Fix_Services] Wifi channel stuck. Restarting recon.')
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
result = agent.run("wifi.recon off; wifi.recon on")
|
result = agent.run("wifi.recon off; wifi.recon on")
|
||||||
if result["success"]:
|
if result["success"]:
|
||||||
logging.debug("[Fix_Services] wifi.recon flip: success!")
|
logging.debug("[Fix_Services] wifi.recon flip: success!")
|
||||||
if display:
|
if display:
|
||||||
display.update(force=True, new_data={"status": "Wifi recon flipped!",
|
display.update(force=True, new_data={"status": "Wifi recon flipped!",
|
||||||
"face": faces.COOL})
|
"face": faces.COOL})
|
||||||
else:
|
|
||||||
print("Wifi recon flipped\nthat was easy!")
|
|
||||||
else:
|
else:
|
||||||
logging.warning("[Fix_Services] wifi.recon flip: FAILED: %s" % repr(result))
|
print("Wifi recon flipped\nthat was easy!")
|
||||||
|
else:
|
||||||
|
logging.warning("[Fix_Services] wifi.recon flip: FAILED: %s" % repr(result))
|
||||||
|
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
logging.error("[Fix_Services wifi.recon flip] %s" % repr(err))
|
logging.error("[Fix_Services wifi.recon flip] %s" % repr(err))
|
||||||
|
|
||||||
# Look for pattern 3
|
# Look for pattern 3
|
||||||
elif len(self.pattern3.findall(other_last_lines)) >= 1:
|
elif len(self.pattern3.findall(other_last_lines)) >= 1:
|
||||||
logging.debug("[Fix_Services] Firmware has halted or crashed. Restarting wlan0mon.")
|
logging.debug("[Fix_Services] Firmware has halted or crashed. Restarting wlan0mon.")
|
||||||
if hasattr(agent, 'view'):
|
if hasattr(agent, 'view'):
|
||||||
display = agent.view()
|
|
||||||
display.set('status', 'Firmware has halted or crashed. Restarting wlan0mon.')
|
display.set('status', 'Firmware has halted or crashed. Restarting wlan0mon.')
|
||||||
display.update(force=True)
|
display.update(force=True)
|
||||||
try:
|
try:
|
||||||
@ -173,7 +168,6 @@ class FixServices(plugins.Plugin):
|
|||||||
elif len(self.pattern4.findall(other_other_last_lines)) >= 3:
|
elif len(self.pattern4.findall(other_other_last_lines)) >= 3:
|
||||||
logging.debug("[Fix_Services] wlan0 is down!")
|
logging.debug("[Fix_Services] wlan0 is down!")
|
||||||
if hasattr(agent, 'view'):
|
if hasattr(agent, 'view'):
|
||||||
display = agent.view()
|
|
||||||
display.set('status', 'Restarting wlan0 now!')
|
display.set('status', 'Restarting wlan0 now!')
|
||||||
display.update(force=True)
|
display.update(force=True)
|
||||||
try:
|
try:
|
||||||
@ -187,7 +181,6 @@ class FixServices(plugins.Plugin):
|
|||||||
elif len(self.pattern5.findall(other_other_last_lines)) >= 1:
|
elif len(self.pattern5.findall(other_other_last_lines)) >= 1:
|
||||||
logging.debug("[Fix_Services] Bettercap has crashed!")
|
logging.debug("[Fix_Services] Bettercap has crashed!")
|
||||||
if hasattr(agent, 'view'):
|
if hasattr(agent, 'view'):
|
||||||
display = agent.view()
|
|
||||||
display.set('status', 'Restarting pwnagotchi!')
|
display.set('status', 'Restarting pwnagotchi!')
|
||||||
display.update(force=True)
|
display.update(force=True)
|
||||||
os.system("systemctl restart bettercap")
|
os.system("systemctl restart bettercap")
|
||||||
@ -197,11 +190,28 @@ class FixServices(plugins.Plugin):
|
|||||||
elif len(self.pattern6.findall(other_other_last_lines)) >= 1:
|
elif len(self.pattern6.findall(other_other_last_lines)) >= 1:
|
||||||
logging.debug("[Fix_Services] Bettercap has crashed!")
|
logging.debug("[Fix_Services] Bettercap has crashed!")
|
||||||
if hasattr(agent, 'view'):
|
if hasattr(agent, 'view'):
|
||||||
display = agent.view()
|
|
||||||
display.set('status', 'Restarting pwnagotchi!')
|
display.set('status', 'Restarting pwnagotchi!')
|
||||||
display.update(force=True)
|
display.update(force=True)
|
||||||
os.system("systemctl restart bettercap")
|
os.system("systemctl restart bettercap")
|
||||||
pwnagotchi.restart("AUTO")
|
pwnagotchi.restart("AUTO")
|
||||||
|
|
||||||
|
# Look for pattern 7
|
||||||
|
elif len(self.pattern7.findall(other_other_last_lines)) >= 1:
|
||||||
|
logging.debug("[Fix_Services] Monitor mode failed!")
|
||||||
|
try:
|
||||||
|
result = agent.run("wifi.recon off; wifi.recon on")
|
||||||
|
if result["success"]:
|
||||||
|
logging.debug("[Fix_Services] wifi.recon flip: success!")
|
||||||
|
if display:
|
||||||
|
display.update(force=True, new_data={"status": "Wifi recon flipped!",
|
||||||
|
"face": faces.COOL})
|
||||||
|
else:
|
||||||
|
print("Wifi recon flipped\nthat was easy!")
|
||||||
|
else:
|
||||||
|
logging.warning("[Fix_Services] wifi.recon flip: FAILED: %s" % repr(result))
|
||||||
|
|
||||||
|
except Exception as err:
|
||||||
|
logging.error("[Fix_Services wifi.recon flip] %s" % repr(err))
|
||||||
else:
|
else:
|
||||||
print("logs look good")
|
print("logs look good")
|
||||||
|
|
||||||
|
@ -14,8 +14,9 @@ class GPIOButtons(plugins.Plugin):
|
|||||||
self.running = False
|
self.running = False
|
||||||
self.ports = {}
|
self.ports = {}
|
||||||
self.commands = None
|
self.commands = None
|
||||||
|
self.options = dict()
|
||||||
|
|
||||||
def runCommand(self, channel):
|
def runcommand(self, channel):
|
||||||
command = self.ports[channel]
|
command = self.ports[channel]
|
||||||
logging.info(f"Button Pressed! Running command: {command}")
|
logging.info(f"Button Pressed! Running command: {command}")
|
||||||
process = subprocess.Popen(command, shell=True, stdin=None, stdout=open("/dev/null", "w"), stderr=None,
|
process = subprocess.Popen(command, shell=True, stdin=None, stdout=open("/dev/null", "w"), stderr=None,
|
||||||
@ -35,8 +36,8 @@ class GPIOButtons(plugins.Plugin):
|
|||||||
gpio = int(gpio)
|
gpio = int(gpio)
|
||||||
self.ports[gpio] = command
|
self.ports[gpio] = command
|
||||||
GPIO.setup(gpio, GPIO.IN, GPIO.PUD_UP)
|
GPIO.setup(gpio, GPIO.IN, GPIO.PUD_UP)
|
||||||
GPIO.add_event_detect(gpio, GPIO.FALLING, callback=self.runCommand, bouncetime=600)
|
GPIO.add_event_detect(gpio, GPIO.FALLING, callback=self.runcommand, bouncetime=600)
|
||||||
#set pimoroni display hat mini LED off/dim
|
# set pimoroni display hat mini LED off/dim
|
||||||
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
GPIO.setup(17, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||||
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
GPIO.setup(22, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||||
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
GPIO.setup(27, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
|
||||||
|
@ -89,7 +89,7 @@ class Grid(plugins.Plugin):
|
|||||||
logging.debug("checking pcap's")
|
logging.debug("checking pcap's")
|
||||||
config = agent.config()
|
config = agent.config()
|
||||||
|
|
||||||
pcap_files = glob.glob(os.path.join(agent.config()['bettercap']['handshakes'], "*.pcap"))
|
pcap_files = glob.glob(os.path.join(config['bettercap']['handshakes'], "*.pcap"))
|
||||||
num_networks = len(pcap_files)
|
num_networks = len(pcap_files)
|
||||||
reported = self.report.data_field_or('reported', default=[])
|
reported = self.report.data_field_or('reported', default=[])
|
||||||
num_reported = len(reported)
|
num_reported = len(reported)
|
||||||
|
@ -253,7 +253,6 @@ class Logtail(plugins.Plugin):
|
|||||||
"""
|
"""
|
||||||
logging.info("Logtail plugin loaded.")
|
logging.info("Logtail plugin loaded.")
|
||||||
|
|
||||||
|
|
||||||
def on_webhook(self, path, request):
|
def on_webhook(self, path, request):
|
||||||
if not self.ready:
|
if not self.ready:
|
||||||
return "Plugin not ready"
|
return "Plugin not ready"
|
||||||
|
@ -130,7 +130,7 @@ class MemTemp(plugins.Plugin):
|
|||||||
except Exception:
|
except Exception:
|
||||||
# Set default position based on screen type
|
# Set default position based on screen type
|
||||||
if ui.is_waveshare_v2():
|
if ui.is_waveshare_v2():
|
||||||
h_pos = (178, 84)
|
h_pos = (175, 84)
|
||||||
v_pos = (197, 74)
|
v_pos = (197, 74)
|
||||||
elif ui.is_waveshare_v1():
|
elif ui.is_waveshare_v1():
|
||||||
h_pos = (170, 80)
|
h_pos = (170, 80)
|
||||||
|
@ -18,12 +18,14 @@ def systemd_dropin(name, content):
|
|||||||
|
|
||||||
systemctl("daemon-reload")
|
systemctl("daemon-reload")
|
||||||
|
|
||||||
|
|
||||||
def systemctl(command, unit=None):
|
def systemctl(command, unit=None):
|
||||||
if unit:
|
if unit:
|
||||||
os.system("/bin/systemctl %s %s" % (command, unit))
|
os.system("/bin/systemctl %s %s" % (command, unit))
|
||||||
else:
|
else:
|
||||||
os.system("/bin/systemctl %s" % command)
|
os.system("/bin/systemctl %s" % command)
|
||||||
|
|
||||||
|
|
||||||
def run_task(name, options):
|
def run_task(name, options):
|
||||||
task_service_name = "switcher-%s-task.service" % name
|
task_service_name = "switcher-%s-task.service" % name
|
||||||
# save all the commands to a shell script
|
# save all the commands to a shell script
|
||||||
@ -57,7 +59,7 @@ def run_task(name, options):
|
|||||||
""" % (name, task_service_name, name))
|
""" % (name, task_service_name, name))
|
||||||
|
|
||||||
if 'reboot' in options and options['reboot']:
|
if 'reboot' in options and options['reboot']:
|
||||||
# create a indication file!
|
# create an indication file!
|
||||||
# if this file is set, we want the switcher-tasks to run
|
# if this file is set, we want the switcher-tasks to run
|
||||||
open('/root/.switcher', 'a').close()
|
open('/root/.switcher', 'a').close()
|
||||||
|
|
||||||
@ -98,6 +100,7 @@ def run_task(name, options):
|
|||||||
systemctl("daemon-reload")
|
systemctl("daemon-reload")
|
||||||
systemctl("start", task_service_name)
|
systemctl("start", task_service_name)
|
||||||
|
|
||||||
|
|
||||||
class Switcher(plugins.Plugin):
|
class Switcher(plugins.Plugin):
|
||||||
__author__ = '33197631+dadav@users.noreply.github.com'
|
__author__ = '33197631+dadav@users.noreply.github.com'
|
||||||
__version__ = '0.0.1'
|
__version__ = '0.0.1'
|
||||||
|
@ -10,13 +10,17 @@ class Widget(object):
|
|||||||
def draw(self, canvas, drawer):
|
def draw(self, canvas, drawer):
|
||||||
raise Exception("not implemented")
|
raise Exception("not implemented")
|
||||||
|
|
||||||
|
# canvas.paste: https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.paste
|
||||||
|
# takes mask variable, to identify color system. (not used for pwnagotchi yet)
|
||||||
|
# Pwn should use "1" since its mainly black or white displays.
|
||||||
class Bitmap(Widget):
|
class Bitmap(Widget):
|
||||||
def __init__(self, path, xy, color=0):
|
def __init__(self, path, xy, color=0):
|
||||||
super().__init__(xy, color)
|
super().__init__(xy, color)
|
||||||
self.image = Image.open(path)
|
self.image = Image.open(path)
|
||||||
|
|
||||||
def draw(self, canvas, drawer):
|
def draw(self, canvas, drawer):
|
||||||
|
if self.color = 0xFF:
|
||||||
|
self.image = ImageOps.invert(self.image)
|
||||||
canvas.paste(self.image, self.xy)
|
canvas.paste(self.image, self.xy)
|
||||||
|
|
||||||
|
|
||||||
|
@ -28,6 +28,39 @@ class Display(View):
|
|||||||
def is_lcdhat(self):
|
def is_lcdhat(self):
|
||||||
return self._implementation.name == 'lcdhat'
|
return self._implementation.name == 'lcdhat'
|
||||||
|
|
||||||
|
def is_wavesharelcd0in96(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd0in96'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in3(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in3'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in8(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in8'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in9(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in9'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in14(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in14'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in28(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in28'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in47(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in47'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in54(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in54'
|
||||||
|
|
||||||
|
def is_wavesharelcd1in69(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd1in69'
|
||||||
|
|
||||||
|
def is_wavesharelcd2in0(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd2in0'
|
||||||
|
|
||||||
|
def is_wavesharelcd2in4(self):
|
||||||
|
return self._implementation.name == 'wavesharelcd2in4'
|
||||||
|
|
||||||
def is_waveshare144lcd(self):
|
def is_waveshare144lcd(self):
|
||||||
return self._implementation.name == 'waveshare144lcd'
|
return self._implementation.name == 'waveshare144lcd'
|
||||||
|
|
||||||
@ -231,6 +264,12 @@ class Display(View):
|
|||||||
|
|
||||||
def is_waveshareoledlcd(self):
|
def is_waveshareoledlcd(self):
|
||||||
return self._implementation.name == 'waveshareoledlcd'
|
return self._implementation.name == 'waveshareoledlcd'
|
||||||
|
|
||||||
|
def is_waveshareoledlcdvert(self):
|
||||||
|
return self._implementation.name == 'waveshareoledlcdvert'
|
||||||
|
|
||||||
|
def is_i2coled(self):
|
||||||
|
return self._implementation.name == 'i2coled'
|
||||||
|
|
||||||
def is_waveshare35lcd(self):
|
def is_waveshare35lcd(self):
|
||||||
return self._implementation.name == 'waveshare35lcd'
|
return self._implementation.name == 'waveshare35lcd'
|
||||||
|
@ -1,291 +1,341 @@
|
|||||||
from pwnagotchi.ui.hw.inky import Inky
|
|
||||||
from pwnagotchi.ui.hw.dummydisplay import DummyDisplay
|
|
||||||
from pwnagotchi.ui.hw.papirus import Papirus
|
|
||||||
from pwnagotchi.ui.hw.oledhat import OledHat
|
|
||||||
from pwnagotchi.ui.hw.lcdhat import LcdHat
|
|
||||||
from pwnagotchi.ui.hw.dfrobot import DFRobotV1
|
|
||||||
from pwnagotchi.ui.hw.dfrobot_v2 import DFRobotV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13 import WaveshareV1
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13_V2 import WaveshareV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13_V3 import WaveshareV3
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13_V4 import WaveshareV4
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in7 import Waveshare27inch
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in7_V2 import Waveshare27inchV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in9 import Waveshare29inch
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in9_V2 import Waveshare29inchV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in44lcd import Waveshare144lcd
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in54b import Waveshare154inchb
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13bc import Waveshare213bc
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13d import Waveshare213d
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13g import Waveshare2in13g
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13b_V4 import Waveshare213bV4
|
|
||||||
from pwnagotchi.ui.hw.waveshare3in5lcd import Waveshare35lcd
|
|
||||||
from pwnagotchi.ui.hw.spotpear24in import Spotpear24inch
|
|
||||||
from pwnagotchi.ui.hw.displayhatmini import DisplayHatMini
|
|
||||||
from pwnagotchi.ui.hw.pirateaudio import PirateAudio
|
|
||||||
from pwnagotchi.ui.hw.pitft import Pitft
|
|
||||||
from pwnagotchi.ui.hw.tftbonnet import TftBonnet
|
|
||||||
from pwnagotchi.ui.hw.adafruit2in13 import Adafruit2in13V3
|
|
||||||
from pwnagotchi.ui.hw.waveshareoledlcd import Waveshareoledlcd
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in02 import Waveshare1in02
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in54 import Waveshare154
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in54_V2 import Waveshare154V2
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in54b_V2 import Waveshare154bV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in54c import Waveshare1in54c
|
|
||||||
from pwnagotchi.ui.hw.waveshare1in64g import Waveshare1in64g
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in7b import Waveshare27b
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in7b_V2 import Waveshare27bV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in9b_V3 import Waveshare29bV3
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in9b_V4 import Waveshare29bV4
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in9bc import Waveshare2in9bc
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in9d import Waveshare2in9d
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in13b_V3 import Waveshare2in13bV3
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in36g import Waveshare2in36g
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in66 import Waveshare2in66
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in66b import Waveshare2in66b
|
|
||||||
from pwnagotchi.ui.hw.waveshare2in66g import Waveshare2in66g
|
|
||||||
from pwnagotchi.ui.hw.waveshare3in0g import Waveshare3in0g
|
|
||||||
from pwnagotchi.ui.hw.waveshare3in7 import Waveshare3in7
|
|
||||||
from pwnagotchi.ui.hw.waveshare3in52 import Waveshare3in52
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in01f import Waveshare4in01f
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in2 import Waveshare4in2
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in2_V2 import Waveshare4in2V2
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in2b_V2 import Waveshare4in2bV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in2bc import Waveshare4in2bc
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in26 import Waveshare4in26
|
|
||||||
from pwnagotchi.ui.hw.waveshare4in37g import Waveshare4in37g
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in65f import Waveshare5in65f
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in79 import Waveshare5in79
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in79b import Waveshare5in79b
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in83 import Waveshare5in83
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in83_V2 import Waveshare5in83V2
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in83b_V2 import Waveshare5in83bV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare5in83bc import Waveshare5in83bc
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in3f import Waveshare7in3f
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in3g import Waveshare7in3g
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in5 import Waveshare7in5
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in5_HD import Waveshare7in5HD
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in5_V2 import Waveshare7in5V2
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in5b_HD import Waveshare7in5bHD
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in5b_V2 import Waveshare7in5bV2
|
|
||||||
from pwnagotchi.ui.hw.waveshare7in5bc import Waveshare7in5bc
|
|
||||||
from pwnagotchi.ui.hw.waveshare13in3k import Waveshare13in3k
|
|
||||||
|
|
||||||
|
|
||||||
def display_for(config):
|
def display_for(config):
|
||||||
# config has been normalized already in utils.load_config
|
# config has been normalized already in utils.load_config
|
||||||
if config['ui']['display']['type'] == 'inky':
|
if config['ui']['display']['type'] == 'inky':
|
||||||
|
from pwnagotchi.ui.hw.inky import Inky
|
||||||
return Inky(config)
|
return Inky(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd0in96':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd0in96 import Wavesharelcd0in96
|
||||||
|
return Wavesharelcd0in96(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in3':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in3 import Wavesharelcd1in3
|
||||||
|
return Wavesharelcd1in3(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in8':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in8 import Wavesharelcd1in8
|
||||||
|
return Wavesharelcd1in8(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in9':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in9 import Wavesharelcd1in9
|
||||||
|
return Wavesharelcd1in9(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in14':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in14 import Wavesharelcd1in14
|
||||||
|
return Wavesharelcd1in14(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in28':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in28 import Wavesharelcd1in28
|
||||||
|
return Wavesharelcd1in28(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in47':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in47 import Wavesharelcd1in47
|
||||||
|
return Wavesharelcd1in47(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in54':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in54 import Wavesharelcd1in54
|
||||||
|
return Wavesharelcd1in54(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd1in69':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd1in69 import Wavesharelcd1in69
|
||||||
|
return Wavesharelcd1in69(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd2in0':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd2in0 import Wavesharelcd2in0
|
||||||
|
return Wavesharelcd2in0(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'wavesharelcd2in4':
|
||||||
|
from pwnagotchi.ui.hw.wavesharelcd2in4 import Wavesharelcd2in4
|
||||||
|
return Wavesharelcd2in4(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'dummydisplay':
|
elif config['ui']['display']['type'] == 'dummydisplay':
|
||||||
|
from pwnagotchi.ui.hw.dummydisplay import DummyDisplay
|
||||||
return DummyDisplay(config)
|
return DummyDisplay(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'papirus':
|
elif config['ui']['display']['type'] == 'papirus':
|
||||||
|
from pwnagotchi.ui.hw.papirus import Papirus
|
||||||
return Papirus(config)
|
return Papirus(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'oledhat':
|
elif config['ui']['display']['type'] == 'oledhat':
|
||||||
|
from pwnagotchi.ui.hw.oledhat import OledHat
|
||||||
return OledHat(config)
|
return OledHat(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'lcdhat':
|
elif config['ui']['display']['type'] == 'lcdhat':
|
||||||
|
from pwnagotchi.ui.hw.lcdhat import LcdHat
|
||||||
return LcdHat(config)
|
return LcdHat(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'dfrobot_1':
|
elif config['ui']['display']['type'] == 'dfrobot_1':
|
||||||
|
from pwnagotchi.ui.hw.dfrobot import DFRobotV1
|
||||||
return DFRobotV1(config)
|
return DFRobotV1(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'dfrobot_2':
|
elif config['ui']['display']['type'] == 'dfrobot_2':
|
||||||
|
from pwnagotchi.ui.hw.dfrobot_v2 import DFRobotV2
|
||||||
return DFRobotV2(config)
|
return DFRobotV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare144lcd':
|
elif config['ui']['display']['type'] == 'waveshare144lcd':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in44lcd import Waveshare144lcd
|
||||||
return Waveshare144lcd(config)
|
return Waveshare144lcd(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare35lcd':
|
elif config['ui']['display']['type'] == 'waveshare35lcd':
|
||||||
|
from pwnagotchi.ui.hw.waveshare3in5lcd import Waveshare35lcd
|
||||||
return Waveshare35lcd(config)
|
return Waveshare35lcd(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'spotpear24inch':
|
elif config['ui']['display']['type'] == 'spotpear24inch':
|
||||||
|
from pwnagotchi.ui.hw.spotpear24in import Spotpear24inch
|
||||||
return Spotpear24inch(config)
|
return Spotpear24inch(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'displayhatmini':
|
elif config['ui']['display']['type'] == 'displayhatmini':
|
||||||
|
from pwnagotchi.ui.hw.displayhatmini import DisplayHatMini
|
||||||
return DisplayHatMini(config)
|
return DisplayHatMini(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'pirateaudio':
|
elif config['ui']['display']['type'] == 'pirateaudio':
|
||||||
|
from pwnagotchi.ui.hw.pirateaudio import PirateAudio
|
||||||
return PirateAudio(config)
|
return PirateAudio(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'pitft':
|
elif config['ui']['display']['type'] == 'pitft':
|
||||||
|
from pwnagotchi.ui.hw.pitft import Pitft
|
||||||
return Pitft(config)
|
return Pitft(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'tftbonnet':
|
elif config['ui']['display']['type'] == 'tftbonnet':
|
||||||
|
from pwnagotchi.ui.hw.tftbonnet import TftBonnet
|
||||||
return TftBonnet(config)
|
return TftBonnet(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshareoledlcd':
|
elif config['ui']['display']['type'] == 'waveshareoledlcd':
|
||||||
|
from pwnagotchi.ui.hw.waveshareoledlcd import Waveshareoledlcd
|
||||||
return Waveshareoledlcd(config)
|
return Waveshareoledlcd(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'waveshareoledlcdvert':
|
||||||
|
from pwnagotchi.ui.hw.waveshareoledlcdvert import Waveshareoledlcdvert
|
||||||
|
return Waveshareoledlcdvert(config)
|
||||||
|
|
||||||
|
elif config['ui']['display']['type'] == 'i2coled':
|
||||||
|
from pwnagotchi.ui.hw.i2coled import I2COled
|
||||||
|
return I2COled(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in02':
|
elif config['ui']['display']['type'] == 'waveshare1in02':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in02 import Waveshare1in02
|
||||||
return Waveshare1in02(config)
|
return Waveshare1in02(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in54':
|
elif config['ui']['display']['type'] == 'waveshare1in54':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in54 import Waveshare154
|
||||||
return Waveshare154(config)
|
return Waveshare154(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in54_v2':
|
elif config['ui']['display']['type'] == 'waveshare1in54_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in54_V2 import Waveshare154V2
|
||||||
return Waveshare154V2(config)
|
return Waveshare154V2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in54b':
|
elif config['ui']['display']['type'] == 'waveshare1in54b':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in54b import Waveshare154inchb
|
||||||
return Waveshare154inchb(config)
|
return Waveshare154inchb(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in54b_v2':
|
elif config['ui']['display']['type'] == 'waveshare1in54b_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in54b_V2 import Waveshare154bV2
|
||||||
return Waveshare154bV2(config)
|
return Waveshare154bV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in54c':
|
elif config['ui']['display']['type'] == 'waveshare1in54c':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in54c import Waveshare1in54c
|
||||||
return Waveshare1in54c(config)
|
return Waveshare1in54c(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare1in64g':
|
elif config['ui']['display']['type'] == 'waveshare1in64g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare1in64g import Waveshare1in64g
|
||||||
return Waveshare1in64g(config)
|
return Waveshare1in64g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in7':
|
elif config['ui']['display']['type'] == 'waveshare2in7':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in7 import Waveshare27inch
|
||||||
return Waveshare27inch(config)
|
return Waveshare27inch(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in7_v2':
|
elif config['ui']['display']['type'] == 'waveshare2in7_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in7_V2 import Waveshare27inchV2
|
||||||
return Waveshare27inchV2(config)
|
return Waveshare27inchV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in7b':
|
elif config['ui']['display']['type'] == 'waveshare2in7b':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in7b import Waveshare27b
|
||||||
return Waveshare27b(config)
|
return Waveshare27b(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in7b_v2':
|
elif config['ui']['display']['type'] == 'waveshare2in7b_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in7b_V2 import Waveshare27bV2
|
||||||
return Waveshare27bV2(config)
|
return Waveshare27bV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in9':
|
elif config['ui']['display']['type'] == 'waveshare2in9':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in9 import Waveshare29inch
|
||||||
return Waveshare29inch(config)
|
return Waveshare29inch(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in9bc':
|
elif config['ui']['display']['type'] == 'waveshare2in9bc':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in9bc import Waveshare2in9bc
|
||||||
return Waveshare2in9bc(config)
|
return Waveshare2in9bc(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in9d':
|
elif config['ui']['display']['type'] == 'waveshare2in9d':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in9d import Waveshare2in9d
|
||||||
return Waveshare2in9d(config)
|
return Waveshare2in9d(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in9_v2':
|
elif config['ui']['display']['type'] == 'waveshare2in9_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in9_V2 import Waveshare29inchV2
|
||||||
return Waveshare29inchV2(config)
|
return Waveshare29inchV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in9b_v3':
|
elif config['ui']['display']['type'] == 'waveshare2in9b_v3':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in9b_V3 import Waveshare29bV3
|
||||||
return Waveshare29bV3(config)
|
return Waveshare29bV3(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in9b_v4':
|
elif config['ui']['display']['type'] == 'waveshare2in9b_v4':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in9b_V4 import Waveshare29bV4
|
||||||
return Waveshare29bV4(config)
|
return Waveshare29bV4(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare_1':
|
elif config['ui']['display']['type'] == 'waveshare_1':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13 import WaveshareV1
|
||||||
return WaveshareV1(config)
|
return WaveshareV1(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare_2':
|
elif config['ui']['display']['type'] == 'waveshare_2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13_V2 import WaveshareV2
|
||||||
return WaveshareV2(config)
|
return WaveshareV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare_3':
|
elif config['ui']['display']['type'] == 'waveshare_3':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13_V3 import WaveshareV3
|
||||||
return WaveshareV3(config)
|
return WaveshareV3(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare_4':
|
elif config['ui']['display']['type'] == 'waveshare_4':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13_V4 import WaveshareV4
|
||||||
return WaveshareV4(config)
|
return WaveshareV4(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'adafruit2in13':
|
elif config['ui']['display']['type'] == 'adafruit2in13_v3':
|
||||||
return Adafruit2in13(config)
|
from pwnagotchi.ui.hw.adafruit2in13 import Adafruit2in13V3
|
||||||
|
return Adafruit2in13V3(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in13bc':
|
elif config['ui']['display']['type'] == 'waveshare2in13bc':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13bc import Waveshare213bc
|
||||||
return Waveshare213bc(config)
|
return Waveshare213bc(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in13d':
|
elif config['ui']['display']['type'] == 'waveshare2in13d':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13d import Waveshare213d
|
||||||
return Waveshare213d(config)
|
return Waveshare213d(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in13b_v3':
|
elif config['ui']['display']['type'] == 'waveshare2in13b_v3':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13b_V3 import Waveshare2in13bV3
|
||||||
return Waveshare2in13bV3(config)
|
return Waveshare2in13bV3(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in13b_v4':
|
elif config['ui']['display']['type'] == 'waveshare2in13b_v4':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13b_V4 import Waveshare213bV4
|
||||||
return Waveshare213bV4(config)
|
return Waveshare213bV4(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in13g':
|
elif config['ui']['display']['type'] == 'waveshare2in13g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in13g import Waveshare2in13g
|
||||||
return Waveshare2in13g(config)
|
return Waveshare2in13g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in36g':
|
elif config['ui']['display']['type'] == 'waveshare2in36g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in36g import Waveshare2in36g
|
||||||
return Waveshare2in36g(config)
|
return Waveshare2in36g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in66':
|
elif config['ui']['display']['type'] == 'waveshare2in66':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in66 import Waveshare2in66
|
||||||
return Waveshare2in66(config)
|
return Waveshare2in66(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in66b':
|
elif config['ui']['display']['type'] == 'waveshare2in66b':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in66b import Waveshare2in66b
|
||||||
return Waveshare2in66b(config)
|
return Waveshare2in66b(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare2in66g':
|
elif config['ui']['display']['type'] == 'waveshare2in66g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare2in66g import Waveshare2in66g
|
||||||
return Waveshare2in66g(config)
|
return Waveshare2in66g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare3in0g':
|
elif config['ui']['display']['type'] == 'waveshare3in0g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare3in0g import Waveshare3in0g
|
||||||
return Waveshare3in0g(config)
|
return Waveshare3in0g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare3in7':
|
elif config['ui']['display']['type'] == 'waveshare3in7':
|
||||||
|
from pwnagotchi.ui.hw.waveshare3in7 import Waveshare3in7
|
||||||
return Waveshare3in7(config)
|
return Waveshare3in7(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare3in52':
|
elif config['ui']['display']['type'] == 'waveshare3in52':
|
||||||
|
from pwnagotchi.ui.hw.waveshare3in52 import Waveshare3in52
|
||||||
return Waveshare3in52(config)
|
return Waveshare3in52(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in01f':
|
elif config['ui']['display']['type'] == 'waveshare4in01f':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in01f import Waveshare4in01f
|
||||||
return Waveshare4in01f(config)
|
return Waveshare4in01f(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in2':
|
elif config['ui']['display']['type'] == 'waveshare4in2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in2 import Waveshare4in2
|
||||||
return Waveshare4in2(config)
|
return Waveshare4in2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in2_v2':
|
elif config['ui']['display']['type'] == 'waveshare4in2_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in2_V2 import Waveshare4in2V2
|
||||||
return Waveshare4in2V2(config)
|
return Waveshare4in2V2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in2b_v2':
|
elif config['ui']['display']['type'] == 'waveshare4in2b_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in2b_V2 import Waveshare4in2bV2
|
||||||
return Waveshare4in2bV2(config)
|
return Waveshare4in2bV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in2bc':
|
elif config['ui']['display']['type'] == 'waveshare4in2bc':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in2bc import Waveshare4in2bc
|
||||||
return Waveshare4in2bc(config)
|
return Waveshare4in2bc(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in26':
|
elif config['ui']['display']['type'] == 'waveshare4in26':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in26 import Waveshare4in26
|
||||||
return Waveshare4in26(config)
|
return Waveshare4in26(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare4in37g':
|
elif config['ui']['display']['type'] == 'waveshare4in37g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare4in37g import Waveshare4in37g
|
||||||
return Waveshare4in37g(config)
|
return Waveshare4in37g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in65f':
|
elif config['ui']['display']['type'] == 'waveshare5in65f':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in65f import Waveshare5in65f
|
||||||
return Waveshare5in65f(config)
|
return Waveshare5in65f(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in79':
|
elif config['ui']['display']['type'] == 'waveshare5in79':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in79 import Waveshare5in79
|
||||||
return Waveshare5in79(config)
|
return Waveshare5in79(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in79b':
|
elif config['ui']['display']['type'] == 'waveshare5in79b':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in79b import Waveshare5in79b
|
||||||
return Waveshare5in79b(config)
|
return Waveshare5in79b(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in83':
|
elif config['ui']['display']['type'] == 'waveshare5in83':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in83 import Waveshare5in83
|
||||||
return Waveshare5in83(config)
|
return Waveshare5in83(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in83_v2':
|
elif config['ui']['display']['type'] == 'waveshare5in83_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in83_V2 import Waveshare5in83V2
|
||||||
return Waveshare5in83V2(config)
|
return Waveshare5in83V2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in83b_v2':
|
elif config['ui']['display']['type'] == 'waveshare5in83b_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in83b_V2 import Waveshare5in83bV2
|
||||||
return Waveshare5in83bV2(config)
|
return Waveshare5in83bV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare5in83bc':
|
elif config['ui']['display']['type'] == 'waveshare5in83bc':
|
||||||
|
from pwnagotchi.ui.hw.waveshare5in83bc import Waveshare5in83bc
|
||||||
return Waveshare5in83bc(config)
|
return Waveshare5in83bc(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in3f':
|
elif config['ui']['display']['type'] == 'waveshare7in3f':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in3f import Waveshare7in3f
|
||||||
return Waveshare7in3f(config)
|
return Waveshare7in3f(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in3g':
|
elif config['ui']['display']['type'] == 'waveshare7in3g':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in3g import Waveshare7in3g
|
||||||
return Waveshare7in3g(config)
|
return Waveshare7in3g(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in5':
|
elif config['ui']['display']['type'] == 'waveshare7in5':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in5 import Waveshare7in5
|
||||||
return Waveshare7in5(config)
|
return Waveshare7in5(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in5_HD':
|
elif config['ui']['display']['type'] == 'waveshare7in5_HD':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in5_HD import Waveshare7in5HD
|
||||||
return Waveshare7in5HD(config)
|
return Waveshare7in5HD(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in5_v2':
|
elif config['ui']['display']['type'] == 'waveshare7in5_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in5_V2 import Waveshare7in5V2
|
||||||
return Waveshare7in5V2(config)
|
return Waveshare7in5V2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in5b_HD':
|
elif config['ui']['display']['type'] == 'waveshare7in5b_HD':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in5b_HD import Waveshare7in5bHD
|
||||||
return Waveshare7in5bHD(config)
|
return Waveshare7in5bHD(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in5b_v2':
|
elif config['ui']['display']['type'] == 'waveshare7in5b_v2':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in5b_V2 import Waveshare7in5bV2
|
||||||
return Waveshare7in5bV2(config)
|
return Waveshare7in5bV2(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare7in5bc':
|
elif config['ui']['display']['type'] == 'waveshare7in5bc':
|
||||||
|
from pwnagotchi.ui.hw.waveshare7in5bc import Waveshare7in5bc
|
||||||
return Waveshare7in5bc(config)
|
return Waveshare7in5bc(config)
|
||||||
|
|
||||||
elif config['ui']['display']['type'] == 'waveshare13in3k':
|
elif config['ui']['display']['type'] == 'waveshare13in3k':
|
||||||
|
from pwnagotchi.ui.hw.waveshare13in3k import Waveshare13in3k
|
||||||
return Waveshare13in3k(config)
|
return Waveshare13in3k(config)
|
||||||
|
@ -34,10 +34,10 @@ class DisplayHatMini(DisplayImpl):
|
|||||||
def initialize(self):
|
def initialize(self):
|
||||||
logging.info("initializing Display Hat Mini")
|
logging.info("initializing Display Hat Mini")
|
||||||
from pwnagotchi.ui.hw.libs.pimoroni.displayhatmini.ST7789 import ST7789
|
from pwnagotchi.ui.hw.libs.pimoroni.displayhatmini.ST7789 import ST7789
|
||||||
self._display = ST7789(0, 1, 9, 13)
|
self._display = ST7789(0, 1, 9, 13, width=self._layout['width'], height=self._layout['height'], rotation=0)
|
||||||
|
|
||||||
def render(self, canvas):
|
def render(self, canvas):
|
||||||
self._display.display(canvas)
|
self._display.display(canvas)
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
self._display.clear()
|
pass
|
||||||
|
67
pwnagotchi/ui/hw/i2coled.py
Normal file
67
pwnagotchi/ui/hw/i2coled.py
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
# Created for the Pwnagotchi project by RasTacsko
|
||||||
|
# HW libraries are based on the adafruit python SSD1306 repo:
|
||||||
|
# https://github.com/adafruit/Adafruit_Python_SSD1306
|
||||||
|
# SMBus parts coming from BLavery's lib_oled96 repo:
|
||||||
|
# https://github.com/BLavery/lib_oled96
|
||||||
|
# I2C address, width and height import from config.toml made by NurseJackass
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
import pwnagotchi.ui.fonts as fonts
|
||||||
|
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||||
|
|
||||||
|
#
|
||||||
|
# Default is 128x64 display on i2c address 0x3C
|
||||||
|
#
|
||||||
|
# Configure i2c address and dimensions in config.toml:
|
||||||
|
#
|
||||||
|
# ui.display.type = "i2coled"
|
||||||
|
# ui.display.i2c_addr = 0x3C
|
||||||
|
# ui.display.width = 128
|
||||||
|
# ui.display.height = 64
|
||||||
|
#
|
||||||
|
|
||||||
|
class I2COled(DisplayImpl):
|
||||||
|
def __init__(self, config):
|
||||||
|
self._config = config['ui']['display']
|
||||||
|
super(I2COled, self).__init__(config, 'i2coled')
|
||||||
|
|
||||||
|
def layout(self):
|
||||||
|
fonts.setup(8, 8, 8, 10, 10, 8)
|
||||||
|
self._layout['width'] = self._config['width'] if 'width' in self._config else 128
|
||||||
|
self._layout['height'] = self._config['height'] if 'height' in self._config else 64
|
||||||
|
self._layout['face'] = (0, 30)
|
||||||
|
self._layout['name'] = (0, 10)
|
||||||
|
self._layout['channel'] = (72, 10)
|
||||||
|
self._layout['aps'] = (0, 0)
|
||||||
|
self._layout['uptime'] = (87, 0)
|
||||||
|
self._layout['line1'] = [0, 9, 128, 9]
|
||||||
|
self._layout['line2'] = [0, 54, 128, 54]
|
||||||
|
self._layout['friend_face'] = (0, 41)
|
||||||
|
self._layout['friend_name'] = (40, 43)
|
||||||
|
self._layout['shakes'] = (0, 55)
|
||||||
|
self._layout['mode'] = (107, 10)
|
||||||
|
self._layout['status'] = {
|
||||||
|
'pos': (37, 19),
|
||||||
|
'font': fonts.status_font(fonts.Small),
|
||||||
|
'max': 18
|
||||||
|
}
|
||||||
|
return self._layout
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
i2caddr = self._config['i2c_addr'] if 'i2c_addr' in self._config else 0x3C
|
||||||
|
width = self._config['width'] if 'width' in self._config else 128
|
||||||
|
height = self._config['height'] if 'height' in self._config else 64
|
||||||
|
|
||||||
|
logging.info("initializing %dx%d I2C Oled Display on address 0x%X" % (width, height, i2caddr))
|
||||||
|
|
||||||
|
from pwnagotchi.ui.hw.libs.i2coled.epd import EPD
|
||||||
|
self._display = EPD(address=i2caddr, width=width, height=height)
|
||||||
|
self._display.Init()
|
||||||
|
self._display.Clear()
|
||||||
|
|
||||||
|
def render(self, canvas):
|
||||||
|
self._display.display(canvas)
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self._display.clear()
|
@ -33,7 +33,7 @@ class LcdHat(DisplayImpl):
|
|||||||
|
|
||||||
def initialize(self):
|
def initialize(self):
|
||||||
logging.info("initializing lcdhat display")
|
logging.info("initializing lcdhat display")
|
||||||
from pwnagotchi.ui.hw.libs.waveshare.lcdhat.epd import EPD
|
from pwnagotchi.ui.hw.libs.waveshare.lcd.lcdhat.epd import EPD
|
||||||
self._display = EPD()
|
self._display = EPD()
|
||||||
self._display.init()
|
self._display.init()
|
||||||
self._display.clear()
|
self._display.clear()
|
||||||
|
@ -93,6 +93,7 @@ ILI9341_GMCTRN1 = 0xE1
|
|||||||
|
|
||||||
ILI9341_PWCTR6 = 0xFC
|
ILI9341_PWCTR6 = 0xFC
|
||||||
|
|
||||||
|
|
||||||
class ILI9341(object):
|
class ILI9341(object):
|
||||||
"""Representation of an ILI9341 TFT LCD."""
|
"""Representation of an ILI9341 TFT LCD."""
|
||||||
|
|
||||||
@ -349,7 +350,6 @@ class ILI9341(object):
|
|||||||
# Rotate the image
|
# Rotate the image
|
||||||
pb = np.rot90(image, rotation // 90).astype('uint16')
|
pb = np.rot90(image, rotation // 90).astype('uint16')
|
||||||
|
|
||||||
|
|
||||||
# Mask and shift the 888 RGB into 565 RGB
|
# Mask and shift the 888 RGB into 565 RGB
|
||||||
red = (pb[..., [0]] & 0xf8) << 8
|
red = (pb[..., [0]] & 0xf8) << 8
|
||||||
green = (pb[..., [1]] & 0xfc) << 3
|
green = (pb[..., [1]] & 0xfc) << 3
|
||||||
|
@ -1,144 +1,164 @@
|
|||||||
FBIOGET_VSCREENINFO=0x4600
|
FBIOGET_VSCREENINFO = 0x4600
|
||||||
FBIOPUT_VSCREENINFO=0x4601
|
FBIOPUT_VSCREENINFO = 0x4601
|
||||||
FBIOGET_FSCREENINFO=0x4602
|
FBIOGET_FSCREENINFO = 0x4602
|
||||||
FBIOGETCMAP=0x4604
|
FBIOGETCMAP = 0x4604
|
||||||
FBIOPUTCMAP=0x4605
|
FBIOPUTCMAP = 0x4605
|
||||||
FBIOPAN_DISPLAY=0x4606
|
FBIOPAN_DISPLAY = 0x4606
|
||||||
|
|
||||||
FBIOGET_CON2FBMAP=0x460F
|
FBIOGET_CON2FBMAP = 0x460F
|
||||||
FBIOPUT_CON2FBMAP=0x4610
|
FBIOPUT_CON2FBMAP = 0x4610
|
||||||
FBIOBLANK=0x4611
|
FBIOBLANK = 0x4611
|
||||||
FBIO_ALLOC=0x4613
|
FBIO_ALLOC = 0x4613
|
||||||
FBIO_FREE=0x4614
|
FBIO_FREE = 0x4614
|
||||||
FBIOGET_GLYPH=0x4615
|
FBIOGET_GLYPH = 0x4615
|
||||||
FBIOGET_HWCINFO=0x4616
|
FBIOGET_HWCINFO = 0x4616
|
||||||
FBIOPUT_MODEINFO=0x4617
|
FBIOPUT_MODEINFO = 0x4617
|
||||||
FBIOGET_DISPINFO=0x4618
|
FBIOGET_DISPINFO = 0x4618
|
||||||
|
|
||||||
from mmap import mmap
|
from mmap import mmap
|
||||||
from fcntl import ioctl
|
from fcntl import ioctl
|
||||||
import struct
|
import struct
|
||||||
|
|
||||||
mm = None
|
mm = None
|
||||||
bpp, w, h = 0, 0, 0 # framebuffer bpp and size
|
bpp, w, h = 0, 0, 0 # framebuffer bpp and size
|
||||||
bytepp = 0
|
bytepp = 0
|
||||||
vx, vy, vw, vh = 0, 0, 0, 0 #virtual window offset and size
|
vx, vy, vw, vh = 0, 0, 0, 0 # virtual window offset and size
|
||||||
vi, fi = None, None
|
vi, fi = None, None
|
||||||
_fb_cmap = 'IIPPPP' # start, len, r, g, b, a
|
_fb_cmap = 'IIPPPP' # start, len, r, g, b, a
|
||||||
RGB = False
|
RGB = False
|
||||||
_verbose = False
|
_verbose = False
|
||||||
msize_kb = 0
|
msize_kb = 0
|
||||||
|
|
||||||
|
|
||||||
def report_fb(i=0, layer=0):
|
def report_fb(i=0, layer=0):
|
||||||
with open('/dev/fb'+str(i), 'r+b')as f:
|
with open('/dev/fb' + str(i), 'r+b') as f:
|
||||||
vi = ioctl(f, FBIOGET_VSCREENINFO, bytes(160))
|
vi = ioctl(f, FBIOGET_VSCREENINFO, bytes(160))
|
||||||
vi = list(struct.unpack('I'*40, vi))
|
vi = list(struct.unpack('I' * 40, vi))
|
||||||
ffm = 'c'*16+'L'+'I'*4+'H'*3+'ILIIHHH'
|
ffm = 'c' * 16 + 'L' + 'I' * 4 + 'H' * 3 + 'ILIIHHH'
|
||||||
fic = struct.calcsize(ffm)
|
fic = struct.calcsize(ffm)
|
||||||
fi = struct.unpack(ffm, ioctl(f, FBIOGET_FSCREENINFO, bytes(fic)))
|
fi = struct.unpack(ffm, ioctl(f, FBIOGET_FSCREENINFO, bytes(fic)))
|
||||||
|
|
||||||
|
|
||||||
def ready_fb(_bpp=None, i=0, layer=0, _win=None):
|
def ready_fb(_bpp=None, i=0, layer=0, _win=None):
|
||||||
global mm, bpp, w, h, vi, fi, RGB, msize_kb, vx, vy, vw, vh, bytepp
|
global mm, bpp, w, h, vi, fi, RGB, msize_kb, vx, vy, vw, vh, bytepp
|
||||||
if mm and bpp == _bpp: return mm, w, h, bpp
|
if mm and bpp == _bpp:
|
||||||
with open('/dev/fb'+str(i), 'r+b')as f:
|
return mm, w, h, bpp
|
||||||
vi = ioctl(f, FBIOGET_VSCREENINFO, bytes(160))
|
with open('/dev/fb' + str(i), 'r+b') as f:
|
||||||
vi = list(struct.unpack('I'*40, vi))
|
vi = ioctl(f, FBIOGET_VSCREENINFO, bytes(160))
|
||||||
bpp = vi[6]
|
vi = list(struct.unpack('I' * 40, vi))
|
||||||
bytepp = bpp//8
|
|
||||||
if _bpp:
|
|
||||||
vi[6] = _bpp # 24 bit = BGR 888 mode
|
|
||||||
try:
|
|
||||||
vi = ioctl(f, FBIOPUT_VSCREENINFO, struct.pack('I'*40, *vi)) # fb_var_screeninfo
|
|
||||||
vi = struct.unpack('I'*40,vi)
|
|
||||||
bpp = vi[6]
|
bpp = vi[6]
|
||||||
bytepp = bpp//8
|
bytepp = bpp // 8
|
||||||
except:
|
if _bpp:
|
||||||
pass
|
vi[6] = _bpp # 24 bit = BGR 888 mode
|
||||||
|
try:
|
||||||
if vi[8] == 0 : RGB = True
|
vi = ioctl(f, FBIOPUT_VSCREENINFO, struct.pack('I' * 40, *vi)) # fb_var_screeninfo
|
||||||
|
vi = struct.unpack('I' * 40, vi)
|
||||||
ffm = 'c'*16+'L'+'I'*4+'H'*3+'ILIIHHH'
|
bpp = vi[6]
|
||||||
fic = struct.calcsize(ffm)
|
bytepp = bpp // 8
|
||||||
fi = struct.unpack(ffm, ioctl(f, FBIOGET_FSCREENINFO, bytes(fic)))
|
except:
|
||||||
msize = fi[17] # = w*h*bpp//8
|
pass
|
||||||
ll, start = fi[-7:-5]
|
|
||||||
w, h = ll//bytepp, vi[1] # when screen is vertical, width becomes wrong. ll//3 is more accurate at such time.
|
|
||||||
if _win and len(_win)==4: # virtual window settings
|
|
||||||
vx, vy, vw, vh = _win
|
|
||||||
if vw == 'w': vw = w
|
|
||||||
if vh == 'h': vh = h
|
|
||||||
vx, vy, vw, vh = map(int, (vx, vy, vw, vh))
|
|
||||||
if vx>=w: vx = 0
|
|
||||||
if vy>=h: vy = 0
|
|
||||||
if vx>w: vw = w - vx
|
|
||||||
else: vw -= vx
|
|
||||||
if vy>h: vh = h - vy
|
|
||||||
else: vh -= vy
|
|
||||||
else:
|
|
||||||
vx, vy, vw, vh = 0,0,w,h
|
|
||||||
msize_kb = vw*vh*bytepp//1024 # more accurate FB memory size in kb
|
|
||||||
|
|
||||||
mm = mmap(f.fileno(), msize, offset=start)
|
if vi[8] == 0:
|
||||||
return mm, w, h, bpp#ll//(bpp//8), h
|
RGB = True
|
||||||
|
|
||||||
|
ffm = 'c' * 16 + 'L' + 'I' * 4 + 'H' * 3 + 'ILIIHHH'
|
||||||
|
fic = struct.calcsize(ffm)
|
||||||
|
fi = struct.unpack(ffm, ioctl(f, FBIOGET_FSCREENINFO, bytes(fic)))
|
||||||
|
msize = fi[17] # = w*h*bpp//8
|
||||||
|
ll, start = fi[-7:-5]
|
||||||
|
w, h = ll // bytepp, vi[1] # when screen is vertical, width becomes wrong. ll//3 is more accurate at such time.
|
||||||
|
if _win and len(_win) == 4: # virtual window settings
|
||||||
|
vx, vy, vw, vh = _win
|
||||||
|
if vw == 'w':
|
||||||
|
vw = w
|
||||||
|
if vh == 'h':
|
||||||
|
vh = h
|
||||||
|
vx, vy, vw, vh = map(int, (vx, vy, vw, vh))
|
||||||
|
if vx >= w:
|
||||||
|
vx = 0
|
||||||
|
if vy >= h:
|
||||||
|
vy = 0
|
||||||
|
if vx > w:
|
||||||
|
vw = w - vx
|
||||||
|
else:
|
||||||
|
vw -= vx
|
||||||
|
if vy > h:
|
||||||
|
vh = h - vy
|
||||||
|
else:
|
||||||
|
vh -= vy
|
||||||
|
else:
|
||||||
|
vx, vy, vw, vh = 0, 0, w, h
|
||||||
|
msize_kb = vw * vh * bytepp // 1024 # more accurate FB memory size in kb
|
||||||
|
|
||||||
|
mm = mmap(f.fileno(), msize, offset=start)
|
||||||
|
return mm, w, h, bpp # ll//(bpp//8), h
|
||||||
|
|
||||||
|
|
||||||
|
def fill_scr(r, g, b):
|
||||||
|
if bpp == 32:
|
||||||
|
seed = struct.pack('BBBB', b, g, r, 255)
|
||||||
|
elif bpp == 24:
|
||||||
|
seed = struct.pack('BBB', b, g, r)
|
||||||
|
elif bpp == 16:
|
||||||
|
seed = struct.pack('H', r >> 3 << 11 | g >> 2 << 5 | b >> 3)
|
||||||
|
mm.seek(0)
|
||||||
|
show_img(seed * vw * vh)
|
||||||
|
|
||||||
def fill_scr(r,g,b):
|
|
||||||
if bpp == 32:
|
|
||||||
seed = struct.pack('BBBB', b, g, r, 255)
|
|
||||||
elif bpp == 24:
|
|
||||||
seed = struct.pack('BBB', b, g, r)
|
|
||||||
elif bpp == 16:
|
|
||||||
seed = struct.pack('H', r>>3<<11 | g>>2<<5 | b>>3)
|
|
||||||
mm.seek(0)
|
|
||||||
show_img(seed * vw * vh)
|
|
||||||
|
|
||||||
def black_scr():
|
def black_scr():
|
||||||
fill_scr(0,0,0)
|
fill_scr(0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
def white_scr():
|
def white_scr():
|
||||||
fill_scr(255,255,255)
|
fill_scr(255, 255, 255)
|
||||||
|
|
||||||
|
|
||||||
|
def mmseekto(x, y):
|
||||||
|
mm.seek((x + y * w) * bytepp)
|
||||||
|
|
||||||
def mmseekto(x,y):
|
|
||||||
mm.seek((x + y*w) * bytepp)
|
|
||||||
|
|
||||||
def dot(x, y, r, g, b):
|
def dot(x, y, r, g, b):
|
||||||
mmseekto(x,y)
|
mmseekto(x, y)
|
||||||
mm.write(struct.pack('BBB',*((r,g,b) if RGB else (b,g,r))))
|
mm.write(struct.pack('BBB', *((r, g, b) if RGB else (b, g, r))))
|
||||||
|
|
||||||
|
|
||||||
|
def get_pixel(x, y):
|
||||||
|
mmseekto(x, y)
|
||||||
|
return mm.read(bytepp)
|
||||||
|
|
||||||
def get_pixel(x,y):
|
|
||||||
mmseekto(x,y)
|
|
||||||
return mm.read(bytepp)
|
|
||||||
|
|
||||||
def _888_to_565(bt):
|
def _888_to_565(bt):
|
||||||
b = b''
|
b = b''
|
||||||
for i in range(0, len(bt),3):
|
for i in range(0, len(bt), 3):
|
||||||
b += int.to_bytes(bt[i]>>3<<11|bt[i+1]>>2<<5|bt[i+2]>>3, 2, 'little')
|
b += int.to_bytes(bt[i] >> 3 << 11 | bt[i + 1] >> 2 << 5 | bt[i + 2] >> 3, 2, 'little')
|
||||||
return b
|
return b
|
||||||
|
|
||||||
|
|
||||||
def numpy_888_565(bt):
|
def numpy_888_565(bt):
|
||||||
import numpy as np
|
import numpy as np
|
||||||
arr = np.fromstring(bt, dtype=np.uint32)
|
arr = np.fromstring(bt, dtype=np.uint32)
|
||||||
return (((0xF80000 & arr)>>8)|((0xFC00 & arr)>>5)|((0xF8 & arr)>>3)).astype(np.uint16).tostring()
|
return (((0xF80000 & arr) >> 8) | ((0xFC00 & arr) >> 5) | ((0xF8 & arr) >> 3)).astype(np.uint16).tostring()
|
||||||
|
|
||||||
|
|
||||||
def show_img(img):
|
def show_img(img):
|
||||||
if not type(img) is bytes:
|
if not type(img) is bytes:
|
||||||
if not RGB:
|
if not RGB:
|
||||||
if bpp == 24: # for RPI
|
if bpp == 24: # for RPI
|
||||||
img = img.tobytes('raw', 'BGR')
|
img = img.tobytes('raw', 'BGR')
|
||||||
else:
|
else:
|
||||||
img = img.convert('RGBA').tobytes('raw', 'BGRA')
|
img = img.convert('RGBA').tobytes('raw', 'BGRA')
|
||||||
if bpp == 16:
|
if bpp == 16:
|
||||||
img = numpy_888_565(img)
|
img = numpy_888_565(img)
|
||||||
else:
|
else:
|
||||||
if bpp == 24:
|
if bpp == 24:
|
||||||
img = img.tobytes()
|
img = img.tobytes()
|
||||||
else:
|
else:
|
||||||
img = img.convert('RGBA').tobytes()
|
img = img.convert('RGBA').tobytes()
|
||||||
if bpp == 16:
|
if bpp == 16:
|
||||||
img = numpy_888_565(img)
|
img = numpy_888_565(img)
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
b = BytesIO(img)
|
b = BytesIO(img)
|
||||||
s = vw*bytepp
|
s = vw * bytepp
|
||||||
for y in range(vh): # virtual window drawing
|
for y in range(vh): # virtual window drawing
|
||||||
mmseekto(vx,vy+y)
|
mmseekto(vx, vy + y)
|
||||||
mm.write(b.read(s))
|
mm.write(b.read(s))
|
||||||
|
|
||||||
|
312
pwnagotchi/ui/hw/libs/i2coled/SSD1306.py
Normal file
312
pwnagotchi/ui/hw/libs/i2coled/SSD1306.py
Normal file
@ -0,0 +1,312 @@
|
|||||||
|
# Copyright (c) 2014 Adafruit Industries
|
||||||
|
# Author: Tony DiCola
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
# in the Software without restriction, including without limitation the rights
|
||||||
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
# copies of the Software, and to permit persons to whom the Software is
|
||||||
|
# furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
# THE SOFTWARE.
|
||||||
|
#
|
||||||
|
# SMBus parts coming from BLavery's lib_oled96 repo:
|
||||||
|
# https://github.com/BLavery/lib_oled96
|
||||||
|
#
|
||||||
|
# Modified for the Pwnagotchi project by RasTacsko
|
||||||
|
# Using SMBus, spidev RPi.GPIO for I2C communication instead of Adafruit libraries
|
||||||
|
# spidev maybe not necessary... needs some checking!!!
|
||||||
|
# ToDo:
|
||||||
|
# rotation support for vertical layouts
|
||||||
|
# checking luma oled library for support other chipsets/resolutions
|
||||||
|
|
||||||
|
from __future__ import division
|
||||||
|
import logging
|
||||||
|
import time
|
||||||
|
|
||||||
|
import RPi.GPIO as GPIO
|
||||||
|
# import spidev
|
||||||
|
from smbus import SMBus
|
||||||
|
i2cbus = SMBus(1)
|
||||||
|
|
||||||
|
|
||||||
|
# Constants
|
||||||
|
SSD1306_I2C_ADDRESS = 0x3C # 011110+SA0+RW - 0x3C or 0x3D
|
||||||
|
SSD1306_SETCONTRAST = 0x81
|
||||||
|
SSD1306_DISPLAYALLON_RESUME = 0xA4
|
||||||
|
SSD1306_DISPLAYALLON = 0xA5
|
||||||
|
SSD1306_NORMALDISPLAY = 0xA6
|
||||||
|
SSD1306_INVERTDISPLAY = 0xA7
|
||||||
|
SSD1306_DISPLAYOFF = 0xAE
|
||||||
|
SSD1306_DISPLAYON = 0xAF
|
||||||
|
SSD1306_SETDISPLAYOFFSET = 0xD3
|
||||||
|
SSD1306_SETCOMPINS = 0xDA
|
||||||
|
SSD1306_SETVCOMDETECT = 0xDB
|
||||||
|
SSD1306_SETDISPLAYCLOCKDIV = 0xD5
|
||||||
|
SSD1306_SETPRECHARGE = 0xD9
|
||||||
|
SSD1306_SETMULTIPLEX = 0xA8
|
||||||
|
SSD1306_SETLOWCOLUMN = 0x00
|
||||||
|
SSD1306_SETHIGHCOLUMN = 0x10
|
||||||
|
SSD1306_SETSTARTLINE = 0x40
|
||||||
|
SSD1306_MEMORYMODE = 0x20
|
||||||
|
SSD1306_COLUMNADDR = 0x21
|
||||||
|
SSD1306_PAGEADDR = 0x22
|
||||||
|
SSD1306_COMSCANINC = 0xC0
|
||||||
|
SSD1306_COMSCANDEC = 0xC8
|
||||||
|
SSD1306_SEGREMAP = 0xA0
|
||||||
|
SSD1306_CHARGEPUMP = 0x8D
|
||||||
|
SSD1306_EXTERNALVCC = 0x1
|
||||||
|
SSD1306_SWITCHCAPVCC = 0x2
|
||||||
|
|
||||||
|
# Scrolling constants
|
||||||
|
SSD1306_ACTIVATE_SCROLL = 0x2F
|
||||||
|
SSD1306_DEACTIVATE_SCROLL = 0x2E
|
||||||
|
SSD1306_SET_VERTICAL_SCROLL_AREA = 0xA3
|
||||||
|
SSD1306_RIGHT_HORIZONTAL_SCROLL = 0x26
|
||||||
|
SSD1306_LEFT_HORIZONTAL_SCROLL = 0x27
|
||||||
|
SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL = 0x29
|
||||||
|
SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL = 0x2A
|
||||||
|
|
||||||
|
|
||||||
|
class SSD1306Base(object):
|
||||||
|
"""Base class for SSD1306-based OLED displays. Implementors should subclass
|
||||||
|
and provide an implementation for the _initialize function.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, width, height, address=SSD1306_I2C_ADDRESS, bus=None):
|
||||||
|
self._log = logging.getLogger('Adafruit_SSD1306.SSD1306Base')
|
||||||
|
self.cmd_mode = 0x00
|
||||||
|
self.data_mode = 0x40
|
||||||
|
self.bus = i2cbus
|
||||||
|
self.addr = address
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
self._pages = height//8
|
||||||
|
self._buffer = [0]*(width*self._pages)
|
||||||
|
|
||||||
|
def _initialize(self):
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def command(self, *cmd):
|
||||||
|
"""Send command byte to display."""
|
||||||
|
# I2C write.
|
||||||
|
assert(len(cmd) <= 31)
|
||||||
|
try:
|
||||||
|
self.bus.write_i2c_block_data(self.addr, self.cmd_mode, list(cmd))
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(e)
|
||||||
|
|
||||||
|
def data(self, data):
|
||||||
|
"""Send byte of data to display."""
|
||||||
|
# I2C write.
|
||||||
|
try:
|
||||||
|
for i in range(0, len(data), 31):
|
||||||
|
self.bus.write_i2c_block_data(self.addr, self.data_mode, list(data[i:i+31]))
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(e)
|
||||||
|
|
||||||
|
def begin(self, vccstate=SSD1306_SWITCHCAPVCC):
|
||||||
|
"""Initialize display."""
|
||||||
|
# Save vcc state.
|
||||||
|
self._vccstate = vccstate
|
||||||
|
# Reset and initialize display.
|
||||||
|
self._initialize()
|
||||||
|
# Turn on the display.
|
||||||
|
self.command(SSD1306_DISPLAYON)
|
||||||
|
|
||||||
|
def ShowImage(self):
|
||||||
|
"""
|
||||||
|
The image on the "canvas" is flushed through to the hardware display.
|
||||||
|
Takes the 1-bit image and dumps it to the SSD1306 OLED display.
|
||||||
|
"""
|
||||||
|
self.command(SSD1306_COLUMNADDR)
|
||||||
|
self.command(0) # Column start address. (0 = reset)
|
||||||
|
self.command(self.width-1) # Column end address.
|
||||||
|
self.command(SSD1306_PAGEADDR)
|
||||||
|
self.command(0) # Page start address. (0 = reset)
|
||||||
|
self.command(self._pages-1) # Page end address.
|
||||||
|
try:
|
||||||
|
for i in range(0, len(self._buffer), 16):
|
||||||
|
self.bus.write_i2c_block_data(self.addr, self.data_mode, self._buffer[i:i+16])
|
||||||
|
except Exception as e:
|
||||||
|
logging.exception(e)
|
||||||
|
|
||||||
|
def getbuffer(self, image):
|
||||||
|
"""Set buffer to value of Python Imaging Library image. The image should
|
||||||
|
be in 1 bit mode and a size equal to the display size.
|
||||||
|
"""
|
||||||
|
if image.mode != '1':
|
||||||
|
raise ValueError('Image must be in mode 1.')
|
||||||
|
imwidth, imheight = image.size
|
||||||
|
if imwidth != self.width or imheight != self.height:
|
||||||
|
raise ValueError('Image must be same dimensions as display ({0}x{1}).' \
|
||||||
|
.format(self.width, self.height))
|
||||||
|
# Grab all the pixels from the image, faster than getpixel.
|
||||||
|
pix = image.load()
|
||||||
|
# Iterate through the memory pages
|
||||||
|
index = 0
|
||||||
|
for page in range(self._pages):
|
||||||
|
# Iterate through all x axis columns.
|
||||||
|
for x in range(self.width):
|
||||||
|
# Set the bits for the column of pixels at the current position.
|
||||||
|
bits = 0
|
||||||
|
# Don't use range here as it's a bit slow
|
||||||
|
for bit in [0, 1, 2, 3, 4, 5, 6, 7]:
|
||||||
|
bits = bits << 1
|
||||||
|
bits |= 0 if pix[(x, page*8+7-bit)] == 0 else 1
|
||||||
|
# Update buffer byte and increment to next byte.
|
||||||
|
self._buffer[index] = bits
|
||||||
|
index += 1
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
"""Clear contents of image buffer."""
|
||||||
|
self._buffer = [0]*(self.width*self._pages)
|
||||||
|
|
||||||
|
def set_contrast(self, contrast):
|
||||||
|
"""Sets the contrast of the display. Contrast should be a value between
|
||||||
|
0 and 255."""
|
||||||
|
if contrast < 0 or contrast > 255:
|
||||||
|
raise ValueError('Contrast must be a value from 0 to 255 (inclusive).')
|
||||||
|
self.command(SSD1306_SETCONTRAST)
|
||||||
|
self.command(contrast)
|
||||||
|
|
||||||
|
def dim(self, dim):
|
||||||
|
"""Adjusts contrast to dim the display if dim is True, otherwise sets the
|
||||||
|
contrast to normal brightness if dim is False.
|
||||||
|
"""
|
||||||
|
# Assume dim display.
|
||||||
|
contrast = 0
|
||||||
|
# Adjust contrast based on VCC if not dimming.
|
||||||
|
if not dim:
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
contrast = 0x9F
|
||||||
|
else:
|
||||||
|
contrast = 0xCF
|
||||||
|
self.set_contrast(contrast)
|
||||||
|
|
||||||
|
class SSD1306_128_64(SSD1306Base):
|
||||||
|
def __init__(self, width, height, address=None, bus=None):
|
||||||
|
# Call base class constructor.
|
||||||
|
super(SSD1306_128_64, self).__init__(128, 64, address, bus)
|
||||||
|
|
||||||
|
def _initialize(self):
|
||||||
|
# 128x64 pixel specific initialization.
|
||||||
|
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||||
|
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||||
|
self.command(0x80) # the suggested ratio 0x80
|
||||||
|
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||||
|
self.command(0x3F)
|
||||||
|
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||||
|
self.command(0x0) # no offset
|
||||||
|
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||||
|
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x10)
|
||||||
|
else:
|
||||||
|
self.command(0x14)
|
||||||
|
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||||
|
self.command(0x00) # 0x0 act like ks0108
|
||||||
|
self.command(SSD1306_SEGREMAP | 0x1)
|
||||||
|
self.command(SSD1306_COMSCANDEC)
|
||||||
|
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||||
|
self.command(0x12)
|
||||||
|
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x9F)
|
||||||
|
else:
|
||||||
|
self.command(0xCF)
|
||||||
|
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x22)
|
||||||
|
else:
|
||||||
|
self.command(0xF1)
|
||||||
|
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||||
|
self.command(0x40)
|
||||||
|
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||||
|
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||||
|
|
||||||
|
class SSD1306_128_32(SSD1306Base):
|
||||||
|
def __init__(self, width, height, address=None, bus=None):
|
||||||
|
# Call base class constructor.
|
||||||
|
super(SSD1306_128_32, self).__init__(128, 32, address, bus)
|
||||||
|
|
||||||
|
def _initialize(self):
|
||||||
|
# 128x32 pixel specific initialization.
|
||||||
|
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||||
|
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||||
|
self.command(0x80) # the suggested ratio 0x80
|
||||||
|
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||||
|
self.command(0x1F)
|
||||||
|
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||||
|
self.command(0x0) # no offset
|
||||||
|
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||||
|
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x10)
|
||||||
|
else:
|
||||||
|
self.command(0x14)
|
||||||
|
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||||
|
self.command(0x00) # 0x0 act like ks0108
|
||||||
|
self.command(SSD1306_SEGREMAP | 0x1)
|
||||||
|
self.command(SSD1306_COMSCANDEC)
|
||||||
|
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||||
|
self.command(0x02)
|
||||||
|
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||||
|
self.command(0x8F)
|
||||||
|
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x22)
|
||||||
|
else:
|
||||||
|
self.command(0xF1)
|
||||||
|
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||||
|
self.command(0x40)
|
||||||
|
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||||
|
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
||||||
|
|
||||||
|
|
||||||
|
class SSD1306_96_16(SSD1306Base):
|
||||||
|
def __init__(self, width, height, address=None, bus=None):
|
||||||
|
# Call base class constructor.
|
||||||
|
super(SSD1306_96_16, self).__init__(96, 16, address, bus)
|
||||||
|
|
||||||
|
def _initialize(self):
|
||||||
|
# 128x32 pixel specific initialization.
|
||||||
|
self.command(SSD1306_DISPLAYOFF) # 0xAE
|
||||||
|
self.command(SSD1306_SETDISPLAYCLOCKDIV) # 0xD5
|
||||||
|
self.command(0x60) # the suggested ratio 0x60
|
||||||
|
self.command(SSD1306_SETMULTIPLEX) # 0xA8
|
||||||
|
self.command(0x0F)
|
||||||
|
self.command(SSD1306_SETDISPLAYOFFSET) # 0xD3
|
||||||
|
self.command(0x0) # no offset
|
||||||
|
self.command(SSD1306_SETSTARTLINE | 0x0) # line #0
|
||||||
|
self.command(SSD1306_CHARGEPUMP) # 0x8D
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x10)
|
||||||
|
else:
|
||||||
|
self.command(0x14)
|
||||||
|
self.command(SSD1306_MEMORYMODE) # 0x20
|
||||||
|
self.command(0x00) # 0x0 act like ks0108
|
||||||
|
self.command(SSD1306_SEGREMAP | 0x1)
|
||||||
|
self.command(SSD1306_COMSCANDEC)
|
||||||
|
self.command(SSD1306_SETCOMPINS) # 0xDA
|
||||||
|
self.command(0x02)
|
||||||
|
self.command(SSD1306_SETCONTRAST) # 0x81
|
||||||
|
self.command(0x8F)
|
||||||
|
self.command(SSD1306_SETPRECHARGE) # 0xd9
|
||||||
|
if self._vccstate == SSD1306_EXTERNALVCC:
|
||||||
|
self.command(0x22)
|
||||||
|
else:
|
||||||
|
self.command(0xF1)
|
||||||
|
self.command(SSD1306_SETVCOMDETECT) # 0xDB
|
||||||
|
self.command(0x40)
|
||||||
|
self.command(SSD1306_DISPLAYALLON_RESUME) # 0xA4
|
||||||
|
self.command(SSD1306_NORMALDISPLAY) # 0xA6
|
34
pwnagotchi/ui/hw/libs/i2coled/epd.py
Normal file
34
pwnagotchi/ui/hw/libs/i2coled/epd.py
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
from . import SSD1306
|
||||||
|
|
||||||
|
# Display resolution, change if the screen resolution is changed!
|
||||||
|
EPD_WIDTH = 128
|
||||||
|
EPD_HEIGHT = 64
|
||||||
|
|
||||||
|
# Available screen resolutions:
|
||||||
|
# disp = SSD1306.SSD1306_128_32(128, 32, address=0x3C)
|
||||||
|
# disp = SSD1306.SSD1306_96_16(96, 16, address=0x3C)
|
||||||
|
# If you change for different resolution, you have to modify the layout in pwnagotchi/ui/hw/i2coled.py
|
||||||
|
|
||||||
|
class EPD(object):
|
||||||
|
|
||||||
|
def __init__(self, address=0x3D, width=EPD_WIDTH, height=EPD_HEIGHT):
|
||||||
|
self.width = width
|
||||||
|
self.height = height
|
||||||
|
|
||||||
|
# choose subclass based on dimensions
|
||||||
|
if height == 32:
|
||||||
|
self.disp = SSD1306.SSD1306_128_32(width, height, address)
|
||||||
|
elif height == 16:
|
||||||
|
self.disp = SSD1306.SSD1306_96_16(width, height, address)
|
||||||
|
else:
|
||||||
|
self.disp = SSD1306.SSD1306_128_64(width, height, address)
|
||||||
|
|
||||||
|
def Init(self):
|
||||||
|
self.disp.begin()
|
||||||
|
|
||||||
|
def Clear(self):
|
||||||
|
self.disp.clear()
|
||||||
|
|
||||||
|
def display(self, image):
|
||||||
|
self.disp.getbuffer(image)
|
||||||
|
self.disp.ShowImage()
|
@ -31,7 +31,6 @@ import os
|
|||||||
import logging
|
import logging
|
||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
import subprocess
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -113,6 +112,7 @@ class RaspberryPi:
|
|||||||
|
|
||||||
self.GPIO_RST_PIN.off()
|
self.GPIO_RST_PIN.off()
|
||||||
self.GPIO_DC_PIN.off()
|
self.GPIO_DC_PIN.off()
|
||||||
|
self.GPIO_CS_PIN.off()
|
||||||
self.GPIO_PWR_PIN.off()
|
self.GPIO_PWR_PIN.off()
|
||||||
logger.debug("close 5V, Module enters 0 power consumption ...")
|
logger.debug("close 5V, Module enters 0 power consumption ...")
|
||||||
|
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 960
|
EPD_WIDTH = 960
|
@ -29,7 +29,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 80
|
EPD_WIDTH = 80
|
@ -80,7 +80,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 200
|
EPD_WIDTH = 200
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 200
|
EPD_WIDTH = 200
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 200
|
EPD_WIDTH = 200
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 200
|
EPD_WIDTH = 200
|
@ -27,7 +27,7 @@
|
|||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
#
|
#
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 152
|
EPD_WIDTH = 152
|
@ -29,11 +29,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
import PIL
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 168
|
EPD_WIDTH = 168
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -27,7 +27,7 @@
|
|||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
#
|
#
|
||||||
|
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
import RPi.GPIO as GPIO
|
import RPi.GPIO as GPIO
|
||||||
# import numpy as np
|
# import numpy as np
|
||||||
|
|
@ -40,9 +40,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 104
|
EPD_WIDTH = 104
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 104
|
EPD_WIDTH = 104
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
@ -29,9 +29,8 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import RPi.GPIO as GPIO
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 104
|
EPD_WIDTH = 104
|
@ -29,11 +29,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
import PIL
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -29,11 +29,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
import PIL
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 122
|
EPD_WIDTH = 122
|
@ -29,11 +29,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
import PIL
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 168
|
EPD_WIDTH = 168
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 152
|
EPD_WIDTH = 152
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 152
|
EPD_WIDTH = 152
|
@ -29,11 +29,9 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
import PIL
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
import io
|
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 184
|
EPD_WIDTH = 184
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 176
|
EPD_WIDTH = 176
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 176
|
EPD_WIDTH = 176
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 176
|
EPD_WIDTH = 176
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 176
|
EPD_WIDTH = 176
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 128
|
EPD_WIDTH = 128
|
@ -28,7 +28,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 128
|
EPD_WIDTH = 128
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 128
|
EPD_WIDTH = 128
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
from .. import epdconfig
|
from pwnagotchi.ui.hw.libs.waveshare.epaper import epdconfig
|
||||||
|
|
||||||
# Display resolution
|
# Display resolution
|
||||||
EPD_WIDTH = 128
|
EPD_WIDTH = 128
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user