mirror of
https://github.com/markqvist/Sideband.git
synced 2026-04-27 22:25:39 +00:00
Compare commits
13 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cba08b6999 | ||
|
|
9f0d776e3f | ||
|
|
5705e24dde | ||
|
|
39f00554a8 | ||
|
|
fcc0341fe9 | ||
|
|
04908eb45b | ||
|
|
73b9bd032f | ||
|
|
6f8f4351f6 | ||
|
|
cd323c9ca8 | ||
|
|
e798bac4c7 | ||
|
|
2529a70339 | ||
|
|
75373f3aa0 | ||
|
|
73b0f6d4b2 |
9 changed files with 339 additions and 71 deletions
1
Makefile
1
Makefile
|
|
@ -79,6 +79,7 @@ prepare_win_pkg: clean build_spkg
|
|||
rm build/winpkg/sbapp/buildozer.spec
|
||||
cp winbuild.bat build/
|
||||
mv build/winpkg build/sideband_sources
|
||||
chmod -R a+rw build/sideband_sources
|
||||
cd build; zip -r winbuild.zip sideband_sources winbuild.bat
|
||||
mv build/winbuild.zip dist/winbuild.zip
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ Sideband provides many useful and interesting functions, such as:
|
|||
- Remote **telemetry querying**, with strong, secure and cryptographically robust authentication and control.
|
||||
- **Plugin system** that allows you to easily **create your own commands**, services and telemetry sources.
|
||||
|
||||
Sideband is fully compatible with other LXMF clients, such as [MeshChat](https://github.com/liamcottle/reticulum-meshchat), and [Nomad Network](https://github.com/markqvist/nomadnet). The Nomad Network client also allows you to easily host Propagation Nodes for your LXMF network, and more.
|
||||
Sideband is fully compatible with other LXMF clients, such as [MeshChatX](https://git.quad4.io/RNS-Things/MeshChatX), and [Nomad Network](https://github.com/markqvist/nomadnet). The Nomad Network client also allows you to easily host Propagation Nodes for your LXMF network, and more.
|
||||
|
||||
# Installation
|
||||
|
||||
|
|
|
|||
152
docs/example_plugins/raspi_telemetry.py
Normal file
152
docs/example_plugins/raspi_telemetry.py
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# This is a basic Raspberry Pi telemetry plugin
|
||||
# example that you can build upon to
|
||||
# implement your own telemetry plugins.
|
||||
|
||||
import os
|
||||
import RNS
|
||||
import time
|
||||
import psutil
|
||||
import shutil
|
||||
from threading import Thread
|
||||
import urllib.request, json
|
||||
|
||||
class RasPiTelemetryPlugin(SidebandTelemetryPlugin):
|
||||
plugin_name = "raspi_telemetry"
|
||||
|
||||
def start(self):
|
||||
# Do any initialisation work here
|
||||
RNS.log("Raspberry Pi Telemetry plugin starting...")
|
||||
self.initialise_values()
|
||||
|
||||
self.power_stats = False
|
||||
self.storage_stats = True
|
||||
self.target_disk = {"blkid": "mmcblk0p2", "label": "SD Card"}
|
||||
self.should_run = True
|
||||
|
||||
self.update_thread = Thread(target=self.update_job, daemon=True)
|
||||
self.update_thread.start()
|
||||
|
||||
# And finally call start on superclass
|
||||
super().start()
|
||||
|
||||
def stop(self):
|
||||
# Do any teardown work here
|
||||
self.should_run = False
|
||||
|
||||
# And finally call stop on superclass
|
||||
super().stop()
|
||||
|
||||
def initialise_values(self):
|
||||
self.battery_percent = None
|
||||
self.power_production = None
|
||||
self.power_consumption = None
|
||||
self.battery_charging = None
|
||||
self.battery_temperature = None
|
||||
self.uptime = None
|
||||
|
||||
def update_job(self):
|
||||
while self.should_run:
|
||||
try:
|
||||
# Update uptime
|
||||
self.uptime = RNS.prettytime(time.time()-psutil.boot_time())
|
||||
|
||||
# Update power values if enabled
|
||||
if self.power_stats:
|
||||
with urllib.request.urlopen("http://some_host/status.json") as url:
|
||||
data = json.loads(url.read().decode())
|
||||
self.power_production = data["solar_yield"]
|
||||
self.power_consumption = data["inverter_load"]+data["dc_consumption"]
|
||||
self.battery_charging = data["battery_current"] >= 0.0
|
||||
self.battery_charge = data["battery_charge"]
|
||||
self.battery_temperature = data["battery_temperature"]
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error while updating plugin telemetry: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
time.sleep(15)
|
||||
|
||||
def update_telemetry(self, telemeter):
|
||||
if telemeter != None:
|
||||
|
||||
if self.power_stats:
|
||||
# Create power consumption sensor
|
||||
telemeter.synthesize("power_consumption")
|
||||
telemeter.sensors["power_consumption"].update_consumer(self.power_consumption, type_label="Power consumption")
|
||||
|
||||
# Create power production sensor
|
||||
telemeter.synthesize("power_production")
|
||||
telemeter.sensors["power_production"].update_producer(self.power_production, type_label="Solar production", custom_icon="solar-power-variant")
|
||||
|
||||
# Create battery sensor
|
||||
telemeter.synthesize("battery")
|
||||
telemeter.sensors["battery"].data = {"charge_percent": round(self.battery_charge, 1), "charging": self.battery_charging}
|
||||
|
||||
|
||||
# Create NVM sensor if enabled
|
||||
if self.storage_stats:
|
||||
mount_point = None
|
||||
for partition in psutil.disk_partitions(all=False):
|
||||
if self.target_disk["blkid"] in partition.device:
|
||||
mount_point = partition.mountpoint
|
||||
break
|
||||
|
||||
if mount_point:
|
||||
st = shutil.disk_usage(mount_point)
|
||||
telemeter.synthesize("nvm")
|
||||
telemeter.sensors["nvm"].update_entry(capacity=st.total, used=st.used, type_label=self.target_disk["label"])
|
||||
|
||||
# Create RAM sensors
|
||||
ms = psutil.virtual_memory()
|
||||
telemeter.synthesize("ram")
|
||||
telemeter.sensors["ram"].update_entry(capacity=ms.total, used=ms.used, type_label="RAM")
|
||||
|
||||
# Create CPU sensor
|
||||
a = psutil.getloadavg()
|
||||
cps = 0; cpms = 5
|
||||
for m in range(cpms):
|
||||
cps += psutil.cpu_percent()/100.0
|
||||
time.sleep(0.05)
|
||||
cp = cps/cpms
|
||||
|
||||
telemeter.synthesize("processor")
|
||||
telemeter.sensors["processor"].update_entry(current_load=cp, clock=round(psutil.cpu_freq().current*1e6, 0), load_avgs=[a[0], a[1], a[2]], type_label="CPU")
|
||||
|
||||
# Create custom sensor for uptime
|
||||
telemeter.synthesize("custom")
|
||||
telemeter.sensors["custom"].update_entry(self.uptime, type_label="Uptime is", custom_icon="timer-refresh-outline")
|
||||
|
||||
# Read temperature using built-in sensor
|
||||
try:
|
||||
cpu_temp_path = '/sys/class/thermal/thermal_zone0/temp'
|
||||
with open(cpu_temp_path) as f: temp = int(f.read().strip()) / 1000.0
|
||||
|
||||
telemeter.synthesize("temperature")
|
||||
telemeter.sensors["temperature"].data = {"c": round(temp, 2)}
|
||||
|
||||
except Exception as e: RNS.log(f"Getting temperature reading failed: {e}", RNS.LOG_ERROR)
|
||||
|
||||
# Network Interfaces
|
||||
try:
|
||||
for iface in os.listdir('/sys/class/net'):
|
||||
carrier = None
|
||||
speed = None
|
||||
|
||||
try:
|
||||
with open(f'/sys/class/net/{iface}/carrier') as f: carrier = int(f.read().strip()) == 1
|
||||
except FileNotFoundError: pass
|
||||
|
||||
if iface.startswith('eth') or iface.startswith('wlan'):
|
||||
try:
|
||||
with open(f'/sys/class/net/{iface}/speed') as f: speed = int(f.read().strip())
|
||||
except (FileNotFoundError, ValueError): pass
|
||||
|
||||
telemeter.synthesize("custom")
|
||||
speed_str = f" at {RNS.prettyspeed(speed*1e6)}" if speed else ""
|
||||
sensors_str = f"carrier{speed_str}" if carrier else "has no carrier"
|
||||
telemeter.sensors["custom"].update_entry(value=f"{sensors_str}", type_label=f"{iface}", custom_icon="lan" if carrier else "lan-disconnect")
|
||||
|
||||
except Exception as e: RNS.log(f"Getting network stats failed: {e}", RNS.LOG_DEBUG)
|
||||
|
||||
# Finally, tell Sideband what class in this
|
||||
# file is the actual plugin class.
|
||||
plugin_class = RasPiTelemetryPlugin
|
||||
119
docs/example_plugins/server_telemetry.py
Normal file
119
docs/example_plugins/server_telemetry.py
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
# This is a basic server telemetry plugin
|
||||
# example that you can build upon to
|
||||
# implement your own telemetry plugins.
|
||||
|
||||
import RNS
|
||||
import time
|
||||
import psutil
|
||||
import shutil
|
||||
from threading import Thread
|
||||
import urllib.request, json
|
||||
|
||||
class ServerTelemetryPlugin(SidebandTelemetryPlugin):
|
||||
plugin_name = "server_telemetry"
|
||||
|
||||
def start(self):
|
||||
# Do any initialisation work here
|
||||
RNS.log("Server Telemetry plugin starting...")
|
||||
self.initialise_values()
|
||||
|
||||
self.power_stats = False
|
||||
self.storage_stats = True
|
||||
self.target_disk = {"blkid": "mmcblk0p2", "label": "SD Card"}
|
||||
self.should_run = True
|
||||
|
||||
self.update_thread = Thread(target=self.update_job, daemon=True)
|
||||
self.update_thread.start()
|
||||
|
||||
# And finally call start on superclass
|
||||
super().start()
|
||||
|
||||
def stop(self):
|
||||
# Do any teardown work here
|
||||
self.should_run = False
|
||||
|
||||
# And finally call stop on superclass
|
||||
super().stop()
|
||||
|
||||
def initialise_values(self):
|
||||
self.battery_percent = None
|
||||
self.power_production = None
|
||||
self.power_consumption = None
|
||||
self.battery_charging = None
|
||||
self.battery_temperature = None
|
||||
self.uptime = None
|
||||
|
||||
def update_job(self):
|
||||
while self.should_run:
|
||||
try:
|
||||
# Update uptime
|
||||
self.uptime = RNS.prettytime(time.time()-psutil.boot_time())
|
||||
|
||||
# Update power values if enabled
|
||||
if self.power_stats:
|
||||
with urllib.request.urlopen("http://some_host/status.json") as url:
|
||||
data = json.loads(url.read().decode())
|
||||
self.power_production = data["solar_yield"]
|
||||
self.power_consumption = data["inverter_load"]+data["dc_consumption"]
|
||||
self.battery_charging = data["battery_current"] >= 0.0
|
||||
self.battery_charge = data["battery_charge"]
|
||||
self.battery_temperature = data["battery_temperature"]
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error while updating plugin telemetry: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
time.sleep(15)
|
||||
|
||||
def update_telemetry(self, telemeter):
|
||||
if telemeter != None:
|
||||
|
||||
if self.power_stats:
|
||||
# Create power consumption sensor
|
||||
telemeter.synthesize("power_consumption")
|
||||
telemeter.sensors["power_consumption"].update_consumer(self.power_consumption, type_label="Power consumption")
|
||||
|
||||
# Create power production sensor
|
||||
telemeter.synthesize("power_production")
|
||||
telemeter.sensors["power_production"].update_producer(self.power_production, type_label="Solar production", custom_icon="solar-power-variant")
|
||||
|
||||
# Create battery sensor
|
||||
telemeter.synthesize("battery")
|
||||
telemeter.sensors["battery"].data = {"charge_percent": round(self.battery_charge, 1), "charging": self.battery_charging}
|
||||
|
||||
|
||||
# Create NVM sensor if enabled
|
||||
if self.storage_stats:
|
||||
mount_point = None
|
||||
for partition in psutil.disk_partitions(all=False):
|
||||
if self.target_disk["blkid"] in partition.device:
|
||||
mount_point = partition.mountpoint
|
||||
break
|
||||
|
||||
if mount_point:
|
||||
st = shutil.disk_usage(mount_point)
|
||||
telemeter.synthesize("nvm")
|
||||
telemeter.sensors["nvm"].update_entry(capacity=st.total, used=st.used, type_label=self.target_disk["label"])
|
||||
|
||||
# Create RAM sensors
|
||||
ms = psutil.virtual_memory()
|
||||
telemeter.synthesize("ram")
|
||||
telemeter.sensors["ram"].update_entry(capacity=ms.total, used=ms.used, type_label="RAM")
|
||||
|
||||
# Create CPU sensor
|
||||
a = psutil.getloadavg()
|
||||
cps = 0; cpms = 5
|
||||
for m in range(cpms):
|
||||
cps += psutil.cpu_percent()/100.0
|
||||
time.sleep(0.05)
|
||||
cp = cps/cpms
|
||||
|
||||
telemeter.synthesize("processor")
|
||||
telemeter.sensors["processor"].update_entry(current_load=cp, clock=round(psutil.cpu_freq().current*1e6, 0), load_avgs=[a[0], a[1], a[2]], type_label="CPU")
|
||||
|
||||
# Create custom sensor for uptime
|
||||
telemeter.synthesize("custom")
|
||||
telemeter.sensors["custom"].update_entry(self.uptime, type_label="Uptime is", custom_icon="timer-refresh-outline")
|
||||
|
||||
# Finally, tell Sideband what class in this
|
||||
# file is the actual plugin class.
|
||||
plugin_class = ServerTelemetryPlugin
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
__debug_build__ = False
|
||||
__disable_shaders__ = False
|
||||
__version__ = "1.9.0"
|
||||
__version__ = "1.9.2"
|
||||
__variant__ = ""
|
||||
|
||||
import sys
|
||||
|
|
@ -449,6 +449,7 @@ else:
|
|||
from ui.objectdetails import ObjectDetails
|
||||
from ui.announces import Announces
|
||||
from ui.messages import Messages, ts_format, messages_screen_kv
|
||||
# from ui.messages_recycle import Messages, ts_format, messages_screen_kv
|
||||
from ui.helpers import ContentNavigationDrawer, DrawerList, IconListItem
|
||||
from ui.helpers import multilingual_markup, mdc, dark_theme_text_color
|
||||
from kivymd.toast import toast
|
||||
|
|
@ -483,6 +484,7 @@ else:
|
|||
from .ui.hardware import Hardware
|
||||
from .ui.objectdetails import ObjectDetails
|
||||
from .ui.messages import Messages, ts_format, messages_screen_kv
|
||||
# from .ui.messages_recycle import Messages, ts_format, messages_screen_kv
|
||||
from .ui.helpers import ContentNavigationDrawer, DrawerList, IconListItem
|
||||
from .ui.helpers import multilingual_markup, mdc, dark_theme_text_color
|
||||
|
||||
|
|
@ -1062,7 +1064,7 @@ class SidebandApp(MDApp):
|
|||
self.sideband.setstate("app.running", True)
|
||||
self.sideband.setstate("app.foreground", False)
|
||||
self.app_state = SidebandApp.PAUSED
|
||||
self.sideband.should_persist_data()
|
||||
self.sideband.should_persist_data(background=False)
|
||||
RNS.log("App paused", RNS.LOG_DEBUG)
|
||||
return True
|
||||
|
||||
|
|
@ -2870,7 +2872,7 @@ class SidebandApp(MDApp):
|
|||
else:
|
||||
self.messages_view.ids.messages_scrollview.dest_known = False
|
||||
if self.messages_view.ids.nokeys_text.text == "":
|
||||
keys_str = "The crytographic keys for the destination address are unknown at this time. You can wait for an announce to arrive, or query the network for the necessary keys."
|
||||
keys_str = "The cryptographic keys for the destination address are unknown at this time. You can wait for an announce to arrive, or query the network for the necessary keys."
|
||||
self.messages_view.ids.nokeys_text.text = keys_str
|
||||
self.widget_hide(self.messages_view.ids.message_input_part, True)
|
||||
self.widget_hide(self.messages_view.ids.message_ptt, True)
|
||||
|
|
|
|||
|
|
@ -90,10 +90,10 @@ class PropagationNodeDetector():
|
|||
pass
|
||||
|
||||
else:
|
||||
RNS.log(f"Received malformed propagation node announce from {RNS.prettyhexrep(destination_hash)} with data: {app_data}", RNS.LOG_EXTREME)
|
||||
RNS.log(f"Received malformed propagation node announce from {RNS.prettyhexrep(destination_hash)}", RNS.LOG_EXTREME)
|
||||
|
||||
else:
|
||||
RNS.log(f"Received malformed propagation node announce from {RNS.prettyhexrep(destination_hash)} with data: {app_data}", RNS.LOG_EXTREME)
|
||||
RNS.log(f"Received malformed propagation node announce from {RNS.prettyhexrep(destination_hash)}", RNS.LOG_EXTREME)
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error while processing received propagation node announce: "+str(e))
|
||||
|
|
@ -371,8 +371,9 @@ class SidebandCore():
|
|||
self.active_propagation_node = None
|
||||
self.propagation_detector = PropagationNodeDetector(self)
|
||||
|
||||
RNS.Transport.register_announce_handler(self)
|
||||
RNS.Transport.register_announce_handler(self.propagation_detector)
|
||||
if self.is_service or self.is_standalone:
|
||||
RNS.Transport.register_announce_handler(self)
|
||||
RNS.Transport.register_announce_handler(self.propagation_detector)
|
||||
|
||||
self.active_command_plugins = {}
|
||||
self.active_service_plugins = {}
|
||||
|
|
@ -580,10 +581,8 @@ class SidebandCore():
|
|||
total += entry.stat(follow_symlinks=False).st_size
|
||||
return total
|
||||
|
||||
def should_persist_data(self):
|
||||
if self.reticulum != None:
|
||||
self.reticulum._should_persist_data()
|
||||
|
||||
def should_persist_data(self, background=False):
|
||||
if self.reticulum != None: self.reticulum._should_persist_data(background=background)
|
||||
self.save_configuration()
|
||||
|
||||
def __load_telemetry_collector_excluded(self):
|
||||
|
|
@ -808,8 +807,7 @@ class SidebandCore():
|
|||
def __save_config(self, no_thread=False):
|
||||
RNS.log("Saving Sideband configuration...", RNS.LOG_DEBUG)
|
||||
def save_function():
|
||||
while self.saving_configuration:
|
||||
time.sleep(0.15)
|
||||
while self.saving_configuration: time.sleep(0.15)
|
||||
try:
|
||||
self.saving_configuration = True
|
||||
with open(self.config_path, "wb") as config_file: config_file.write(msgpack.packb(self.config))
|
||||
|
|
@ -828,8 +826,8 @@ class SidebandCore():
|
|||
if no_thread: save_function()
|
||||
else: threading.Thread(target=save_function, daemon=True).start()
|
||||
|
||||
if self.is_client:
|
||||
self.setstate("wants.settings_reload", True)
|
||||
if self.is_client: self.setstate("wants.settings_reload", True)
|
||||
RNS.log("Sideband configuration saved", RNS.LOG_DEBUG)
|
||||
|
||||
def __load_plugins(self):
|
||||
plugins_path = self.config["command_plugins_path"]
|
||||
|
|
@ -959,10 +957,8 @@ class SidebandCore():
|
|||
|
||||
def log_announce(self, dest, app_data, dest_type, stamp_cost=None, link_stats=None):
|
||||
try:
|
||||
if app_data == None:
|
||||
app_data = b""
|
||||
if type(app_data) != bytes:
|
||||
app_data = msgpack.packb([app_data, stamp_cost])
|
||||
if app_data == None: app_data = b""
|
||||
if type(app_data) != bytes: app_data = msgpack.packb([app_data, stamp_cost])
|
||||
RNS.log("Received "+str(dest_type)+" announce for "+RNS.prettyhexrep(dest), RNS.LOG_DEBUG)
|
||||
self._db_save_announce(dest, app_data, dest_type, link_stats)
|
||||
self.setstate("app.flags.new_announces", True)
|
||||
|
|
@ -3001,19 +2997,32 @@ class SidebandCore():
|
|||
with self.db_lock:
|
||||
db = self.__db_connect()
|
||||
dbc = db.cursor()
|
||||
|
||||
|
||||
base_condition = "(dest=:context_dest or source=:context_dest)"
|
||||
if after != None and before == None:
|
||||
query = "select * from lxm where (dest=:context_dest or source=:context_dest) and rx_ts>:after_ts"
|
||||
dbc.execute(query, {"context_dest": context_dest, "after_ts": after})
|
||||
query = f"select * from lxm where {base_condition} and rx_ts>:after_ts ORDER BY rx_ts DESC"
|
||||
params = {"context_dest": context_dest, "after_ts": after}
|
||||
if limit is not None:
|
||||
query += f" LIMIT :limit_val"; params["limit_val"] = int(limit)
|
||||
dbc.execute(query, params)
|
||||
elif after == None and before != None:
|
||||
query = "select * from lxm where (dest=:context_dest or source=:context_dest) and rx_ts<:before_ts"
|
||||
dbc.execute(query, {"context_dest": context_dest, "before_ts": before})
|
||||
query = f"select * from lxm where {base_condition} and rx_ts<:before_ts ORDER BY rx_ts DESC"
|
||||
params = {"context_dest": context_dest, "before_ts": before}
|
||||
if limit is not None:
|
||||
query += f" LIMIT :limit_val"; params["limit_val"] = int(limit)
|
||||
dbc.execute(query, params)
|
||||
elif after != None and before != None:
|
||||
query = "select * from lxm where (dest=:context_dest or source=:context_dest) and rx_ts<:before_ts and rx_ts>:after_ts"
|
||||
dbc.execute(query, {"context_dest": context_dest, "before_ts": before, "after_ts": after})
|
||||
query = f"select * from lxm where {base_condition} and rx_ts<:before_ts and rx_ts>:after_ts ORDER BY rx_ts DESC"
|
||||
params = {"context_dest": context_dest, "before_ts": before, "after_ts": after}
|
||||
if limit is not None:
|
||||
query += f" LIMIT :limit_val"; params["limit_val"] = int(limit)
|
||||
dbc.execute(query, params)
|
||||
else:
|
||||
query = "select * from lxm where dest=:context_dest or source=:context_dest"
|
||||
dbc.execute(query, {"context_dest": context_dest})
|
||||
query = f"select * from lxm where {base_condition} ORDER BY rx_ts DESC"
|
||||
params = {"context_dest": context_dest}
|
||||
if limit is not None:
|
||||
query += f" LIMIT :limit_val"; params["limit_val"] = int(limit)
|
||||
dbc.execute(query, params)
|
||||
|
||||
result = dbc.fetchall()
|
||||
|
||||
|
|
@ -3036,10 +3045,8 @@ class SidebandCore():
|
|||
lxm.paper_packed = paper_packed_lxm
|
||||
|
||||
extras = None
|
||||
try:
|
||||
extras = msgpack.unpackb(entry[11])
|
||||
except:
|
||||
pass
|
||||
try: extras = msgpack.unpackb(entry[11])
|
||||
except: pass
|
||||
|
||||
message = {
|
||||
"hash": lxm.hash,
|
||||
|
|
@ -3056,8 +3063,9 @@ class SidebandCore():
|
|||
}
|
||||
|
||||
messages.append(message)
|
||||
if len(messages) > limit:
|
||||
messages = messages[-limit:]
|
||||
|
||||
messages.reverse()
|
||||
if len(messages) > limit: messages = messages[-limit:]
|
||||
return messages
|
||||
|
||||
def _db_save_lxm(self, lxm, context_dest, originator = False, own_command = False, is_retry = False):
|
||||
|
|
@ -3271,42 +3279,31 @@ class SidebandCore():
|
|||
|
||||
def update_telemetry(self):
|
||||
try:
|
||||
try:
|
||||
latest_telemetry = deepcopy(self.latest_telemetry)
|
||||
except:
|
||||
latest_telemetry = None
|
||||
try: latest_telemetry = deepcopy(self.latest_telemetry)
|
||||
except: latest_telemetry = None
|
||||
|
||||
telemetry = self.get_telemetry()
|
||||
packed_telemetry = self.get_packed_telemetry()
|
||||
telemetry_changed = False
|
||||
|
||||
if telemetry != None and packed_telemetry != None:
|
||||
if latest_telemetry == None or len(telemetry) != len(latest_telemetry):
|
||||
telemetry_changed = True
|
||||
if latest_telemetry == None or len(telemetry) != len(latest_telemetry): telemetry_changed = True
|
||||
|
||||
if latest_telemetry != None:
|
||||
|
||||
if not telemetry_changed:
|
||||
for sn in telemetry:
|
||||
if telemetry_changed:
|
||||
break
|
||||
if telemetry_changed: break
|
||||
|
||||
if sn != "time":
|
||||
if sn in latest_telemetry:
|
||||
if telemetry[sn] != latest_telemetry[sn]:
|
||||
telemetry_changed = True
|
||||
else:
|
||||
telemetry_changed = True
|
||||
if telemetry[sn] != latest_telemetry[sn]: telemetry_changed = True
|
||||
else: telemetry_changed = True
|
||||
|
||||
if not telemetry_changed:
|
||||
for sn in latest_telemetry:
|
||||
|
||||
if telemetry_changed:
|
||||
break
|
||||
|
||||
if telemetry_changed: break
|
||||
if sn != "time":
|
||||
if not sn in telemetry:
|
||||
telemetry_changed = True
|
||||
if not sn in telemetry: telemetry_changed = True
|
||||
|
||||
if telemetry_changed:
|
||||
self.telemetry_changes += 1
|
||||
|
|
@ -3315,10 +3312,8 @@ class SidebandCore():
|
|||
self.setstate("app.flags.last_telemetry", time.time())
|
||||
|
||||
if self.is_client:
|
||||
try:
|
||||
self.service_set_latest_telemetry(self.latest_telemetry, self.latest_packed_telemetry)
|
||||
except Exception as e:
|
||||
RNS.log("Error while sending latest telemetry to service: "+str(e), RNS.LOG_ERROR)
|
||||
try: self.service_set_latest_telemetry(self.latest_telemetry, self.latest_packed_telemetry)
|
||||
except Exception as e: RNS.log("Error while sending latest telemetry to service: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
except Exception as e:
|
||||
import traceback
|
||||
|
|
@ -3408,14 +3403,10 @@ class SidebandCore():
|
|||
def is_known(self, dest_hash):
|
||||
try:
|
||||
source_identity = RNS.Identity.recall(dest_hash)
|
||||
if source_identity: return True
|
||||
else: return False
|
||||
|
||||
if source_identity:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
return False
|
||||
except Exception as e: return False
|
||||
|
||||
def request_key(self, dest_hash):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -37,6 +37,10 @@ class Keys():
|
|||
self.keys_screen.ids.keys_info.text = info1
|
||||
self.keys_screen.ids.backup_info.text = info2
|
||||
|
||||
def test_a(self, sender):
|
||||
RNS.log("TEST ACTION");
|
||||
RNS.log(self)
|
||||
RNS.log(self.app)
|
||||
|
||||
def _profile_backup_job(self):
|
||||
import tarfile
|
||||
|
|
@ -160,10 +164,10 @@ MDScreen:
|
|||
anchor_title: "left"
|
||||
elevation: 0
|
||||
left_action_items:
|
||||
[['menu', lambda x: root.app.nav_drawer.set_state("open")]]
|
||||
[['menu', lambda x: root.app.app.nav_drawer.set_state("open")]]
|
||||
right_action_items:
|
||||
[
|
||||
['close', lambda x: root.app.close_keys_action(self)],
|
||||
['close', lambda x: root.app.app.close_keys_action(self)],
|
||||
]
|
||||
|
||||
ScrollView:
|
||||
|
|
|
|||
|
|
@ -271,8 +271,7 @@ class Messages():
|
|||
else: self.hide_widget(self.ids.message_ptt, True)
|
||||
|
||||
c_ts = time.time()
|
||||
if len(self.new_messages) > 0:
|
||||
self.update_widget()
|
||||
if len(self.new_messages) > 0: self.update_widget()
|
||||
|
||||
if (len(self.added_item_hashes) < self.db_message_count) and not self.load_more_button in self.list.children:
|
||||
self.list.add_widget(self.load_more_button, len(self.list.children))
|
||||
|
|
|
|||
4
setup.py
4
setup.py
|
|
@ -114,8 +114,8 @@ setuptools.setup(
|
|||
]
|
||||
},
|
||||
install_requires=[
|
||||
"rns>=1.1.5",
|
||||
"lxmf>=0.9.4",
|
||||
"rns>=1.2.0",
|
||||
"lxmf>=0.9.6",
|
||||
"lxst>=0.4.6",
|
||||
"kivy>=2.3.0",
|
||||
"numpy>=2.0.0",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue