Compare commits

..

27 Commits

Author SHA1 Message Date
17f04f7506 Merge pull request #318
Added DNS check to plugins command
2025-01-27 10:24:45 +01:00
76c4888e88 Merge pull request #319
Update gdrivesync.py
2025-01-27 10:23:58 +01:00
d44b8d02b6 Merge remote-tracking branch 'origin/noai' into noai 2025-01-27 10:23:05 +01:00
02454597b2 Version 2.9.5.3
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-27 10:22:55 +01:00
cb207d4d70 Update gdrivesync.py
Updated backup items

Signed-off-by: findingmoist <128169791+findingmoist@users.noreply.github.com>
2025-01-25 20:06:15 -05:00
7b9150af6b Merge branch 'jayofelony:noai' into noai 2025-01-25 23:02:21 +00:00
8787c1bdd3 Update cmd.py
Signed-off-by: wpa-2 <9049886+wpa-2@users.noreply.github.com>
2025-01-25 23:02:06 +00:00
ec93838b7a Update defaults.toml 2025-01-25 17:26:31 +01:00
f6d5a481bb Removed unused import
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-24 23:48:38 +01:00
eee3eb962b Small changes on pisugarx.py
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-24 23:48:25 +01:00
847e9f5908 Enable auto-update by default now.
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-24 23:47:58 +01:00
af1544535c Merge pull request #316 from wlmh110/noai
Update pisugarx.py
2025-01-24 09:41:50 +01:00
0fbf209881 Update pisugarx.py
Complete the basic information retrieval for the PiSugar power module without the need for additional installation of PiSugar-server:
1. Automatically determine the model of PiSugar in use.
2. Automatically initialize the power module.
3. Retrieve the battery level and charging status.
2025-01-24 15:16:51 +08:00
cf14f3f663 Another fix for bt-tether
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-21 17:30:06 +01:00
948fe89ce6 Another fix for bt-tether
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-21 14:37:02 +01:00
8d1a5babe8 Version 2.9.5.2 will be next
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-20 21:30:58 +01:00
042d5ba765 Change in defaults for PwnDroid.
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-20 21:13:17 +01:00
58857058a4 Revert "PwnDroid, new plugin for the companion app on Android to share GPS data from your Android phone."
This reverts commit 0e06d3bd76.
2025-01-20 21:11:40 +01:00
5e6443ae58 Merge remote-tracking branch 'origin/noai' into noai 2025-01-20 21:11:14 +01:00
0e06d3bd76 PwnDroid, new plugin for the companion app on Android to share GPS data from your Android phone.
Signed-off-by: Jeroen Oudshoorn <oudshoorn.jeroen@gmail.com>
2025-01-20 21:10:46 +01:00
64f7c6e1e5 Merge pull request #311 from fmatray/noai
Web redirections for GRID, OHCAPI and Wigle
2025-01-20 19:18:10 +01:00
8442ce93be Update ohcapi.py
version update

Signed-off-by: Frédéric <fmatray@users.noreply.github.com>
2025-01-20 15:43:55 +01:00
730fa7dc8e Update wigle.py
version update

Signed-off-by: Frédéric <fmatray@users.noreply.github.com>
2025-01-20 15:43:35 +01:00
0959140098 Update grid.py
Rediction to https://opwngrid.xyz in the plugins' page

Signed-off-by: Frédéric <fmatray@users.noreply.github.com>
2025-01-20 15:41:49 +01:00
7c4764bff8 Update ohcapi.py
add a web hook to redirect to onlinehashcrack

Signed-off-by: Frédéric <fmatray@users.noreply.github.com>
2025-01-20 15:30:00 +01:00
e179165850 Update wigle.py
Signed-off-by: Frédéric <fmatray@users.noreply.github.com>
2025-01-20 15:28:46 +01:00
0140a1fc97 Update wigle.py
add a redirection to wiggle.net

Signed-off-by: Frédéric <fmatray@users.noreply.github.com>
2025-01-20 15:27:54 +01:00
10 changed files with 458 additions and 29 deletions

View File

@ -1 +1 @@
__version__ = '2.9.5.1' __version__ = '2.9.5.3'

View File

@ -19,8 +19,8 @@ main.custom_plugins = "/usr/local/share/pwnagotchi/custom-plugins/"
main.plugins.auto-tune.enabled = true main.plugins.auto-tune.enabled = true
main.plugins.auto-update.enabled = false main.plugins.auto-update.enabled = true
main.plugins.auto-update.install = false main.plugins.auto-update.install = true
main.plugins.auto-update.interval = 1 main.plugins.auto-update.interval = 1
main.plugins.bt-tether.enabled = false main.plugins.bt-tether.enabled = false
@ -60,6 +60,7 @@ main.plugins.ohcapi.receive_email = "yes"
main.plugins.pwndroid.enabled = false main.plugins.pwndroid.enabled = false
main.plugins.pwndroid.display = false # show coords on display main.plugins.pwndroid.display = false # show coords on display
main.plugins.pwndroid.display_altitude = false # show altitude on display
main.plugins.pisugarx.enabled = false main.plugins.pisugarx.enabled = false
main.plugins.pisugarx.rotation = false main.plugins.pisugarx.rotation = false

View File

@ -1,10 +1,9 @@
# Handles the commandline stuff
import os import os
import logging import logging
import glob import glob
import re import re
import shutil import shutil
import socket # <-- Added for DNS check
from fnmatch import fnmatch from fnmatch import fnmatch
from pwnagotchi.utils import download_file, unzip, save_config, parse_version, md5 from pwnagotchi.utils import download_file, unzip, save_config, parse_version, md5
from pwnagotchi.plugins import default_path from pwnagotchi.plugins import default_path
@ -164,8 +163,8 @@ def upgrade(args, config, pattern='*'):
installed_version = _extract_version(filename) installed_version = _extract_version(filename)
if installed_version and available_version: if installed_version and available_version:
if available_version <= installed_version: if available_version <= installed_version:
continue continue
else: else:
continue continue
@ -348,12 +347,34 @@ def _analyse_dir(path):
return results return results
def _check_internet():
"""
Simple DNS check to verify that we can resolve a common hostname.
Returns True if DNS resolution succeeds, False otherwise.
"""
try:
socket.gethostbyname('google.com')
return True
except:
return False
def update(config): def update(config):
""" """
Updates the database Updates the database
""" """
global SAVE_DIR global SAVE_DIR
if not _check_internet():
logging.error("No internet connection or DNS not working. Please follow these instructions:")
logging.error("https://github.com/jayofelony/pwnagotchi/wiki/Step-2-Connecting")
print("No internet/DNS. Please follow these instructions:")
print("https://github.com/jayofelony/pwnagotchi/wiki/Step-2-Connecting")
return 1
else:
logging.info("Internet detected - Please run sudo pwnagotchi plugins list")
print("Internet detected - Please run sudo pwnagotchi plugins list")
urls = config['main']['custom_plugin_repos'] urls = config['main']['custom_plugin_repos']
if not urls: if not urls:
logging.info('No plugin repositories configured.') logging.info('No plugin repositories configured.')
@ -393,3 +414,4 @@ def update(config):
logging.error('Error while updating plugins: %s', ex) logging.error('Error while updating plugins: %s', ex)
rc = 1 rc = 1
return rc return rc

View File

@ -41,15 +41,15 @@ class BTTether(plugins.Plugin):
'bluetooth.type', 'panu', 'bluetooth.type', 'panu',
'bluetooth.bdaddr', f'{mac}', 'bluetooth.bdaddr', f'{mac}',
'ipv4.method', 'manual', 'ipv4.method', 'manual',
'ipv4.dns', '8.8.8.8;1.1.1.1;', 'ipv4.dns', '8.8.8.8 1.1.1.1',
'ipv4.addresses', f'{address}', 'ipv4.addresses', f'{address}/24',
'ipv4.gateway', f'{gateway}', 'ipv4.gateway', f'{gateway}',
'ipv4.route-metric', '100' 'ipv4.route-metric', '100'
], check=True) ], check=True)
subprocess.run(['nmcli', 'connection', 'reload'], check=True) subprocess.run(['nmcli', 'connection', 'reload'], check=True)
subprocess.run(['nmcli', 'connection', 'up', f'{phone_name}'], check=True) subprocess.run(['nmcli', 'connection', 'up', f'{phone_name}'], check=True)
except Exception as e: except Exception as e:
logging.debug(f"[BT-Tether] Failed to connect to device: {e}") logging.error(f"[BT-Tether] Failed to connect to device: {e}")
logging.error(f"[BT-Tether] Failed to connect to device: have you enabled bluetooth tethering on your phone?") logging.error(f"[BT-Tether] Failed to connect to device: have you enabled bluetooth tethering on your phone?")
self.ready = True self.ready = True

View File

@ -13,8 +13,8 @@ import zipfile
class GdriveSync(plugins.Plugin): class GdriveSync(plugins.Plugin):
__author__ = '@jayofelony' __author__ = '@jayofelony & Moist'
__version__ = '1.2' __version__ = '1.4'
__license__ = 'GPL3' __license__ = 'GPL3'
__description__ = 'A plugin to backup various pwnagotchi files and folders to Google Drive. Once every hour from loading plugin.' __description__ = 'A plugin to backup various pwnagotchi files and folders to Google Drive. Once every hour from loading plugin.'
@ -26,12 +26,15 @@ class GdriveSync(plugins.Plugin):
self.status = StatusFile('/root/.gdrive-backup') self.status = StatusFile('/root/.gdrive-backup')
self.backup = True self.backup = True
self.backupfiles = [ self.backupfiles = [
'/root/brain.nn',
'/root/brain.json', '/root/brain.json',
'/root/.api-report.json', '/root/.api-report.json',
'/root/handshakes', '/home/pi/handshakes',
'/root/peers', '/root/peers',
'/etc/pwnagotchi' '/etc/pwnagotchi',
'.etc/profile/',
'/usr/local/share/pwnagotchi/custom-plugins',
'/boot/firmware/config.txt',
'/boot/firmware/cmdline.txt'
] ]
def on_loaded(self): def on_loaded(self):

View File

@ -44,7 +44,7 @@ def parse_pcap(filename):
class Grid(plugins.Plugin): class Grid(plugins.Plugin):
__author__ = 'evilsocket@gmail.com' __author__ = 'evilsocket@gmail.com'
__version__ = '1.0.1' __version__ = '1.1.0'
__license__ = 'GPL3' __license__ = 'GPL3'
__description__ = 'This plugin signals the unit cryptographic identity and list of pwned networks and list of pwned ' \ __description__ = 'This plugin signals the unit cryptographic identity and list of pwned networks and list of pwned ' \
'networks to opwngrid.xyz ' 'networks to opwngrid.xyz '
@ -69,6 +69,11 @@ class Grid(plugins.Plugin):
def on_loaded(self): def on_loaded(self):
logging.info("grid plugin loaded.") logging.info("grid plugin loaded.")
def on_webhook(self, path, request):
from flask import make_response, redirect
response = make_response(redirect("https://opwngrid.xyz", code=302))
return response
def set_reported(self, reported, net_id): def set_reported(self, reported, net_id):
if net_id not in reported: if net_id not in reported:
reported.append(net_id) reported.append(net_id)

View File

@ -10,7 +10,7 @@ from json.decoder import JSONDecodeError
class ohcapi(plugins.Plugin): class ohcapi(plugins.Plugin):
__author__ = 'Rohan Dayaram' __author__ = 'Rohan Dayaram'
__version__ = '1.0.3' __version__ = '1.1.0'
__license__ = 'GPL3' __license__ = 'GPL3'
__description__ = 'Uploads WPA/WPA2 handshakes to OnlineHashCrack.com using the new API (V2), no dashboard.' __description__ = 'Uploads WPA/WPA2 handshakes to OnlineHashCrack.com using the new API (V2), no dashboard.'
@ -45,6 +45,11 @@ class ohcapi(plugins.Plugin):
self.ready = True self.ready = True
logging.info("OHC NewAPI: Plugin loaded and ready.") logging.info("OHC NewAPI: Plugin loaded and ready.")
def on_webhook(self, path, request):
from flask import make_response, redirect
response = make_response(redirect("https://www.onlinehashcrack.com", code=302))
return response
def on_internet_available(self, agent): def on_internet_available(self, agent):
""" """
Called once when the internet becomes available. Called once when the internet becomes available.

View File

@ -6,9 +6,405 @@ import pwnagotchi.ui.fonts as fonts
import pwnagotchi.plugins as plugins import pwnagotchi.plugins as plugins
import pwnagotchi import pwnagotchi
import time import time
from pisugar import * import smbus
from flask import abort from flask import abort
from flask import render_template_string from flask import render_template_string
from collections import deque
import threading
PiSugar_addresses = {
"PiSugar2": 0x75, # PiSugar2\2Plus
"PiSugar3": 0x57, # PiSugar3\3Plus
"PiSugar2 RTC": 0x32 # PiSugar2\2Plus RTC
}
curve1200 = [
(4.16, 100.0),
(4.05, 95.0),
(4.00, 80.0),
(3.92, 65.0),
(3.86, 40.0),
(3.79, 25.5),
(3.66, 10.0),
(3.52, 6.5),
(3.49, 3.2),
(3.1, 0.0),
]
curve1200_3= [
(4.2, 100.0), # 高电量阶段 (100%)
(4.0, 80.0), # 中电量阶段 (80%)
(3.7, 60.0), # 中电量阶段 (60%)
(3.5, 20.0), # 低电量阶段 (20%)
(3.1, 0.0) # 电量耗尽 (0%)
]
curve5000 = [
(4.10, 100.0),
(4.05, 95.0),
(3.90, 88.0),
(3.80, 77.0),
(3.70, 65.0),
(3.62, 55.0),
(3.58, 49.0),
(3.49, 25.6),
(3.32, 4.5),
(3.1, 0.0),
]
class PiSugarServer:
def __init__(self):
"""
PiSugar initialization, if unable to connect to any version of PiSugar, return false
"""
self._bus = smbus.SMBus(1)
self.modle = None
self.i2creg = []
self.address = 0
self.battery_voltage = 0
self.voltage_history = deque(maxlen=10)
self.battery_level = 0
self.battery_charging = 0
self.temperature = 0
self.power_plugged = False
self.allow_charging = True
while self.modle is None:
if self.check_device(PiSugar_addresses["PiSugar2"]) is not None:
self.address = PiSugar_addresses["PiSugar2"]
if self.check_device(PiSugar_addresses["PiSugar2"], 0Xc2) != 0:
self.modle = "PiSugar2Plus"
else:
self.modle = "PiSugar2"
self.device_init()
elif self.check_device(PiSugar_addresses["PiSugar3"]) is not None:
self.modle = 'PiSugar3'
self.address = PiSugar_addresses["PiSugar3"]
else:
self.modle = None
logging.error(
"No PiSugar device was found. Please check if the PiSugar device is powered on.")
time.sleep(5)
# self.update_value()
self.start_timer()
while len(self.i2creg) < 256:
time.sleep(1)
def start_timer(self):
# 创建一个线程来执行定时函数
timer_thread = threading.Thread(target=self.update_value)
timer_thread.daemon = True # 设置为守护线程,主程序退出时自动结束
timer_thread.start()
def update_value(self):
"""每三秒更新pisugar状态包括触发自动关机"""
while True:
try:
self.i2creg = []
for i in range(0, 256, 32):
# 计算当前读取的起始寄存器地址
current_register = 0 + i
# 计算当前读取的数据长度
current_length = min(32, 256 - i)
# 读取数据块
chunk = self._bus.read_i2c_block_data(
self.address, current_register, current_length)
# 将读取的数据块添加到结果列表中
self.i2creg.extend(chunk)
time.sleep(0.1)
logging.debug(f"Data length: {len(self.i2creg)}")
logging.debug(f"Data: {self.i2creg}")
if self.modle == 'PiSugar3':
low = self.i2creg[0x23]
high = self.i2creg[0x22]
self.battery_voltage = (((high << 8) + low) / 1000)
self.temperature = self.i2creg[0x04]-40
ctr1 = self.i2creg[0x02] # 读取控制寄存器 1
self.power_plugged = (ctr1 & (1 << 7)) != 0 # 检查电源是否插入
self.allow_charging = (ctr1 & (1 << 6)) != 0 # 检查是否允许充电
elif self.modle == 'PiSugar2':
high = self.i2creg[0xa3]
low = self.i2creg[0xa2]
self.battery_voltage = (2600.0 - (((high | 0b11000000) << 8) + low) * 0.26855) / \
1000.0 if high & 0x20 else (
2600.0 + (((high & 0x1f) << 8) + low) * 0.26855) / 1000.0
self.power_plugged = (self.i2creg[0x55] & 0b00010000) != 0
elif self.modle == 'PiSugar2Plus':
low = self.i2creg[0xd0]
high = self.i2creg[0xd1]
self.battery_voltage = (
(((high & 0b00111111) << 8) + low) * 0.26855 + 2600.0)/1000
self.power_plugged = self.i2creg[0xdd] == 0x1f
self.voltage_history.append(self.battery_voltage)
self.battery_level=self.convert_battery_voltage_to_level()
time.sleep(3)
except:
logging.error(f"read error")
time.sleep(3)
def check_device(self, address, reg=0):
"""Check if a device is present at the specified address"""
try:
return self._bus.read_byte_data(address, reg)
except OSError as e:
logging.debug(f"Device not found at address {address}: {e}")
return None
def device_init(self):
if self.modle == "PiSugar2Plus":
'''初始化GPIO'''
self._bus.write_byte_data(self.address, 0x52, self._bus.read_byte_data(
self.address, 0x52) | 0b00000010)
self._bus.write_byte_data(self.address, 0x54, self._bus.read_byte_data(
self.address, 0x54) | 0b00000010)
self._bus.write_byte_data(self.address, 0x52, self._bus.read_byte_data(
self.address, 0x52) | 0b00000100)
self._bus.write_byte_data(self.address, 0x29, self._bus.read_byte_data(
self.address, 0x29) & 0b10111111)
self._bus.write_byte_data(self.address, 0x52, self._bus.read_byte_data(
self.address, 0x52) & 0b10011111 | 0b01000000)
self._bus.write_byte_data(self.address, 0xc2, self._bus.read_byte_data(
self.address, 0xc2) | 0b00010000)
logging.debug(f"PiSugar2Plus GPIO 初始化完毕")
'''Init boost intensity, 0x3f*50ma, 3A'''
self._bus.write_byte_data(self.address, 0x30, self._bus.read_byte_data(
self.address, 0x30) & 0b11000000 | 0x3f)
logging.debug(f"PiSugar2Plus 电流设置完毕")
elif self.modle == "PiSugar2":
'''初始化GPIO'''
self._bus.write_byte_data(self.address, 0x51, (self._bus.read_byte_data(
self.address, 0x51) & 0b11110011) | 0b00000100)
self._bus.write_byte_data(self.address, 0x53, self._bus.read_byte_data(
self.address, 0x53) | 0b00000010)
self._bus.write_byte_data(self.address, 0x51, (self._bus.read_byte_data(
self.address, 0x51) & 0b11001111) | 0b00010000)
self._bus.write_byte_data(self.address, 0x26, self._bus.read_byte_data(
self.address, 0x26) & 0b10110000)
self._bus.write_byte_data(self.address, 0x52, (self._bus.read_byte_data(
self.address, 0x52) & 0b11110011) | 0b00000100)
self._bus.write_byte_data(self.address, 0x53, (self._bus.read_byte_data(
self.address, 0x53) & 0b11101111) | 0b00010000)
logging.debug(f"PiSugar2 GPIO 初始化完毕")
pass
def convert_battery_voltage_to_level(self):
"""
将电池电压转换为电量百分比。
:param voltage: 当前电池电压
:param curve: 电池阈值曲线,格式为 [(电压1, 电量1), (电压2, 电量2), ...]
:return: 电量百分比
"""
if (self.modle == "PiSugar2Plus") | (self.modle == "PiSugar3Plus"):
curve = curve5000
elif self.modle == "PiSugar2":
curve = curve1200
elif self.modle == "PiSugar3":
curve = curve1200_3
# 将当前电压加入历史记录
# 如果历史记录不足 5 次,直接返回平均值(避免截尾后无有效数据)
if len(self.voltage_history) < 5:
avg_voltage = sum(self.voltage_history) / len(self.voltage_history)
else:
# 排序后去掉最高 2 个和最低 2 个
sorted_history = sorted(self.voltage_history)
trimmed_history = sorted_history[2:-2] # 去掉前两个和后两个
avg_voltage = sum(trimmed_history) / len(trimmed_history) # 计算截尾平均
# 遍历电池曲线的每一段
for (v1, p1), (v2, p2) in zip(curve, curve[1:]):
# 如果电压在当前区间内
if v2 <= avg_voltage <= v1:
# 使用线性插值计算电量
return p2 + (p1 - p2) * (avg_voltage - v2) / (v1 - v2)
# 如果电压超出曲线范围,返回最低或最高电量
return curve[-1][1] if avg_voltage < curve[-1][0] else curve[0][1]
def get_version(self):
"""
Get the firmware version of the PiSugar3.
If not PiSugar3, return None
:return: Version string or None
"""
if self.modle == 'PiSugar3':
try:
return bytes(self.i2creg[0xe2:0xee]).decode('ascii')
except OSError as e:
logging.error(f"Failed to read version from PiSugar3: {e}")
return None
return None
def get_model(self):
"""
Get the model of the PiSugar hardware.
:return: Model string.
"""
return self.modle
def get_battery_level(self):
"""
Get the current battery level in percentage.
:return: Battery level as a percentage (0-100).
"""
return self.battery_level
def get_battery_voltage(self):
"""
Get the current battery voltage.
:return: Battery voltage in volts.
"""
return self.battery_voltage
def get_battery_current(self):
"""
Get the current battery current.
:return: Battery current in amperes.
"""
pass
def get_battery_allow_charging(self):
"""
Check if battery charging is allowed.
:return: True if charging is allowed, False otherwise.
"""
return self.allow_charging
def get_battery_charging_range(self):
"""
Get the battery charging range.
:return: Charging range string.
"""
pass
def get_battery_full_charge_duration(self):
"""
Get the duration of keeping the battery charging when full.
:return: Duration in seconds.
"""
pass
def get_battery_safe_shutdown_level(self):
"""
Get the safe shutdown level for the battery.
:return: Safe shutdown level as a percentage.
"""
pass
def get_battery_safe_shutdown_delay(self):
"""
Get the safe shutdown delay.
:return: Delay in seconds.
"""
pass
def get_battery_auto_power_on(self):
"""
Check if auto power on is enabled.
:return: True if enabled, False otherwise.
"""
pass
def get_battery_soft_poweroff(self):
"""
Check if soft power off is enabled.
:return: True if enabled, False otherwise.
"""
pass
def get_system_time(self):
"""
Get the system time.
:return: System time string.
"""
pass
def get_rtc_adjust_ppm(self):
"""
Get the RTC adjust PPM.
:return: RTC adjust PPM value.
"""
pass
def get_rtc_alarm_repeat(self):
"""
Get the RTC alarm repeat setting.
:return: RTC alarm repeat string.
"""
pass
def get_tap_enable(self, tap):
"""
Check if a specific tap (single, double, long) is enabled.
:param tap: Type of tap ('single', 'double', 'long').
:return: True if enabled, False otherwise.
"""
pass
def get_tap_shell(self, tap):
"""
Get the shell command associated with a specific tap.
:param tap: Type of tap ('single', 'double', 'long').
:return: Shell command string.
"""
pass
def get_anti_mistouch(self):
"""
Check if anti-mistouch protection is enabled.
:return: True if enabled, False otherwise.
"""
pass
def get_temperature(self):
"""
Get the current temperature.
:return: Temperature in degrees Celsius.
"""
return self.temperature
def get_battery_power_plugged(self):
"""
Check if the battery is plugged in.
:return: True if plugged in, False otherwise.
"""
return self.power_plugged
def get_battery_charging(self):
"""
Check if the battery is currently charging.
:return: True if charging, False otherwise.
"""
pass
def rtc_web(self):
"""
Synchronize RTC with web time.
"""
pass
class PiSugar(plugins.Plugin): class PiSugar(plugins.Plugin):
__author__ = "jayofelony" __author__ = "jayofelony"
@ -26,8 +422,7 @@ class PiSugar(plugins.Plugin):
self.options = dict() self.options = dict()
self.ps = None self.ps = None
try: try:
conn, event_conn = connect_tcp() self.ps = PiSugarServer()
self.ps = PiSugarServer(conn, event_conn)
except Exception as e: except Exception as e:
# Log at debug to avoid clutter since it might be a false positive # Log at debug to avoid clutter since it might be a false positive
logging.debug("[PiSugarX] Unable to establish connection: %s", repr(e)) logging.debug("[PiSugarX] Unable to establish connection: %s", repr(e))
@ -69,11 +464,6 @@ class PiSugar(plugins.Plugin):
def on_ready(self, agent): def on_ready(self, agent):
self.ready = True self.ready = True
self._agent = agent self._agent = agent
led_amount = self.safe_get(self.ps.get_battery_led_amount, default=0)
if led_amount == 2:
self.is_new_model = True
else:
self.is_new_model = False
def on_internet_available(self, agent): def on_internet_available(self, agent):
self._agent = agent self._agent = agent
@ -92,7 +482,6 @@ class PiSugar(plugins.Plugin):
battery_level = self.safe_get(self.ps.get_battery_level, default='N/A') battery_level = self.safe_get(self.ps.get_battery_level, default='N/A')
battery_voltage = self.safe_get(self.ps.get_battery_voltage, default='N/A') battery_voltage = self.safe_get(self.ps.get_battery_voltage, default='N/A')
battery_current = self.safe_get(self.ps.get_battery_current, default='N/A') battery_current = self.safe_get(self.ps.get_battery_current, default='N/A')
battery_led_amount = self.safe_get(self.ps.get_battery_led_amount, default='N/A') if model == 'Pisugar 2' else 'Not supported'
battery_allow_charging = self.safe_get(self.ps.get_battery_allow_charging, default=False) battery_allow_charging = self.safe_get(self.ps.get_battery_allow_charging, default=False)
battery_charging_range = self.safe_get(self.ps.get_battery_charging_range, default='N/A') if self.is_new_model or model == 'Pisugar 3' else 'Not supported' battery_charging_range = self.safe_get(self.ps.get_battery_charging_range, default='N/A') if self.is_new_model or model == 'Pisugar 3' else 'Not supported'
battery_full_charge_duration = getattr(self.ps, 'get_battery_full_charge_duration', lambda: 'N/A')() battery_full_charge_duration = getattr(self.ps, 'get_battery_full_charge_duration', lambda: 'N/A')()
@ -172,7 +561,6 @@ class PiSugar(plugins.Plugin):
<tr><td>Battery Level</td><td>{battery_level}%</td></tr> <tr><td>Battery Level</td><td>{battery_level}%</td></tr>
<tr><td>Battery Voltage</td><td>{battery_voltage}V</td></tr> <tr><td>Battery Voltage</td><td>{battery_voltage}V</td></tr>
<tr><td>Battery Current</td><td>{battery_current}A</td></tr> <tr><td>Battery Current</td><td>{battery_current}A</td></tr>
<tr><td>Battery LED Amount</td><td>{battery_led_amount}</td></tr>
<tr><td>Battery Allow Charging</td><td>{"Yes" if battery_allow_charging and self.is_new_model else "No"}</td></tr> <tr><td>Battery Allow Charging</td><td>{"Yes" if battery_allow_charging and self.is_new_model else "No"}</td></tr>
<tr><td>Battery Charging Range</td><td>{battery_charging_range}</td></tr> <tr><td>Battery Charging Range</td><td>{battery_charging_range}</td></tr>
<tr><td>Duration of Keep Charging When Full</td><td>{battery_full_charge_duration} seconds</td></tr> <tr><td>Duration of Keep Charging When Full</td><td>{battery_full_charge_duration} seconds</td></tr>
@ -284,3 +672,4 @@ class PiSugar(plugins.Plugin):
f"[PiSugarX] Empty battery (<= {safe_shutdown_level}%): shutting down" f"[PiSugarX] Empty battery (<= {safe_shutdown_level}%): shutting down"
) )
ui.update(force=True, new_data={"status": "Battery exhausted, bye ..."}) ui.update(force=True, new_data={"status": "Battery exhausted, bye ..."})

View File

@ -106,7 +106,7 @@ def _send_to_wigle(lines, api_key, donate=True, timeout=30):
class Wigle(plugins.Plugin): class Wigle(plugins.Plugin):
__author__ = "Dadav and updated by Jayofelony" __author__ = "Dadav and updated by Jayofelony"
__version__ = "3.0.1" __version__ = "3.1.0"
__license__ = "GPL3" __license__ = "GPL3"
__description__ = "This plugin automatically uploads collected WiFi to wigle.net" __description__ = "This plugin automatically uploads collected WiFi to wigle.net"
@ -127,6 +127,11 @@ class Wigle(plugins.Plugin):
self.ready = True self.ready = True
logging.info("WIGLE: ready") logging.info("WIGLE: ready")
def on_webhook(self, path, request):
from flask import make_response, redirect
response = make_response(redirect("https://www.wigle.net/", code=302))
return response
def on_internet_available(self, agent): def on_internet_available(self, agent):
""" """

View File

@ -1,7 +1,6 @@
import os import os
import logging import logging
import requests import requests
import subprocess
from datetime import datetime from datetime import datetime
from threading import Lock from threading import Lock
from pwnagotchi.utils import StatusFile, remove_whitelisted from pwnagotchi.utils import StatusFile, remove_whitelisted