mirror of
https://github.com/jayofelony/pwnagotchi.git
synced 2025-07-01 18:37:27 -04:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
cca3e77d50 | |||
4fe603bf5e | |||
9a9ee70a78 | |||
7fc8838f76 | |||
94b2ff7047 | |||
8edb0fdaa4 | |||
b557768159 | |||
5a6967eb4d | |||
c0c35231cf | |||
88362b3354 | |||
e50cf04967 | |||
85a64a3914 | |||
63d0c20a3e | |||
044639a6d4 | |||
7fc2c6b25f | |||
c5d5d9bb14 | |||
129ae92447 | |||
2560692ee2 | |||
1424e0d510 | |||
2c9eaa436a | |||
0c5c6058a5 | |||
a3fb39d78c | |||
bac62bc4aa | |||
f7a5f2a554 | |||
6921fd14a3 | |||
0dbd611ed5 | |||
18b9093f70 | |||
26913016b9 | |||
0786b6757e | |||
0f4eda8039 |
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@ -4,4 +4,7 @@
|
||||
<option name="sdkName" value="Python 3.11 (pwnagotchi)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (pwnagotchi-torch-bookworm)" project-jdk-type="Python SDK" />
|
||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
@ -11,7 +11,7 @@ Select ‘Credentials’ from the left menu, click ‘Create Credentials’, sel
|
||||
|
||||
Now, the product name and consent screen need to be set -> click ‘Configure consent screen’ and follow the instructions. Once finished:
|
||||
|
||||
Select ‘Application type’ to be Desktop application.
|
||||
Select ‘Application type’ to be Web application.
|
||||
|
||||
Enter an appropriate name.
|
||||
|
||||
@ -19,7 +19,7 @@ Input http://localhost/ for ‘Authorized redirect URIs’.
|
||||
|
||||
Select the correct oauth scope:
|
||||
|
||||
- drive
|
||||
- drive.file
|
||||
- drive.install
|
||||
|
||||
Click ‘Create’.
|
||||
|
@ -7,7 +7,7 @@ It seems the Pi 5 is unable to run in monitor mode, will keep you updated on thi
|
||||
If you are using an older 32-bit version Raspberry Pi, ZeroWH, use this [fork](https://github.com/jayofelony/pwnagotchi-torch/releases/tag/v2.6.4) and make sure you download the `armhf` version.
|
||||
|
||||
---
|
||||
Download latest image file [here](https://github.com/jayofelony/pwnagotchi-bookworm/releases/tag/v2.6.7), and let it auto-update from here on out.
|
||||
Download latest image file [here](https://github.com/jayofelony/pwnagotchi-bookworm/releases/tag/v2.7.3), and let it auto-update from here on out.
|
||||
|
||||
**Use RPi imager to flash, please don't flash a new user as this will mess with logs created.**
|
||||
|
||||
|
@ -157,7 +157,7 @@ def pwnagotchi_cli():
|
||||
sys.exit(0)
|
||||
|
||||
if args.donate:
|
||||
print("Donations can made @ https://www.patreon.com/pwnagotchi_torch \n\nBut only if you really want to!")
|
||||
print("Donations can made @ https://github.com/sponsors/jayofelony \n\nBut only if you really want to!")
|
||||
sys.exit(0)
|
||||
|
||||
if args.check_update:
|
||||
|
15
builder/data/etc/default/zramswap
Normal file
15
builder/data/etc/default/zramswap
Normal file
@ -0,0 +1,15 @@
|
||||
# Specifies amount of zram devices to create.
|
||||
# By default, zramswap-start will use all available cores.
|
||||
#CORES=1
|
||||
|
||||
# Specifies the amount of RAM that should be used for zram
|
||||
# based on a percentage the total amount of available memory
|
||||
PERCENTAGE=60
|
||||
|
||||
# Specifies a static amount of RAM that should be used for
|
||||
# the ZRAM devices, this is in MiB
|
||||
#ALLOCATION=256
|
||||
|
||||
# Specifies the priority for the swap devices, see swapon(2)
|
||||
# for more details.
|
||||
#PRIORITY=100
|
@ -1,26 +0,0 @@
|
||||
# /etc/dphys-swapfile - user settings for dphys-swapfile package
|
||||
# author Neil Franklin, last modification 2010.05.05
|
||||
# copyright ETH Zuerich Physics Departement
|
||||
# use under either modified/non-advertising BSD or GPL license
|
||||
|
||||
# this file is sourced with . so full normal sh syntax applies
|
||||
|
||||
# the default settings are added as commented out CONF_*=* lines
|
||||
|
||||
|
||||
# where we want the swapfile to be, this is the default
|
||||
#CONF_SWAPFILE=/var/swap
|
||||
|
||||
# set size to absolute value, leaving empty (default) then uses computed value
|
||||
# you most likely don't want this, unless you have an special disk situation
|
||||
CONF_SWAPSIZE=2048
|
||||
|
||||
# set size to computed value, this times RAM size, dynamically adapts,
|
||||
# guarantees that there is enough swap without wasting disk space on excess
|
||||
#CONF_SWAPFACTOR=2
|
||||
|
||||
# restrict size (computed and absolute!) to maximally this limit
|
||||
# can be set to empty for no limit, but beware of filled partitions!
|
||||
# this is/was a (outdated?) 32bit kernel limit (in MBytes), do not overrun it
|
||||
# but is also sensible on 64bit to prevent filling /var or even / partition
|
||||
#CONF_MAXSWAP=2048
|
@ -39,8 +39,10 @@ reload_brcm() {
|
||||
start_monitor_interface() {
|
||||
rfkill unblock all
|
||||
ifconfig wlan0 up
|
||||
sleep 3
|
||||
iw dev wlan0 set power_save off
|
||||
iw phy "$(iw phy | head -1 | cut -d" " -f2)" interface add wlan0mon type monitor
|
||||
sleep 2
|
||||
rfkill unblock all
|
||||
ifconfig wlan0 down
|
||||
ifconfig wlan0mon up
|
||||
@ -54,7 +56,7 @@ stop_monitor_interface() {
|
||||
ifconfig wlan0 up
|
||||
}
|
||||
|
||||
# returns 0 if the specificed network interface is up
|
||||
# returns 0 if the specified network interface is up
|
||||
is_interface_up() {
|
||||
if grep -qi 'up' /sys/class/net/"$1"/operstate; then
|
||||
return 0
|
||||
|
@ -23,21 +23,17 @@
|
||||
services:
|
||||
enable:
|
||||
- bettercap.service
|
||||
- dphys-swapfile.service
|
||||
- fstrim.timer
|
||||
- pwnagotchi.service
|
||||
- pwngrid-peer.service
|
||||
- zramswap.service
|
||||
disable:
|
||||
- apt-daily-upgrade.service
|
||||
- apt-daily-upgrade.timer
|
||||
- apt-daily.service
|
||||
- apt-daily.timer
|
||||
- avahi-daemon.service
|
||||
- avahi-daemon.socket
|
||||
- bluetooth.service
|
||||
- ifup@wlan0.service
|
||||
- triggerhappy.service
|
||||
- wpa_supplicant.service
|
||||
packages:
|
||||
caplets:
|
||||
source: "https://github.com/jayofelony/caplets.git"
|
||||
@ -61,6 +57,7 @@
|
||||
- libpcap0.8-dbg
|
||||
remove:
|
||||
- avahi-daemon
|
||||
- dhpys-swapfile
|
||||
- nfs-common
|
||||
- triggerhappy
|
||||
- wpasupplicant
|
||||
@ -73,7 +70,6 @@
|
||||
- build-essential
|
||||
- curl
|
||||
- dkms
|
||||
- dphys-swapfile
|
||||
- fbi
|
||||
- flex
|
||||
- fonts-dejavu
|
||||
@ -161,17 +157,62 @@
|
||||
- wl
|
||||
- xxd
|
||||
- zlib1g-dev
|
||||
- zram-tools
|
||||
environment:
|
||||
ARCHFLAGS: "-arch aarch64"
|
||||
QEMU_UNAME: "{{ kernel.full }}"
|
||||
|
||||
tasks:
|
||||
# First we install and remove unnecessary packages
|
||||
- name: install packages
|
||||
apt:
|
||||
name: "{{ packages.apt.install }}"
|
||||
state: present
|
||||
update_cache: yes
|
||||
install_recommends: false
|
||||
|
||||
- name: remove unnecessary apt packages
|
||||
apt:
|
||||
name: "{{ packages.apt.remove }}"
|
||||
state: absent
|
||||
purge: yes
|
||||
register: removed
|
||||
|
||||
# Now we set up /boot/firmware
|
||||
- name: Create pi user
|
||||
copy:
|
||||
dest: /boot/firmware/userconf
|
||||
content: |
|
||||
pi:$6$3jNr0GA9KIyt4hmM$efeVIopdMQ8DGgEPCWWlbx3mJJNAYci1lEXGdlky0xPyjqwKNbwTL5SrCcpb4144C4IvzWjn7Iv.QjqmU7iyT/
|
||||
|
||||
- name: enable ssh on boot
|
||||
file:
|
||||
path: /boot/firmware/ssh
|
||||
state: touch
|
||||
|
||||
- name: adjust /boot/firmware/config.txt
|
||||
lineinfile:
|
||||
dest: /boot/firmware/config.txt
|
||||
insertafter: EOF
|
||||
line: '{{ item }}'
|
||||
with_items: "{{ system.boot_options }}"
|
||||
|
||||
- name: change root partition
|
||||
replace:
|
||||
dest: /boot/firmware/cmdline.txt
|
||||
backup: no
|
||||
regexp: "root=PARTUUID=[a-zA-Z0-9\\-]+"
|
||||
replace: "root=/dev/mmcblk0p2"
|
||||
|
||||
- name: configure /boot/firmware/cmdline.txt
|
||||
lineinfile:
|
||||
path: /boot/firmware/cmdline.txt
|
||||
backrefs: True
|
||||
state: present
|
||||
backup: no
|
||||
regexp: '(.*)$'
|
||||
line: '\1 modules-load=dwc2,g_ether'
|
||||
|
||||
- name: change hostname
|
||||
lineinfile:
|
||||
dest: /etc/hostname
|
||||
@ -189,6 +230,7 @@
|
||||
state: present
|
||||
when: hostname.changed
|
||||
|
||||
# Now we disable sap and a2dp, we don't use them on rpi
|
||||
- name: disable sap plugin for bluetooth.service
|
||||
lineinfile:
|
||||
dest: /lib/systemd/system/bluetooth.service
|
||||
@ -196,19 +238,6 @@
|
||||
line: 'ExecStart=/usr/libexec/bluetooth/bluetoothd --noplugin=sap,a2dp'
|
||||
state: present
|
||||
|
||||
- name: configure dphys-swapfile
|
||||
lineinfile:
|
||||
path: /etc/dphys-swapfile
|
||||
regexp: "^CONF_SWAPSIZE=.*$"
|
||||
line: "CONF_SWAPSIZE=2048"
|
||||
|
||||
- name: install packages
|
||||
apt:
|
||||
name: "{{ packages.apt.install }}"
|
||||
state: present
|
||||
update_cache: yes
|
||||
install_recommends: false
|
||||
|
||||
###########################################
|
||||
#
|
||||
# libpcap v1.9 - build from source
|
||||
@ -477,41 +506,6 @@
|
||||
state: absent
|
||||
path: /etc/update-motd.d/10-uname
|
||||
|
||||
- name: enable ssh on boot
|
||||
file:
|
||||
path: /boot/firmware/ssh
|
||||
state: touch
|
||||
|
||||
- name: adjust /boot/config.txt
|
||||
lineinfile:
|
||||
dest: /boot/firmware/config.txt
|
||||
insertafter: EOF
|
||||
line: '{{ item }}'
|
||||
with_items: "{{ system.boot_options }}"
|
||||
|
||||
- name: adjust /etc/modules
|
||||
lineinfile:
|
||||
dest: /etc/modules
|
||||
insertafter: EOF
|
||||
line: '{{ item }}'
|
||||
with_items: "{{ system.modules }}"
|
||||
|
||||
- name: change root partition
|
||||
replace:
|
||||
dest: /boot/firmware/cmdline.txt
|
||||
backup: no
|
||||
regexp: "root=PARTUUID=[a-zA-Z0-9\\-]+"
|
||||
replace: "root=/dev/mmcblk0p2"
|
||||
|
||||
- name: configure /boot/cmdline.txt
|
||||
lineinfile:
|
||||
path: /boot/cmdline.txt
|
||||
backrefs: True
|
||||
state: present
|
||||
backup: no
|
||||
regexp: '(.*)$'
|
||||
line: '\1 modules-load=dwc2,g_ether'
|
||||
|
||||
- name: Add pwnlog alias
|
||||
lineinfile:
|
||||
dest: /home/pi/.bashrc
|
||||
@ -563,13 +557,6 @@
|
||||
group: pi
|
||||
recurse: true
|
||||
|
||||
- name: remove unnecessary apt packages
|
||||
apt:
|
||||
name: "{{ packages.apt.remove }}"
|
||||
state: absent
|
||||
purge: yes
|
||||
register: removed
|
||||
|
||||
- name: clean apt cache
|
||||
apt:
|
||||
autoclean: true
|
||||
|
@ -1 +1 @@
|
||||
__version__ = '2.7.1'
|
||||
__version__ = '2.7.6'
|
||||
|
@ -59,7 +59,8 @@ def load(config, agent, epoch, from_disk=True):
|
||||
|
||||
return a2c
|
||||
except Exception as e:
|
||||
logging.exception("[AI] error while starting AI (%s)", e)
|
||||
logging.info("[AI] Error while starting AI")
|
||||
logging.debug("[AI] error while starting AI (%s)", e)
|
||||
logging.info("[AI] Deleting brain and restarting.")
|
||||
os.system("rm /root/brain.nn && service pwnagotchi restart")
|
||||
|
||||
|
@ -212,7 +212,7 @@ class AutoUpdate(plugins.Plugin):
|
||||
if install(display, update):
|
||||
num_installed += 1
|
||||
else:
|
||||
prev_status = '%d new update%c available!' % (num_updates, 's' if num_updates > 1 else '')
|
||||
prev_status = '%d new update%s available!' % (num_updates, 's' if num_updates > 1 else '')
|
||||
|
||||
logging.info("[update] done")
|
||||
|
||||
|
@ -21,9 +21,6 @@ class FixServices(plugins.Plugin):
|
||||
__help__ = """
|
||||
Reload brcmfmac module when blindbug is detected, instead of rebooting. Adapted from WATCHDOG.
|
||||
"""
|
||||
__dependencies__ = {
|
||||
'pip': ['scapy']
|
||||
}
|
||||
__defaults__ = {
|
||||
'enabled': True,
|
||||
}
|
||||
@ -46,8 +43,7 @@ class FixServices(plugins.Plugin):
|
||||
logging.info("[Fix_Services] plugin loaded.")
|
||||
|
||||
def on_ready(self, agent):
|
||||
last_lines = ''.join(list(TextIOWrapper(subprocess.Popen(['journalctl', '-n10', '-k'],
|
||||
stdout=subprocess.PIPE).stdout))[-10:])
|
||||
last_lines = self.get_last_lines('journalctl', ['-n10', '-k'], 10)
|
||||
try:
|
||||
cmd_output = subprocess.check_output("ip link show wlan0mon", shell=True)
|
||||
logging.info("[Fix_Services ip link show wlan0mon]: %s" % repr(cmd_output))
|
||||
@ -99,14 +95,23 @@ class FixServices(plugins.Plugin):
|
||||
logging.error("[Fix_Services]SYSLOG wifi.recon flip fail: %s" % err)
|
||||
self._tryTurningItOffAndOnAgain(agent)
|
||||
|
||||
def get_last_lines(self, command, args, n):
|
||||
try:
|
||||
process = subprocess.Popen([command] + args, stdout=subprocess.PIPE)
|
||||
output = TextIOWrapper(process.stdout)
|
||||
lines = output.readlines()
|
||||
last_n_lines = ''.join(lines[-n:])
|
||||
return last_n_lines
|
||||
except Exception as e:
|
||||
print(f"Error occurred: {e}")
|
||||
return None
|
||||
|
||||
def on_epoch(self, agent, epoch, epoch_data):
|
||||
last_lines = ''.join(list(TextIOWrapper(subprocess.Popen(['journalctl', '-n10', '-k'],
|
||||
stdout=subprocess.PIPE).stdout))[-10:])
|
||||
other_last_lines = ''.join(list(TextIOWrapper(subprocess.Popen(['journalctl', '-n10'],
|
||||
stdout=subprocess.PIPE).stdout))[-10:])
|
||||
other_other_last_lines = ''.join(
|
||||
list(TextIOWrapper(subprocess.Popen(['tail', '-n10', '/home/pi/logs/pwnagotchi.log'],
|
||||
stdout=subprocess.PIPE).stdout))[-10:])
|
||||
|
||||
last_lines = self.get_last_lines('journalctl', ['-n10', '-k'], 10)
|
||||
other_last_lines = self.get_last_lines('journalctl', ['-n10'], 10)
|
||||
other_other_last_lines = self.get_last_lines('tail', ['-n10', '/home/pi/logs/pwnagotchi.log'], 10)
|
||||
|
||||
# don't check if we ran a reset recently
|
||||
logging.debug("[Fix_Services]**** epoch")
|
||||
if time.time() - self.LASTTRY > 180:
|
||||
|
@ -14,19 +14,15 @@ import zipfile
|
||||
|
||||
class GdriveSync(plugins.Plugin):
|
||||
__author__ = '@jayofelony'
|
||||
__version__ = '1.0'
|
||||
__version__ = '1.2'
|
||||
__license__ = 'GPL3'
|
||||
__description__ = 'A plugin to backup various pwnagotchi files and folders to Google Drive. Once every hour from loading plugin.'
|
||||
__dependencies__ = {
|
||||
'pip': ['pydrive2']
|
||||
}
|
||||
|
||||
def __init__(self):
|
||||
self.options = dict()
|
||||
self.lock = Lock()
|
||||
self.internet = False
|
||||
self.ready = False
|
||||
self.drive = None
|
||||
self.status = StatusFile('/root/.gdrive-backup')
|
||||
self.backup = True
|
||||
self.backupfiles = [
|
||||
@ -38,12 +34,11 @@ class GdriveSync(plugins.Plugin):
|
||||
'/etc/pwnagotchi'
|
||||
]
|
||||
|
||||
def on_loaded(self, agent):
|
||||
def on_loaded(self):
|
||||
"""
|
||||
Called when the plugin is loaded
|
||||
"""
|
||||
# client_secrets.json needs to be not empty
|
||||
display = agent.view()
|
||||
if os.stat("/root/client_secrets.json").st_size == 0:
|
||||
logging.error("[gDriveSync] /root/client_secrets.json is empty. Please RTFM!")
|
||||
return
|
||||
@ -78,25 +73,24 @@ class GdriveSync(plugins.Plugin):
|
||||
# logging.warning(f"[gDriveSync] No files found in the folder with ID {root_file_list} and {pwnagotchi_file_list}")
|
||||
if self.options['backupfiles'] is not None:
|
||||
self.backupfiles = self.backupfiles + self.options['backupfiles']
|
||||
self.backup_files(self.backupfiles, '/backup')
|
||||
self.backup_files(self.backupfiles, '/home/pi/backup')
|
||||
|
||||
# Create a zip archive of the /backup folder
|
||||
zip_file_path = os.path.join('/home/pi', 'backup.zip')
|
||||
with zipfile.ZipFile(zip_file_path, 'w') as zip_ref:
|
||||
for root, dirs, files in os.walk('/backup'):
|
||||
for root, dirs, files in os.walk('/home/pi/backup'):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
arcname = os.path.relpath(file_path, '/backup')
|
||||
arcname = os.path.relpath(file_path, '/home/pi/backup')
|
||||
zip_ref.write(file_path, arcname=arcname)
|
||||
|
||||
# Upload the zip archive to Google Drive
|
||||
self.upload_to_gdrive(zip_file_path, self.get_folder_id_by_name(self.drive, self.options['backup_folder']))
|
||||
display.on_uploading("Google Drive")
|
||||
self.backup = True
|
||||
self.status.update()
|
||||
|
||||
# Specify the local backup path
|
||||
local_backup_path = '/'
|
||||
local_backup_path = '/home/pi/'
|
||||
|
||||
# Download the zip archive from Google Drive
|
||||
zip_file_id = self.get_latest_backup_file_id(self.options['backup_folder'])
|
||||
@ -104,7 +98,6 @@ class GdriveSync(plugins.Plugin):
|
||||
zip_file = self.drive.CreateFile({'id': zip_file_id})
|
||||
zip_file.GetContentFile(os.path.join(local_backup_path, 'backup.zip'))
|
||||
|
||||
display.on_downloading("Google Drive")
|
||||
logging.info("[gDriveSync] Downloaded backup.zip from Google Drive")
|
||||
|
||||
# Extract the zip archive to the root directory
|
||||
@ -112,9 +105,12 @@ class GdriveSync(plugins.Plugin):
|
||||
zip_ref.extractall('/')
|
||||
|
||||
self.status.update()
|
||||
os.remove("/backup")
|
||||
# Reboot so we can start opwngrid with the backup id
|
||||
pwnagotchi.reboot()
|
||||
shutil.rmtree("/home/pi/backup")
|
||||
os.remove("/home/pi/backup.zip")
|
||||
self.ready = True
|
||||
logging.info("[gdrivesync] loaded")
|
||||
# Restart so we can start opwngrid with the backup id
|
||||
pwnagotchi.restart("AUTO")
|
||||
|
||||
# all set, gdriveSync is ready to run
|
||||
self.ready = True
|
||||
@ -186,15 +182,15 @@ class GdriveSync(plugins.Plugin):
|
||||
logging.info("[gdrivesync] new handshake captured, backing up to gdrive")
|
||||
if self.options['backupfiles'] is not None:
|
||||
self.backupfiles = self.backupfiles + self.options['backupfiles']
|
||||
self.backup_files(self.backupfiles, '/backup')
|
||||
self.backup_files(self.backupfiles, '/home/pi/backup')
|
||||
|
||||
# Create a zip archive of the /backup folder
|
||||
zip_file_path = os.path.join('/home/pi', 'backup.zip')
|
||||
with zipfile.ZipFile(zip_file_path, 'w') as zip_ref:
|
||||
for root, dirs, files in os.walk('/backup'):
|
||||
for root, dirs, files in os.walk('/home/pi/backup'):
|
||||
for file in files:
|
||||
file_path = os.path.join(root, file)
|
||||
arcname = os.path.relpath(file_path, '/backup')
|
||||
arcname = os.path.relpath(file_path, '/home/pi/backup')
|
||||
zip_ref.write(file_path, arcname=arcname)
|
||||
|
||||
# Upload the zip archive to Google Drive
|
||||
@ -203,7 +199,7 @@ class GdriveSync(plugins.Plugin):
|
||||
|
||||
# Cleanup the local zip file
|
||||
os.remove(zip_file_path)
|
||||
os.remove("/backup")
|
||||
shutil.rmtree("/home/pi/backup")
|
||||
self.status.update()
|
||||
display = agent.view()
|
||||
display.update(force=True, new_data={'Backing up to gdrive ...'})
|
||||
|
@ -24,6 +24,7 @@ class NetPos(plugins.Plugin):
|
||||
self.skip = list()
|
||||
self.ready = False
|
||||
self.lock = threading.Lock()
|
||||
self.options = dict()
|
||||
|
||||
def on_loaded(self):
|
||||
if 'api_key' not in self.options or ('api_key' in self.options and not self.options['api_key']):
|
||||
@ -116,6 +117,7 @@ class NetPos(plugins.Plugin):
|
||||
except OSError as os_e:
|
||||
logging.error("NET-POS: %s", os_e)
|
||||
|
||||
|
||||
def _get_netpos(self, agent):
|
||||
aps = agent.get_access_points()
|
||||
netpos = dict()
|
||||
|
@ -1,14 +1,20 @@
|
||||
# Based on UPS Lite v1.1 from https://github.com/xenDE
|
||||
# Made specifically to address the problems caused by the hardware changes in 1.3. Oh yeah I also removed the auto-shutdown feature because it's kind of broken.
|
||||
#
|
||||
# functions for get UPS status - needs enable "i2c" in raspi-config
|
||||
# To setup, see page six of this manual to see how to enable i2c:
|
||||
# https://github.com/linshuqin329/UPS-Lite/blob/master/UPS-Lite_V1.3_CW2015/Instructions%20for%20UPS-Lite%20V1.3.pdf
|
||||
#
|
||||
# https://github.com/linshuqin329/UPS-Lite
|
||||
# Follow page seven, install the dependencies (python-smbus) and copy this script over for later use:
|
||||
# https://github.com/linshuqin329/UPS-Lite/blob/master/UPS-Lite_V1.3_CW2015/UPS_Lite_V1.3_CW2015.py
|
||||
#
|
||||
# For Raspberry Pi Zero Ups Power Expansion Board with Integrated Serial Port S3U4
|
||||
# https://www.ebay.de/itm/For-Raspberry-Pi-Zero-Ups-Power-Expansion-Board-with-Integrated-Serial-Port-S3U4/323873804310
|
||||
# https://www.aliexpress.com/item/32888533624.html
|
||||
# Now, install this plugin by copying this to the 'available-plugins' folder in your pwnagotchi, install and enable the plugin with the commands:
|
||||
# sudo pwnagotchi plugins install upslite_plugin_1_3
|
||||
# sudo pwnagotchi plugins enable upslite_plugin_1_3
|
||||
#
|
||||
# To display external power supply status you need to bridge the necessary pins on the UPS-Lite board. See instructions in the UPS-Lite repo.
|
||||
# Now restart raspberry pi. Once back up ensure upslite_plugin_1_3 plugin is turned on in the WebUI. If there is still '0%' on your battery meter
|
||||
# run the script we saved earlier and ensure that the pwnagotchi is plugged in both at the battery and the raspberry pi. The script should start trying to
|
||||
# read the battery, and should be successful once there's a USB cable running power to the battery supply.
|
||||
|
||||
import logging
|
||||
import struct
|
||||
|
||||
@ -20,6 +26,11 @@ import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.components import LabeledValue
|
||||
from pwnagotchi.ui.view import BLACK
|
||||
|
||||
CW2015_ADDRESS = 0X62
|
||||
CW2015_REG_VCELL = 0X02
|
||||
CW2015_REG_SOC = 0X04
|
||||
CW2015_REG_MODE = 0X0A
|
||||
|
||||
|
||||
# TODO: add enable switch in config.yml an cleanup all to the best place
|
||||
class UPS:
|
||||
@ -31,8 +42,7 @@ class UPS:
|
||||
|
||||
def voltage(self):
|
||||
try:
|
||||
address = 0x36
|
||||
read = self._bus.read_word_data(address, 2)
|
||||
read = self._bus.read_word_data(CW2015_ADDRESS, CW2015_REG_VCELL)
|
||||
swapped = struct.unpack("<H", struct.pack(">H", read))[0]
|
||||
return swapped * 1.25 / 1000 / 16
|
||||
except:
|
||||
@ -41,7 +51,7 @@ class UPS:
|
||||
def capacity(self):
|
||||
try:
|
||||
address = 0x36
|
||||
read = self._bus.read_word_data(address, 4)
|
||||
read = self._bus.read_word_data(CW2015_ADDRESS, CW2015_REG_SOC)
|
||||
swapped = struct.unpack("<H", struct.pack(">H", read))[0]
|
||||
return swapped / 256
|
||||
except:
|
||||
@ -57,10 +67,10 @@ class UPS:
|
||||
|
||||
|
||||
class UPSLite(plugins.Plugin):
|
||||
__author__ = 'evilsocket@gmail.com'
|
||||
__version__ = '1.0.0'
|
||||
__author__ = 'marbasec'
|
||||
__version__ = '1.3.0'
|
||||
__license__ = 'GPL3'
|
||||
__description__ = 'A plugin that will add a voltage indicator for the UPS Lite v1.1'
|
||||
__description__ = 'A plugin that will add a voltage indicator for the UPS Lite v1.3'
|
||||
|
||||
def __init__(self):
|
||||
self.ups = None
|
||||
@ -69,7 +79,7 @@ class UPSLite(plugins.Plugin):
|
||||
self.ups = UPS()
|
||||
|
||||
def on_ui_setup(self, ui):
|
||||
ui.add_element('ups', LabeledValue(color=BLACK, label='UPS', value='0%/0V', position=(ui.width() / 2 + 15, 0),
|
||||
ui.add_element('ups', LabeledValue(color=BLACK, label='UPS', value='0%', position=(ui.width() / 2 + 15, 0),
|
||||
label_font=fonts.Bold, text_font=fonts.Medium))
|
||||
|
||||
def on_unload(self, ui):
|
||||
@ -80,7 +90,3 @@ class UPSLite(plugins.Plugin):
|
||||
capacity = self.ups.capacity()
|
||||
charging = self.ups.charging()
|
||||
ui.set('ups', "%2i%s" % (capacity, charging))
|
||||
if capacity <= self.options['shutdown']:
|
||||
logging.info('[ups_lite] Empty battery (<= %s%%): shuting down' % self.options['shutdown'])
|
||||
ui.update(force=True, new_data={'status': 'Battery exhausted, bye ...'})
|
||||
pwnagotchi.shutdown()
|
||||
|
@ -3,6 +3,7 @@ import logging
|
||||
import json
|
||||
import csv
|
||||
import requests
|
||||
import pwnagotchi
|
||||
|
||||
from io import StringIO
|
||||
from datetime import datetime
|
||||
@ -24,7 +25,11 @@ def _extract_gps_data(path):
|
||||
with open(path, 'r') as json_file:
|
||||
tempJson = json.load(json_file)
|
||||
d = datetime.utcfromtimestamp(int(tempJson["ts"]))
|
||||
return {"Latitude": tempJson["location"]["lat"], "Longitude": tempJson["location"]["lng"], "Altitude": 10, "Updated": d.strftime('%Y-%m-%dT%H:%M:%S.%f')}
|
||||
return {"Latitude": tempJson["location"]["lat"],
|
||||
"Longitude": tempJson["location"]["lng"],
|
||||
"Altitude": 10,
|
||||
"Accuracy": tempJson["accuracy"],
|
||||
"Updated": d.strftime('%Y-%m-%dT%H:%M:%S.%f')}
|
||||
else:
|
||||
with open(path, 'r') as json_file:
|
||||
return json.load(json_file)
|
||||
@ -38,7 +43,7 @@ def _format_auth(data):
|
||||
out = ""
|
||||
for auth in data:
|
||||
out = f"{out}[{auth}]"
|
||||
return out
|
||||
return [f"{auth}" for auth in data]
|
||||
|
||||
|
||||
def _transform_wigle_entry(gps_data, pcap_data, plugin_version):
|
||||
@ -47,10 +52,10 @@ def _transform_wigle_entry(gps_data, pcap_data, plugin_version):
|
||||
"""
|
||||
dummy = StringIO()
|
||||
# write kismet header
|
||||
dummy.write(
|
||||
"WigleWifi-1.4,appRelease={},model=pwnagotchi,release={},device=pwnagotchi,display=kismet,board=kismet,brand=pwnagotchi\n".format(plugin_version, __pwnagotchi_version__))
|
||||
dummy.write(
|
||||
"MAC,SSID,AuthMode,FirstSeen,Channel,RSSI,CurrentLatitude,CurrentLongitude,AltitudeMeters,AccuracyMeters,Type")
|
||||
dummy.write(f"WigleWifi-1.4,appRelease={plugin_version},model=pwnagotchi,release={__pwnagotchi_version__},"
|
||||
f"device={pwnagotchi.name()},display=kismet,board=RaspberryPi,brand=pwnagotchi\n")
|
||||
dummy.write("MAC,SSID,AuthMode,FirstSeen,Channel,RSSI,CurrentLatitude,"
|
||||
"CurrentLongitude,AltitudeMeters,AccuracyMeters,Type\n")
|
||||
|
||||
writer = csv.writer(dummy, delimiter=",", quoting=csv.QUOTE_NONE, escapechar="\\")
|
||||
writer.writerow([
|
||||
@ -64,7 +69,7 @@ def _transform_wigle_entry(gps_data, pcap_data, plugin_version):
|
||||
gps_data['Latitude'],
|
||||
gps_data['Longitude'],
|
||||
gps_data['Altitude'],
|
||||
0, # accuracy?
|
||||
gps_data['Accuracy'],
|
||||
'WIFI'])
|
||||
return dummy.getvalue()
|
||||
|
||||
@ -84,7 +89,7 @@ def _send_to_wigle(lines, api_key, donate=True, timeout=30):
|
||||
headers = {'Authorization': f"Basic {api_key}",
|
||||
'Accept': 'application/json'}
|
||||
data = {'donate': 'on' if donate else 'false'}
|
||||
payload = {'file': dummy, 'type': 'text/csv'}
|
||||
payload = {'file': (pwnagotchi.name()+".csv", dummy), 'type': 'multipart/form-data'}
|
||||
try:
|
||||
res = requests.post('https://api.wigle.net/api/v2/file/upload',
|
||||
data=data,
|
||||
@ -99,8 +104,8 @@ def _send_to_wigle(lines, api_key, donate=True, timeout=30):
|
||||
|
||||
|
||||
class Wigle(plugins.Plugin):
|
||||
__author__ = '33197631+dadav@users.noreply.github.com'
|
||||
__version__ = '2.0.0'
|
||||
__author__ = 'Dadav and fixed by Jayofelony'
|
||||
__version__ = '3.0.0'
|
||||
__license__ = 'GPL3'
|
||||
__description__ = 'This plugin automatically uploads collected wifis to wigle.net'
|
||||
|
||||
@ -109,6 +114,7 @@ class Wigle(plugins.Plugin):
|
||||
self.report = StatusFile('/root/.wigle_uploads', data_format='json')
|
||||
self.skip = list()
|
||||
self.lock = Lock()
|
||||
self.options = dict()
|
||||
|
||||
def on_loaded(self):
|
||||
if 'api_key' not in self.options or ('api_key' in self.options and self.options['api_key'] is None):
|
||||
|
@ -103,8 +103,8 @@ class Display(View):
|
||||
def is_waveshare2in13d(self):
|
||||
return self._implementation.name == 'waveshare2in13d'
|
||||
|
||||
def is_waveshare2in23g(self):
|
||||
return self._implementation.name == 'waveshare2in23g'
|
||||
def is_waveshare2in13g(self):
|
||||
return self._implementation.name == 'waveshare2in13g'
|
||||
|
||||
def is_waveshare2in36g(self):
|
||||
return self._implementation.name == 'waveshare2in36g'
|
||||
@ -112,6 +112,9 @@ class Display(View):
|
||||
def is_waveshare2in66(self):
|
||||
return self._implementation.name == 'waveshare2in66'
|
||||
|
||||
def is_waveshare2in66b(self):
|
||||
return self._implementation.name == 'waveshare2in66b'
|
||||
|
||||
def is_waveshare2in66g(self):
|
||||
return self._implementation.name == 'waveshare2in66g'
|
||||
|
||||
|
@ -16,6 +16,7 @@ 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
|
||||
@ -33,9 +34,10 @@ 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.waveshare2in23g import Waveshare2in23g
|
||||
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
|
||||
@ -82,6 +84,21 @@ def display_for(config):
|
||||
elif config['ui']['display']['type'] == 'dfrobot_2':
|
||||
return DFRobotV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare144lcd':
|
||||
return Waveshare144lcd(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare35lcd':
|
||||
return Waveshare35lcd(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'spotpear24inch':
|
||||
return Spotpear24inch(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'displayhatmini':
|
||||
return DisplayHatMini(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in02':
|
||||
return Waveshare1in02(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in54':
|
||||
return Waveshare154(config)
|
||||
|
||||
@ -94,12 +111,36 @@ def display_for(config):
|
||||
elif config['ui']['display']['type'] == 'waveshare1in54b_v2':
|
||||
return Waveshare154bV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in54c':
|
||||
return Waveshare1in54c(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in64g':
|
||||
return Waveshare1in64g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in7':
|
||||
return Waveshare27inch(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in7_v2':
|
||||
return Waveshare27inchV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in7b':
|
||||
return Waveshare27b(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in7b_v2':
|
||||
return Waveshare27bV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9':
|
||||
return Waveshare29inch(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9bc':
|
||||
return Waveshare2in9bc(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9d':
|
||||
return Waveshare2in9d(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9_v2':
|
||||
return Waveshare29inchV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9b_v3':
|
||||
return Waveshare29bV3(config)
|
||||
|
||||
@ -118,137 +159,101 @@ def display_for(config):
|
||||
elif config['ui']['display']['type'] == 'waveshare_4':
|
||||
return WaveshareV4(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in7':
|
||||
return Waveshare27inch(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in7_v2':
|
||||
return Waveshare27inchV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9':
|
||||
return Waveshare29inch(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9_v2':
|
||||
return Waveshare29inchV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare144lcd':
|
||||
return Waveshare144lcd(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in54b':
|
||||
return Waveshare154inchb(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in13bc':
|
||||
return Waveshare213bc(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in13d':
|
||||
return Waveshare213d(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in13b_v3':
|
||||
return Waveshare2in13bV3(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in13b_v4':
|
||||
return Waveshare213bV4(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare35lcd':
|
||||
return Waveshare35lcd(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'spotpear24inch':
|
||||
return Spotpear24inch(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'displayhatmini':
|
||||
return DisplayHatMini(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in54c':
|
||||
return Waveshare1in54c
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in64g':
|
||||
return Waveshare1in64g
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare1in02':
|
||||
return Waveshare1in02
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9bc':
|
||||
return Waveshare2in9bc
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in9d':
|
||||
return Waveshare2in9d
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in13b_v3':
|
||||
return Waveshare2in13bV3
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in23g':
|
||||
return Waveshare2in23g
|
||||
elif config['ui']['display']['type'] == 'waveshare2in13g':
|
||||
return Waveshare2in13g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in36g':
|
||||
return Waveshare2in36g
|
||||
return Waveshare2in36g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in66':
|
||||
return Waveshare2in66
|
||||
return Waveshare2in66(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in66b':
|
||||
return Waveshare2in66b(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare2in66g':
|
||||
return Waveshare2in66g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare3in0g':
|
||||
return Waveshare3in0g
|
||||
return Waveshare3in0g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare3in7':
|
||||
return Waveshare3in7
|
||||
return Waveshare3in7(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare3in52':
|
||||
return Waveshare3in52
|
||||
return Waveshare3in52(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in01f':
|
||||
return Waveshare4in01f
|
||||
return Waveshare4in01f(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in2':
|
||||
return Waveshare4in2
|
||||
return Waveshare4in2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in2_v2':
|
||||
return Waveshare4in2V2
|
||||
return Waveshare4in2V2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in2b_v2':
|
||||
return Waveshare4in2bV2
|
||||
return Waveshare4in2bV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in2bc':
|
||||
return Waveshare4in2bc
|
||||
return Waveshare4in2bc(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in26':
|
||||
return Waveshare4in26
|
||||
return Waveshare4in26(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare4in37g':
|
||||
return Waveshare4in37g
|
||||
return Waveshare4in37g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare5in65f':
|
||||
return Waveshare5in65f
|
||||
return Waveshare5in65f(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare5in83':
|
||||
return Waveshare5in83
|
||||
return Waveshare5in83(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare5in83_v2':
|
||||
return Waveshare5in83V2
|
||||
return Waveshare5in83V2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare5in83b_v2':
|
||||
return Waveshare5in83bV2
|
||||
return Waveshare5in83bV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare5in83bc':
|
||||
return Waveshare5in83bc
|
||||
return Waveshare5in83bc(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in3f':
|
||||
return Waveshare7in3f
|
||||
return Waveshare7in3f(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in3g':
|
||||
return Waveshare7in3g
|
||||
return Waveshare7in3g(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in5':
|
||||
return Waveshare7in5
|
||||
return Waveshare7in5(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in5_HD':
|
||||
return Waveshare7in5HD
|
||||
return Waveshare7in5HD(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in5_v2':
|
||||
return Waveshare7in5V2
|
||||
return Waveshare7in5V2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in5b_HD':
|
||||
return Waveshare7in5bHD
|
||||
return Waveshare7in5bHD(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in5b_v2':
|
||||
return Waveshare7in5bV2
|
||||
return Waveshare7in5bV2(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare7in5bc':
|
||||
return Waveshare7in5bc
|
||||
return Waveshare7in5bc(config)
|
||||
|
||||
elif config['ui']['display']['type'] == 'waveshare13in3k':
|
||||
return Waveshare13in3k
|
||||
return Waveshare13in3k(config)
|
||||
|
@ -3,6 +3,7 @@ import pwnagotchi.ui.fonts as fonts
|
||||
|
||||
class DisplayImpl(object):
|
||||
def __init__(self, config, name):
|
||||
self._display = None
|
||||
if fonts.Medium is None:
|
||||
fonts.init(config)
|
||||
self.name = name
|
||||
|
@ -3,10 +3,10 @@ import logging
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class DFRobotV1(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(DFRobotV1, self).__init__(config, 'dfrobot_1')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -3,10 +3,10 @@ import logging
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class DFRobotV1(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(DFRobotV1, self).__init__(config, 'dfrobot_1')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -3,10 +3,10 @@ import logging
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class DFRobotV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(DFRobotV2, self).__init__(config, 'dfrobot_2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -3,10 +3,10 @@ import logging
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class DFRobotV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(DFRobotV2, self).__init__(config, 'dfrobot_2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class DisplayHatMini(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(DisplayHatMini, self).__init__(config, 'displayhatmini')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(12, 10, 12, 70, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Inky(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Inky, self).__init__(config, 'inky')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 28, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class LcdHat(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(LcdHat, self).__init__(config, 'lcdhat')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -91,9 +91,9 @@ class EPD:
|
||||
def SetWindow(self):
|
||||
self.send_command(0x61) # SET_RAM_X_ADDRESS_START_END_POSITION
|
||||
# x point must be the multiple of 8 or the last 3 bits will be ignored
|
||||
self.send_data(self.Source_BITS / 256)
|
||||
self.send_data(int(self.Source_BITS / 256))
|
||||
self.send_data(self.Source_BITS % 256)
|
||||
self.send_data(self.Gate_BITS / 256)
|
||||
self.send_data(int(self.Gate_BITS / 256))
|
||||
self.send_data(self.Gate_BITS % 256)
|
||||
|
||||
def TurnOnDisplay(self):
|
||||
@ -166,20 +166,21 @@ class EPD:
|
||||
|
||||
def getbuffer(self, image):
|
||||
# Create a pallette with the 4 colors supported by the panel
|
||||
global image_temp
|
||||
pal_image = Image.new("P", (1, 1))
|
||||
pal_image.putpalette((0, 0, 0, 255, 255, 255, 255, 255, 0, 255, 0, 0) + (0, 0, 0) * 252)
|
||||
|
||||
# Check if we need to rotate the image
|
||||
imwidth, imheight = image.size
|
||||
if (imwidth == self.width and imheight == self.height):
|
||||
if imwidth == self.width and imheight == self.height:
|
||||
image_temp = image
|
||||
elif (imwidth == self.height and imheight == self.width):
|
||||
elif imwidth == self.height and imheight == self.width:
|
||||
image_temp = image.rotate(90, expand=True)
|
||||
else:
|
||||
logger.warning(
|
||||
"Invalid image dimensions: %d x %d, expected %d x %d" % (imwidth, imheight, self.width, self.height))
|
||||
|
||||
# Convert the soruce image to the 4 colors, dithering if needed
|
||||
# Convert the source image to the 4 colors, dithering if needed
|
||||
image_4color = image_temp.convert("RGB").quantize(palette=pal_image)
|
||||
buf_4color = bytearray(image_4color.tobytes('raw'))
|
||||
|
189
pwnagotchi/ui/hw/libs/waveshare/v2in66b/epd2in66b.py
Normal file
189
pwnagotchi/ui/hw/libs/waveshare/v2in66b/epd2in66b.py
Normal file
@ -0,0 +1,189 @@
|
||||
# *****************************************************************************
|
||||
# * | File : epd2in66b.py
|
||||
# * | Author : Waveshare team
|
||||
# * | Function : Electronic paper driver
|
||||
# * | Info :
|
||||
# *----------------
|
||||
# * | This version: V1.1
|
||||
# * | Date : 2022-08-9
|
||||
# # | Info : python demo
|
||||
# -----------------------------------------------------------------------------
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documnetation 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
|
||||
# furished 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 OR 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.
|
||||
#
|
||||
|
||||
import logging
|
||||
from .. import epdconfig
|
||||
|
||||
# Display resolution
|
||||
EPD_WIDTH = 152
|
||||
EPD_HEIGHT = 296
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class EPD:
|
||||
def __init__(self):
|
||||
self.reset_pin = epdconfig.RST_PIN
|
||||
self.dc_pin = epdconfig.DC_PIN
|
||||
self.busy_pin = epdconfig.BUSY_PIN
|
||||
self.cs_pin = epdconfig.CS_PIN
|
||||
self.width = EPD_WIDTH
|
||||
self.height = EPD_HEIGHT
|
||||
|
||||
# Hardware reset
|
||||
def reset(self):
|
||||
epdconfig.digital_write(self.reset_pin, 1)
|
||||
epdconfig.delay_ms(200)
|
||||
epdconfig.digital_write(self.reset_pin, 0)
|
||||
epdconfig.delay_ms(5)
|
||||
epdconfig.digital_write(self.reset_pin, 1)
|
||||
epdconfig.delay_ms(200)
|
||||
|
||||
def send_command(self, command):
|
||||
epdconfig.digital_write(self.dc_pin, 0)
|
||||
epdconfig.digital_write(self.cs_pin, 0)
|
||||
epdconfig.spi_writebyte([command])
|
||||
epdconfig.digital_write(self.cs_pin, 1)
|
||||
|
||||
def send_data(self, data):
|
||||
epdconfig.digital_write(self.dc_pin, 1)
|
||||
epdconfig.digital_write(self.cs_pin, 0)
|
||||
epdconfig.spi_writebyte([data])
|
||||
epdconfig.digital_write(self.cs_pin, 1)
|
||||
|
||||
# send a lot of data
|
||||
def send_data2(self, data):
|
||||
epdconfig.digital_write(self.dc_pin, 1)
|
||||
epdconfig.digital_write(self.cs_pin, 0)
|
||||
epdconfig.spi_writebyte2(data)
|
||||
epdconfig.digital_write(self.cs_pin, 1)
|
||||
|
||||
def ReadBusy(self):
|
||||
logger.debug("e-Paper busy")
|
||||
while (epdconfig.digital_read(self.busy_pin) == 1): # 0: idle, 1: busy
|
||||
epdconfig.delay_ms(20)
|
||||
logger.debug("e-Paper busy release")
|
||||
|
||||
def init(self):
|
||||
if (epdconfig.module_init() != 0):
|
||||
return -1
|
||||
# EPD hardware init start
|
||||
self.reset()
|
||||
|
||||
self.send_command(0x12)
|
||||
epdconfig.delay_ms(30)
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x11) # setting gaet number
|
||||
self.send_data(0x03)
|
||||
|
||||
self.setWindows(0, 0, self.width - 1, self.height - 1)
|
||||
|
||||
self.send_command(0x21)
|
||||
self.send_data(0x00)
|
||||
self.send_data(0x80)
|
||||
|
||||
self.setCursor(0, 0)
|
||||
self.ReadBusy()
|
||||
|
||||
return 0
|
||||
|
||||
def setWindows(self, Xstart, Ystart, Xend, Yend):
|
||||
self.send_command(0x44) # SET_RAM_X_ADDRESS_START_END_POSITION
|
||||
self.send_data((Xstart >> 3) & 0x1F)
|
||||
self.send_data((Xend >> 3) & 0x1F)
|
||||
|
||||
self.send_command(0x45) # SET_RAM_Y_ADDRESS_START_END_POSITION
|
||||
self.send_data(Ystart & 0xFF)
|
||||
self.send_data((Ystart >> 8) & 0x01)
|
||||
self.send_data(Yend & 0xFF)
|
||||
self.send_data((Yend >> 8) & 0x01)
|
||||
|
||||
def setCursor(self, Xstart, Ystart):
|
||||
self.send_command(0x4E) # SET_RAM_X_ADDRESS_COUNTER
|
||||
self.send_data(Xstart & 0x1F)
|
||||
|
||||
self.send_command(0x4F) # SET_RAM_Y_ADDRESS_COUNTER
|
||||
self.send_data(Ystart & 0xFF)
|
||||
self.send_data((Ystart >> 8) & 0x01)
|
||||
|
||||
def turnon_display(self):
|
||||
self.send_command(0x20)
|
||||
self.ReadBusy()
|
||||
|
||||
def getbuffer(self, image):
|
||||
# logger.debug("bufsiz = ",int(self.width/8) * self.height)
|
||||
buf = [0xFF] * (int(self.width / 8) * self.height)
|
||||
image_monocolor = image.convert('1')
|
||||
imwidth, imheight = image_monocolor.size
|
||||
pixels = image_monocolor.load()
|
||||
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
||||
if (imwidth == self.width and imheight == self.height):
|
||||
logger.debug("Vertical")
|
||||
for y in range(imheight):
|
||||
for x in range(imwidth):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
if pixels[x, y] == 0:
|
||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||
elif (imwidth == self.height and imheight == self.width):
|
||||
logger.debug("Horizontal")
|
||||
for y in range(imheight):
|
||||
for x in range(imwidth):
|
||||
newx = y
|
||||
newy = self.height - x - 1
|
||||
if pixels[x, y] == 0:
|
||||
buf[int((newx + newy * self.width) / 8)] &= ~(0x80 >> (y % 8))
|
||||
return buf
|
||||
|
||||
def display(self, Blackimage, Redimage):
|
||||
if (Blackimage == None or Redimage == None):
|
||||
return
|
||||
Redimage_1 = [0x00] * len(Redimage)
|
||||
for i in range(len(Redimage)):
|
||||
Redimage_1[i] = ~Redimage[i]
|
||||
self.send_command(0x24)
|
||||
self.send_data2(Blackimage)
|
||||
|
||||
self.send_command(0x26)
|
||||
self.send_data2(Redimage_1)
|
||||
|
||||
self.turnon_display()
|
||||
|
||||
def Clear(self):
|
||||
if self.width % 8 == 0:
|
||||
linewidth = int(self.width / 8)
|
||||
else:
|
||||
linewidth = int(self.width / 8) + 1
|
||||
|
||||
self.send_command(0x24)
|
||||
self.send_data2([0xff] * int(self.height * linewidth))
|
||||
|
||||
self.send_command(0x26)
|
||||
self.send_data2([0x00] * int(self.height * linewidth))
|
||||
|
||||
self.turnon_display()
|
||||
|
||||
def sleep(self):
|
||||
self.send_command(0X10) # DEEP_SLEEP_MODE
|
||||
self.send_data(0x01)
|
||||
|
||||
epdconfig.delay_ms(2000)
|
||||
epdconfig.module_exit()
|
||||
|
||||
### END OF FILE ###
|
@ -100,7 +100,7 @@ class EPD:
|
||||
|
||||
def ReadBusy(self):
|
||||
logger.debug("e-Paper busy")
|
||||
while (epdconfig.digital_read(self.busy_pin) == 1): # 1: idle, 0: busy
|
||||
while epdconfig.digital_read(self.busy_pin) == 1: # 1: idle, 0: busy
|
||||
epdconfig.delay_ms(20)
|
||||
logger.debug("e-Paper busy release")
|
||||
|
||||
@ -134,7 +134,7 @@ class EPD:
|
||||
self.send_data(self.LUT_DATA_4Gray[i])
|
||||
|
||||
def init(self):
|
||||
if (epdconfig.module_init() != 0):
|
||||
if epdconfig.module_init() != 0:
|
||||
return -1
|
||||
|
||||
# EPD hardware init start
|
||||
@ -159,7 +159,7 @@ class EPD:
|
||||
return 0
|
||||
|
||||
def init_Fast(self):
|
||||
if (epdconfig.module_init() != 0):
|
||||
if epdconfig.module_init() != 0:
|
||||
return -1
|
||||
|
||||
# EPD hardware init start
|
||||
@ -204,12 +204,12 @@ class EPD:
|
||||
return 0
|
||||
|
||||
def Init_4Gray(self):
|
||||
if (epdconfig.module_init() != 0):
|
||||
if epdconfig.module_init() != 0:
|
||||
return -1
|
||||
self.reset()
|
||||
|
||||
self.send_command(0x12) # soft reset
|
||||
self.ReadBusy();
|
||||
self.ReadBusy()
|
||||
|
||||
self.send_command(0x74) # set analog block control
|
||||
self.send_data(0x54)
|
||||
@ -268,14 +268,14 @@ class EPD:
|
||||
imwidth, imheight = image_monocolor.size
|
||||
pixels = image_monocolor.load()
|
||||
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
||||
if (imwidth == self.width and imheight == self.height):
|
||||
if imwidth == self.width and imheight == self.height:
|
||||
logger.debug("Vertical")
|
||||
for y in range(imheight):
|
||||
for x in range(imwidth):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
if pixels[x, y] == 0:
|
||||
buf[int((x + y * self.width) / 8)] &= ~(0x80 >> (x % 8))
|
||||
elif (imwidth == self.height and imheight == self.width):
|
||||
elif imwidth == self.height and imheight == self.width:
|
||||
logger.debug("Horizontal")
|
||||
for y in range(imheight):
|
||||
for x in range(imwidth):
|
||||
@ -293,40 +293,40 @@ class EPD:
|
||||
pixels = image_monocolor.load()
|
||||
i = 0
|
||||
# logger.debug("imwidth = %d, imheight = %d",imwidth,imheight)
|
||||
if (imwidth == self.width and imheight == self.height):
|
||||
if imwidth == self.width and imheight == self.height:
|
||||
logger.debug("Vertical")
|
||||
for y in range(imheight):
|
||||
for x in range(imwidth):
|
||||
# Set the bits for the column of pixels at the current position.
|
||||
if (pixels[x, y] == 0xC0):
|
||||
if pixels[x, y] == 0xC0:
|
||||
pixels[x, y] = 0x80
|
||||
elif (pixels[x, y] == 0x80):
|
||||
elif pixels[x, y] == 0x80:
|
||||
pixels[x, y] = 0x40
|
||||
i = i + 1
|
||||
if (i % 4 == 0):
|
||||
if i % 4 == 0:
|
||||
buf[int((x + (y * self.width)) / 4)] = (
|
||||
(pixels[x - 3, y] & 0xc0) | (pixels[x - 2, y] & 0xc0) >> 2 | (
|
||||
pixels[x - 1, y] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
||||
|
||||
elif (imwidth == self.height and imheight == self.width):
|
||||
elif imwidth == self.height and imheight == self.width:
|
||||
logger.debug("Horizontal")
|
||||
for x in range(imwidth):
|
||||
for y in range(imheight):
|
||||
newx = y
|
||||
newy = self.height - x - 1
|
||||
if (pixels[x, y] == 0xC0):
|
||||
if pixels[x, y] == 0xC0:
|
||||
pixels[x, y] = 0x80
|
||||
elif (pixels[x, y] == 0x80):
|
||||
elif pixels[x, y] == 0x80:
|
||||
pixels[x, y] = 0x40
|
||||
i = i + 1
|
||||
if (i % 4 == 0):
|
||||
if i % 4 == 0:
|
||||
buf[int((newx + (newy * self.width)) / 4)] = (
|
||||
(pixels[x, y - 3] & 0xc0) | (pixels[x, y - 2] & 0xc0) >> 2 | (
|
||||
pixels[x, y - 1] & 0xc0) >> 4 | (pixels[x, y] & 0xc0) >> 6)
|
||||
return buf
|
||||
|
||||
def Clear(self):
|
||||
if (self.width % 8 == 0):
|
||||
if self.width % 8 == 0:
|
||||
Width = self.width // 8
|
||||
else:
|
||||
Width = self.width // 8 + 1
|
||||
@ -338,7 +338,7 @@ class EPD:
|
||||
self.TurnOnDisplay()
|
||||
|
||||
def display(self, image):
|
||||
if (self.width % 8 == 0):
|
||||
if self.width % 8 == 0:
|
||||
Width = self.width // 8
|
||||
else:
|
||||
Width = self.width // 8 + 1
|
||||
@ -350,7 +350,7 @@ class EPD:
|
||||
self.TurnOnDisplay()
|
||||
|
||||
def display_Fast(self, image):
|
||||
if (self.width % 8 == 0):
|
||||
if self.width % 8 == 0:
|
||||
Width = self.width // 8
|
||||
else:
|
||||
Width = self.width // 8 + 1
|
||||
@ -362,7 +362,7 @@ class EPD:
|
||||
self.TurnOnDisplay_Fast()
|
||||
|
||||
def display_Base(self, image):
|
||||
if (self.width % 8 == 0):
|
||||
if self.width % 8 == 0:
|
||||
Width = self.width // 8
|
||||
else:
|
||||
Width = self.width // 8 + 1
|
||||
@ -379,7 +379,7 @@ class EPD:
|
||||
self.TurnOnDisplay()
|
||||
|
||||
def display_Base_color(self, color):
|
||||
if (self.width % 8 == 0):
|
||||
if self.width % 8 == 0:
|
||||
Width = self.width // 8
|
||||
else:
|
||||
Width = self.width // 8 + 1
|
||||
@ -396,8 +396,7 @@ class EPD:
|
||||
# self.TurnOnDisplay()
|
||||
|
||||
def display_Partial(self, Image, Xstart, Ystart, Xend, Yend):
|
||||
if ((Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | (
|
||||
Xend - Xstart) % 8 == 0):
|
||||
if (Xstart % 8 + Xend % 8 == 8 & Xstart % 8 > Xend % 8) | Xstart % 8 + Xend % 8 == 0 | (Xend - Xstart) % 8 == 0:
|
||||
Xstart = Xstart // 8
|
||||
Xend = Xend // 8
|
||||
else:
|
||||
@ -440,23 +439,23 @@ class EPD:
|
||||
self.send_command(0x24) # Write Black and White image to RAM
|
||||
for j in range(Height):
|
||||
for i in range(Width):
|
||||
if ((j > Ystart - 1) & (j < (Yend + 1)) & (i > Xstart - 1) & (i < (Xend + 1))):
|
||||
if (j > Ystart - 1) & (j < (Yend + 1)) & (i > Xstart - 1) & (i < (Xend + 1)):
|
||||
self.send_data(Image[i + j * Width])
|
||||
self.TurnOnDisplay_Partial()
|
||||
|
||||
def display_4Gray(self, image):
|
||||
self.send_command(0x24)
|
||||
for i in range(0, 48000): # 5808*4 46464
|
||||
for i in range(0, 5808): # 5808*4 46464
|
||||
temp3 = 0
|
||||
for j in range(0, 2):
|
||||
temp1 = image[i * 2 + j]
|
||||
for k in range(0, 2):
|
||||
temp2 = temp1 & 0xC0
|
||||
if (temp2 == 0xC0):
|
||||
if temp2 == 0xC0:
|
||||
temp3 |= 0x00
|
||||
elif (temp2 == 0x00):
|
||||
elif temp2 == 0x00:
|
||||
temp3 |= 0x01
|
||||
elif (temp2 == 0x80):
|
||||
elif temp2 == 0x80:
|
||||
temp3 |= 0x01
|
||||
else: # 0x40
|
||||
temp3 |= 0x00
|
||||
@ -464,31 +463,31 @@ class EPD:
|
||||
|
||||
temp1 <<= 2
|
||||
temp2 = temp1 & 0xC0
|
||||
if (temp2 == 0xC0):
|
||||
if temp2 == 0xC0:
|
||||
temp3 |= 0x00
|
||||
elif (temp2 == 0x00):
|
||||
elif temp2 == 0x00:
|
||||
temp3 |= 0x01
|
||||
elif (temp2 == 0x80):
|
||||
elif temp2 == 0x80:
|
||||
temp3 |= 0x01
|
||||
else: # 0x40
|
||||
temp3 |= 0x00
|
||||
if (j != 1 or k != 1):
|
||||
if j != 1 or k != 1:
|
||||
temp3 <<= 1
|
||||
temp1 <<= 2
|
||||
self.send_data(temp3)
|
||||
|
||||
self.send_command(0x26)
|
||||
for i in range(0, 48000): # 5808*4 46464
|
||||
for i in range(0, 5808): # 5808*4 46464
|
||||
temp3 = 0
|
||||
for j in range(0, 2):
|
||||
temp1 = image[i * 2 + j]
|
||||
for k in range(0, 2):
|
||||
temp2 = temp1 & 0xC0
|
||||
if (temp2 == 0xC0):
|
||||
if temp2 == 0xC0:
|
||||
temp3 |= 0x00
|
||||
elif (temp2 == 0x00):
|
||||
elif temp2 == 0x00:
|
||||
temp3 |= 0x01
|
||||
elif (temp2 == 0x80):
|
||||
elif temp2 == 0x80:
|
||||
temp3 |= 0x00
|
||||
else: # 0x40
|
||||
temp3 |= 0x01
|
||||
@ -496,15 +495,15 @@ class EPD:
|
||||
|
||||
temp1 <<= 2
|
||||
temp2 = temp1 & 0xC0
|
||||
if (temp2 == 0xC0):
|
||||
if temp2 == 0xC0:
|
||||
temp3 |= 0x00
|
||||
elif (temp2 == 0x00):
|
||||
elif temp2 == 0x00:
|
||||
temp3 |= 0x01
|
||||
elif (temp2 == 0x80):
|
||||
elif temp2 == 0x80:
|
||||
temp3 |= 0x00
|
||||
else: # 0x40
|
||||
temp3 |= 0x01
|
||||
if (j != 1 or k != 1):
|
||||
if j != 1 or k != 1:
|
||||
temp3 <<= 1
|
||||
temp1 <<= 2
|
||||
self.send_data(temp3)
|
||||
@ -517,4 +516,3 @@ class EPD:
|
||||
|
||||
epdconfig.delay_ms(2000)
|
||||
epdconfig.module_exit()
|
||||
### END OF FILE ###
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class OledHat(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(OledHat, self).__init__(config, 'oledhat')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(8, 8, 8, 10, 10, 8)
|
||||
|
@ -8,7 +8,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Papirus(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Papirus, self).__init__(config, 'papirus')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 23, 25, 9)
|
||||
|
@ -3,12 +3,12 @@ import logging
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
import os,time
|
||||
import time
|
||||
|
||||
|
||||
class Spotpear24inch(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Spotpear24inch, self).__init__(config, 'spotpear24inch')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(12, 10, 12, 70, 25, 9)
|
||||
|
@ -3,12 +3,12 @@ import logging
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
import os,time
|
||||
import time
|
||||
|
||||
|
||||
class Spotpear24inch(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Spotpear24inch, self).__init__(config, 'spotpear24inch')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(12, 10, 12, 70, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare13in3k(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare13in3k, self).__init__(config, 'waveshare13in3k')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare144lcd(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare144lcd, self).__init__(config, 'waveshare144lcd')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
@ -42,5 +41,4 @@ class Waveshare144lcd(DisplayImpl):
|
||||
self._display.display(canvas)
|
||||
|
||||
def clear(self):
|
||||
pass
|
||||
#self._display.clear()
|
||||
self._display.clear()
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare1in02(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare1in02, self).__init__(config, 'waveshare1in02')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare144lcd(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare144lcd, self).__init__(config, 'waveshare144lcd')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare154(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare154, self).__init__(config, 'waveshare1in54')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare154V2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare154V2, self).__init__(config, 'waveshare1in54_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare154inchb(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare154inchb, self).__init__(config, 'waveshare1in54b')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare154bV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare154bV2, self).__init__(config, 'waveshare1in54b_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare1in54c(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare1in54c, self).__init__(config, 'waveshare1in54c')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare1in64g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare1in64g, self).__init__(config, 'waveshare1in64g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class WaveshareV1(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(WaveshareV1, self).__init__(config, 'waveshare_1')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
if self.config['color'] == 'black':
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class WaveshareV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(WaveshareV2, self).__init__(config, 'waveshare_2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
if self.config['color'] == 'black':
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class WaveshareV3(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(WaveshareV3, self).__init__(config, 'waveshare_3')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class WaveshareV4(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(WaveshareV4, self).__init__(config, 'waveshare_4')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -8,7 +8,6 @@ from PIL import Image
|
||||
class Waveshare2in13bV3(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in13bV3, self).__init__(config, 'waveshare2in13b_v3')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
if self.config['color'] == 'black':
|
||||
|
@ -8,7 +8,6 @@ from PIL import Image
|
||||
class Waveshare213bV4(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare213bV4, self).__init__(config, 'waveshare213inb_v4')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
if self.config['color'] == 'black':
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare213bc(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare213bc, self).__init__(config, 'waveshare2in13bc')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare213d(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare213d, self).__init__(config, 'waveshare2in13d')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||
|
45
pwnagotchi/ui/hw/waveshare2in13g.py
Normal file
45
pwnagotchi/ui/hw/waveshare2in13g.py
Normal file
@ -0,0 +1,45 @@
|
||||
import logging
|
||||
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class Waveshare2in13g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in13g, self).__init__(config, 'waveshare2in13g')
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
self._layout['width'] = 250
|
||||
self._layout['height'] = 122
|
||||
self._layout['face'] = (0, 40)
|
||||
self._layout['name'] = (5, 20)
|
||||
self._layout['channel'] = (0, 0)
|
||||
self._layout['aps'] = (28, 0)
|
||||
self._layout['uptime'] = (185, 0)
|
||||
self._layout['line1'] = [0, 14, 250, 14]
|
||||
self._layout['line2'] = [0, 108, 250, 108]
|
||||
self._layout['friend_face'] = (0, 92)
|
||||
self._layout['friend_name'] = (40, 94)
|
||||
self._layout['shakes'] = (0, 109)
|
||||
self._layout['mode'] = (225, 109)
|
||||
self._layout['status'] = {
|
||||
'pos': (125, 20),
|
||||
'font': fonts.status_font(fonts.Medium),
|
||||
'max': 20
|
||||
}
|
||||
return self._layout
|
||||
|
||||
def initialize(self):
|
||||
logging.info("initializing waveshare v2in13g display")
|
||||
from pwnagotchi.ui.hw.libs.waveshare.v2in13g.epd2in13g import EPD
|
||||
self._display = EPD()
|
||||
self._display.init()
|
||||
self._display.Clear()
|
||||
|
||||
def render(self, canvas):
|
||||
buf = self._display.getbuffer(canvas)
|
||||
self._display.display(buf)
|
||||
|
||||
def clear(self):
|
||||
self._display.Clear()
|
@ -1,46 +0,0 @@
|
||||
import logging
|
||||
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class Waveshare2in23g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in23g, self).__init__(config, 'waveshare2in23g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 25, 25, 9)
|
||||
self._layout['width'] = 122
|
||||
self._layout['height'] = 250
|
||||
self._layout['face'] = (0, 26)
|
||||
self._layout['name'] = (5, 15)
|
||||
self._layout['channel'] = (0, 0)
|
||||
self._layout['aps'] = (28, 0)
|
||||
self._layout['uptime'] = (147, 0)
|
||||
self._layout['line1'] = [0, 12, 122, 12]
|
||||
self._layout['line2'] = [0, 92, 122, 92]
|
||||
self._layout['friend_face'] = (0, 76)
|
||||
self._layout['friend_name'] = (40, 78)
|
||||
self._layout['shakes'] = (0, 93)
|
||||
self._layout['mode'] = (187, 93)
|
||||
self._layout['status'] = {
|
||||
'pos': (91, 15),
|
||||
'font': fonts.status_font(fonts.Medium),
|
||||
'max': 20
|
||||
}
|
||||
return self._layout
|
||||
|
||||
def initialize(self):
|
||||
logging.info("initializing waveshare 2.23g inch display")
|
||||
from pwnagotchi.ui.hw.libs.waveshare.v2in23g.epd2in13g import EPD
|
||||
self._display = EPD()
|
||||
self._display.init()
|
||||
self._display.Clear()
|
||||
|
||||
def render(self, canvas):
|
||||
buf = self._display.getbuffer(canvas)
|
||||
self._display.display(buf)
|
||||
|
||||
def clear(self):
|
||||
self._display.Clear()
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare2in36g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in36g, self).__init__(config, 'waveshare2in36g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare2in66(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in66, self).__init__(config, 'waveshare2in66')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
45
pwnagotchi/ui/hw/waveshare2in66b.py
Normal file
45
pwnagotchi/ui/hw/waveshare2in66b.py
Normal file
@ -0,0 +1,45 @@
|
||||
import logging
|
||||
|
||||
import pwnagotchi.ui.fonts as fonts
|
||||
from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
|
||||
|
||||
class Waveshare2in66b(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in66b, self).__init__(config, 'waveshare2in66b')
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
self._layout['width'] = 152
|
||||
self._layout['height'] = 296
|
||||
self._layout['face'] = (0, 43)
|
||||
self._layout['name'] = (0, 14)
|
||||
self._layout['channel'] = (0, 0)
|
||||
self._layout['aps'] = (0, 71)
|
||||
self._layout['uptime'] = (0, 25)
|
||||
self._layout['line1'] = [0, 12, 152, 12]
|
||||
self._layout['line2'] = [0, 116, 152, 116]
|
||||
self._layout['friend_face'] = (12, 88)
|
||||
self._layout['friend_name'] = (1, 103)
|
||||
self._layout['shakes'] = (26, 117)
|
||||
self._layout['mode'] = (0, 117)
|
||||
self._layout['status'] = {
|
||||
'pos': (65, 26),
|
||||
'font': fonts.status_font(fonts.Small),
|
||||
'max': 12
|
||||
}
|
||||
return self._layout
|
||||
|
||||
def initialize(self):
|
||||
logging.info("initializing waveshare 2.66b inch lcd display")
|
||||
from pwnagotchi.ui.hw.libs.waveshare.v2in66b.epd2in66b import EPD
|
||||
self._display = EPD()
|
||||
self._display.init()
|
||||
self._display.Clear()
|
||||
|
||||
def render(self, canvas):
|
||||
buf = self._display.getbuffer(canvas)
|
||||
self._display.display(buf, None)
|
||||
|
||||
def clear(self):
|
||||
self._display.Clear()
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare2in66g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in66g, self).__init__(config, 'waveshare2in66g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare27inch(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare27inch, self).__init__(config, 'waveshare2in7')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare27inchV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare27inchV2, self).__init__(config, 'waveshare2in7_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
@ -42,7 +41,7 @@ class Waveshare27inchV2(DisplayImpl):
|
||||
|
||||
def render(self, canvas):
|
||||
buf = self._display.getbuffer(canvas)
|
||||
self._display.display_Partial(buf,0,0,176,264)
|
||||
self._display.display_Partial(buf, 0, 0, 176, 264)
|
||||
|
||||
def clear(self):
|
||||
# This line also removes the 0xFF
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare27b(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare27b, self).__init__(config, 'waveshare2in7b')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare27bV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare27bV2, self).__init__(config, 'waveshare2in7b_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare29inch(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare29inch, self).__init__(config, 'waveshare2in9')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare29inchV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare29inchV2, self).__init__(config, 'waveshare2in9_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare29bV3(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare29bV3, self).__init__(config, 'waveshare2in9b_v3')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare29bV4(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare29bV4, self).__init__(config, 'waveshare2in9b_v4')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 9, 10, 35, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare2in9bc(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in9bc, self).__init__(config, 'waveshare2in9bc')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare2in9d(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare2in9d, self).__init__(config, 'waveshare2in9d')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -9,7 +9,6 @@ import os, time
|
||||
class Waveshare35lcd(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare35lcd, self).__init__(config, 'waveshare35lcd')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(12, 10, 12, 70, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare3in0g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare3in0g, self).__init__(config, 'waveshare3in0g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare3in52(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare3in52, self).__init__(config, 'waveshare3in52')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -9,7 +9,6 @@ import os, time
|
||||
class Waveshare35lcd(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare35lcd, self).__init__(config, 'waveshare35lcd')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(12, 10, 12, 70, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare3in7(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare3in7, self).__init__(config, 'waveshare3in7')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
@ -39,7 +38,7 @@ class Waveshare3in7(DisplayImpl):
|
||||
self._display.Clear(0)
|
||||
|
||||
def render(self, canvas):
|
||||
self._display.display(canvas)
|
||||
self._display.display_4Gray(canvas)
|
||||
|
||||
def clear(self):
|
||||
self._display.Clear(0)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in01f(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in01f, self).__init__(config, 'waveshare4in01f')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in2, self).__init__(config, 'waveshare4in2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in26(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in26, self).__init__(config, 'waveshare4in26')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in2V2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in2V2, self).__init__(config, 'waveshare4in2_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in2bV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in2bV2, self).__init__(config, 'waveshare4in2b_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in2bc(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in2bc, self).__init__(config, 'waveshare4in2bc')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare4in37g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare4in37g, self).__init__(config, 'waveshare4in37g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare5in65f(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare5in65f, self).__init__(config, 'waveshare5in65f')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare5in83(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare5in83, self).__init__(config, 'waveshare5in83')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare5in83V2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare5in83V2, self).__init__(config, 'waveshare5in83_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare5in83bV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare5in83bV2, self).__init__(config, 'waveshare5in83b_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare5in83bc(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare5in83bc, self).__init__(config, 'waveshare5in83bc')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in3f(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in3f, self).__init__(config, 'waveshare7in3f')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in3g(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in3g, self).__init__(config, 'waveshare7in3g')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in5(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in5, self).__init__(config, 'waveshare7in5')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in5HD(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in5HD, self).__init__(config, 'waveshare7in5_HD')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in5V2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in5V2, self).__init__(config, 'waveshare7in5_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in5bHD(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in5bHD, self).__init__(config, 'waveshare7in5b_HD')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in5bV2(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in5bV2, self).__init__(config, 'waveshare7in5b_v2')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -7,7 +7,6 @@ from pwnagotchi.ui.hw.base import DisplayImpl
|
||||
class Waveshare7in5bc(DisplayImpl):
|
||||
def __init__(self, config):
|
||||
super(Waveshare7in5bc, self).__init__(config, 'waveshare7in5bc')
|
||||
self._display = None
|
||||
|
||||
def layout(self):
|
||||
fonts.setup(10, 8, 10, 18, 25, 9)
|
||||
|
@ -306,6 +306,9 @@ def load_config(args):
|
||||
elif config['ui']['display']['type'] in ('ws_213d', 'ws213d', 'waveshare2in13d', 'waveshare_213d', 'waveshare213d'):
|
||||
config['ui']['display']['type'] = 'waveshare2in13d'
|
||||
|
||||
elif config['ui']['display']['type'] in ('ws_213g', 'waveshare2in13g', 'waveshare213g', 'ws213g', 'waveshare_213g'):
|
||||
config['ui']['display']['type'] = 'waveshare2in13g'
|
||||
|
||||
elif config['ui']['display']['type'] in ('ws_213bc', 'ws213bc', 'waveshare2in13bc', 'waveshare_213bc', 'waveshare213bc'):
|
||||
config['ui']['display']['type'] = 'waveshare2in13bc'
|
||||
|
||||
@ -339,15 +342,18 @@ def load_config(args):
|
||||
elif config['ui']['display']['type'] in 'waveshare2in13b_v3':
|
||||
config['ui']['display']['type'] = 'waveshare2in13b_v3'
|
||||
|
||||
elif config['ui']['display']['type'] in 'waveshare2in23g':
|
||||
config['ui']['display']['type'] = 'waveshare2in23g'
|
||||
|
||||
elif config['ui']['display']['type'] in 'waveshare2in36g':
|
||||
config['ui']['display']['type'] = 'waveshare2in36g'
|
||||
|
||||
elif config['ui']['display']['type'] in 'waveshare2in66':
|
||||
config['ui']['display']['type'] = 'waveshare2in66'
|
||||
|
||||
elif config['ui']['display']['type'] in 'waveshare2in66b':
|
||||
config['ui']['display']['type'] = 'waveshare2in66b'
|
||||
|
||||
elif config['ui']['display']['type'] in 'waveshare2in66g':
|
||||
config['ui']['display']['type'] = 'waveshare2in66g'
|
||||
|
||||
elif config['ui']['display']['type'] in 'waveshare3in0g':
|
||||
config['ui']['display']['type'] = 'waveshare3in0g'
|
||||
|
||||
|
@ -1,60 +0,0 @@
|
||||
[build-system]
|
||||
requires = ["setuptools"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "pwnagotchi"
|
||||
dynamic = ["version"]
|
||||
dependencies = [
|
||||
"Pillow",
|
||||
"PyYAML",
|
||||
"RPi.GPIO",
|
||||
"file-read-backwards",
|
||||
"flask",
|
||||
"flask-cors",
|
||||
"flask-wtf",
|
||||
"gast",
|
||||
"gym",
|
||||
"inky",
|
||||
"pycryptodome",
|
||||
"pydrive2",
|
||||
"python-dateutil",
|
||||
"requests",
|
||||
"rpi_hardware_pwm",
|
||||
"scapy",
|
||||
"shimmy",
|
||||
"smbus2",
|
||||
"spidev",
|
||||
"stable_baselines3",
|
||||
"toml",
|
||||
"torch",
|
||||
"torchvision",
|
||||
"tweepy",
|
||||
"websockets"
|
||||
]
|
||||
requires-python = ">=3.9"
|
||||
authors = [
|
||||
{name = "Evilsocket", email = "evilsocket@gmail.com"},
|
||||
{name = "Jayofelony", email = "oudshoorn.jeroen@gmail.com"}
|
||||
]
|
||||
maintainers = [
|
||||
{name = "Jayofelony", email = "oudshoorn.jeroen@gmail.com"}
|
||||
]
|
||||
description = "(⌐■_■) - Deep Reinforcement Learning instrumenting bettercap for WiFI pwning."
|
||||
readme = "README.md"
|
||||
license = {file = "LICENSE.md"}
|
||||
classifiers = [
|
||||
'Programming Language :: Python :: 3',
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||
'Environment :: Console',
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
Homepage = "https://pwnagotchi.ai/"
|
||||
Documentation = "https://pwnagotchi.ai/"
|
||||
Repository = "https://github.com/jayofelony/pwnagotchi-bookworm"
|
||||
"Bug Tracker" = "https://github.com/jayofelony/pwnagotchi-bookworm/issues"
|
||||
|
||||
[project.scripts]
|
||||
pwnagotchi_cli = "bin.pwnagotchi:pwnagotchi_cli"
|
Reference in New Issue
Block a user