mirror of
https://github.com/markqvist/Sideband.git
synced 2024-12-26 07:59:23 -05:00
Added per-object livetracking functionality
This commit is contained in:
parent
d2efd8e91a
commit
a2575559cb
@ -160,6 +160,7 @@ class SidebandCore():
|
|||||||
self.telemetry_send_blocked_until = 0
|
self.telemetry_send_blocked_until = 0
|
||||||
self.pending_telemetry_request = False
|
self.pending_telemetry_request = False
|
||||||
self.telemetry_request_max_history = 7*24*60*60
|
self.telemetry_request_max_history = 7*24*60*60
|
||||||
|
self.live_tracked_objects = {}
|
||||||
self.default_lxm_limit = 128*1000
|
self.default_lxm_limit = 128*1000
|
||||||
self.state_db = {}
|
self.state_db = {}
|
||||||
self.state_lock = Lock()
|
self.state_lock = Lock()
|
||||||
@ -1253,7 +1254,7 @@ class SidebandCore():
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def request_latest_telemetry(self, from_addr=None):
|
def request_latest_telemetry(self, from_addr=None, is_livetrack=False):
|
||||||
if self.allow_service_dispatch and self.is_client:
|
if self.allow_service_dispatch and self.is_client:
|
||||||
try:
|
try:
|
||||||
return self._service_request_latest_telemetry(from_addr)
|
return self._service_request_latest_telemetry(from_addr)
|
||||||
@ -1286,6 +1287,10 @@ class SidebandCore():
|
|||||||
|
|
||||||
if self.config["telemetry_use_propagation_only"] == True:
|
if self.config["telemetry_use_propagation_only"] == True:
|
||||||
desired_method = LXMF.LXMessage.PROPAGATED
|
desired_method = LXMF.LXMessage.PROPAGATED
|
||||||
|
else:
|
||||||
|
if not self.message_router.delivery_link_available(from_addr) and RNS.Identity.current_ratchet_id(from_addr) != None:
|
||||||
|
RNS.log(f"Have ratchet for {RNS.prettyhexrep(from_addr)}, requesting opportunistic delivery of telemetry request", RNS.LOG_DEBUG)
|
||||||
|
desired_method = LXMF.LXMessage.OPPORTUNISTIC
|
||||||
else:
|
else:
|
||||||
desired_method = LXMF.LXMessage.DIRECT
|
desired_method = LXMF.LXMessage.DIRECT
|
||||||
|
|
||||||
@ -1300,7 +1305,7 @@ class SidebandCore():
|
|||||||
lxm.register_failed_callback(self.telemetry_request_finished)
|
lxm.register_failed_callback(self.telemetry_request_finished)
|
||||||
|
|
||||||
if self.message_router.get_outbound_propagation_node() != None:
|
if self.message_router.get_outbound_propagation_node() != None:
|
||||||
if self.config["telemetry_try_propagation_on_fail"]:
|
if self.config["telemetry_try_propagation_on_fail"] and not is_livetrack:
|
||||||
lxm.try_propagation_on_fail = True
|
lxm.try_propagation_on_fail = True
|
||||||
|
|
||||||
RNS.log(f"Sending telemetry request with timebase {request_timebase}", RNS.LOG_DEBUG)
|
RNS.log(f"Sending telemetry request with timebase {request_timebase}", RNS.LOG_DEBUG)
|
||||||
@ -1312,6 +1317,62 @@ class SidebandCore():
|
|||||||
else:
|
else:
|
||||||
return "not_sent"
|
return "not_sent"
|
||||||
|
|
||||||
|
def _is_tracking(self, object_addr):
|
||||||
|
return object_addr in self.live_tracked_objects
|
||||||
|
|
||||||
|
def is_tracking(self, object_addr, allow_cache=False):
|
||||||
|
if not RNS.vendor.platformutils.is_android():
|
||||||
|
return self._is_tracking(object_addr)
|
||||||
|
else:
|
||||||
|
if self.is_service:
|
||||||
|
return self._is_tracking(object_addr)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
return self.service_rpc_request({"is_tracking": object_addr})
|
||||||
|
except Exception as e:
|
||||||
|
ed = "Error while getting tracking state over RPC: "+str(e)
|
||||||
|
RNS.log(ed, RNS.LOG_DEBUG)
|
||||||
|
return ed
|
||||||
|
|
||||||
|
def _start_tracking(self, object_addr, interval, duration):
|
||||||
|
RNS.log("Starting tracking of "+RNS.prettyhexrep(object_addr), RNS.LOG_DEBUG)
|
||||||
|
self.live_tracked_objects[object_addr] = [interval, 0, time.time()+duration]
|
||||||
|
|
||||||
|
def start_tracking(self, object_addr, interval, duration, allow_cache=False):
|
||||||
|
if not RNS.vendor.platformutils.is_android():
|
||||||
|
return self._start_tracking(object_addr, interval, duration)
|
||||||
|
else:
|
||||||
|
if self.is_service:
|
||||||
|
return self._start_tracking(object_addr, interval, duration)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
args = {"object_addr": object_addr, "interval": interval, "duration": duration}
|
||||||
|
return self.service_rpc_request({"start_tracking": args})
|
||||||
|
except Exception as e:
|
||||||
|
ed = "Error while starting tracking over RPC: "+str(e)
|
||||||
|
RNS.log(ed, RNS.LOG_DEBUG)
|
||||||
|
return ed
|
||||||
|
|
||||||
|
def _stop_tracking(self, object_addr):
|
||||||
|
RNS.log("Stopping tracking of "+RNS.prettyhexrep(object_addr), RNS.LOG_DEBUG)
|
||||||
|
if object_addr in self.live_tracked_objects:
|
||||||
|
self.live_tracked_objects.pop(object_addr)
|
||||||
|
|
||||||
|
def stop_tracking(self, object_addr, allow_cache=False):
|
||||||
|
if not RNS.vendor.platformutils.is_android():
|
||||||
|
return self._stop_tracking(object_addr)
|
||||||
|
else:
|
||||||
|
if self.is_service:
|
||||||
|
return self._stop_tracking(object_addr)
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
args = {"object_addr": object_addr}
|
||||||
|
return self.service_rpc_request({"stop_tracking": args})
|
||||||
|
except Exception as e:
|
||||||
|
ed = "Error while stopping tracking over RPC: "+str(e)
|
||||||
|
RNS.log(ed, RNS.LOG_DEBUG)
|
||||||
|
return ed
|
||||||
|
|
||||||
def _service_send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemetry_request=False):
|
def _service_send_latest_telemetry(self, to_addr=None, stream=None, is_authorized_telemetry_request=False):
|
||||||
if not RNS.vendor.platformutils.is_android():
|
if not RNS.vendor.platformutils.is_android():
|
||||||
return False
|
return False
|
||||||
@ -1366,6 +1427,10 @@ class SidebandCore():
|
|||||||
|
|
||||||
if self.config["telemetry_use_propagation_only"] == True:
|
if self.config["telemetry_use_propagation_only"] == True:
|
||||||
desired_method = LXMF.LXMessage.PROPAGATED
|
desired_method = LXMF.LXMessage.PROPAGATED
|
||||||
|
else:
|
||||||
|
if not self.message_router.delivery_link_available(to_addr) and RNS.Identity.current_ratchet_id(to_addr) != None:
|
||||||
|
RNS.log(f"Have ratchet for {RNS.prettyhexrep(to_addr)}, requesting opportunistic delivery of telemetry", RNS.LOG_DEBUG)
|
||||||
|
desired_method = LXMF.LXMessage.OPPORTUNISTIC
|
||||||
else:
|
else:
|
||||||
desired_method = LXMF.LXMessage.DIRECT
|
desired_method = LXMF.LXMessage.DIRECT
|
||||||
|
|
||||||
@ -1778,6 +1843,14 @@ class SidebandCore():
|
|||||||
elif "get_lxm_stamp_cost" in call:
|
elif "get_lxm_stamp_cost" in call:
|
||||||
args = call["get_lxm_stamp_cost"]
|
args = call["get_lxm_stamp_cost"]
|
||||||
connection.send(self.get_lxm_stamp_cost(args["lxm_hash"]))
|
connection.send(self.get_lxm_stamp_cost(args["lxm_hash"]))
|
||||||
|
elif "is_tracking" in call:
|
||||||
|
connection.send(self.is_tracking(call["is_tracking"]))
|
||||||
|
elif "start_tracking" in call:
|
||||||
|
args = call["start_tracking"]
|
||||||
|
connection.send(self.start_tracking(object_addr=args["object_addr"], interval=args["interval"], duration=args["duration"]))
|
||||||
|
elif "stop_tracking" in call:
|
||||||
|
args = call["stop_tracking"]
|
||||||
|
connection.send(self.stop_tracking(object_addr=args["object_addr"]))
|
||||||
else:
|
else:
|
||||||
connection.send(None)
|
connection.send(None)
|
||||||
|
|
||||||
@ -3403,6 +3476,28 @@ class SidebandCore():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("An error occurred while requesting scheduled telemetry from collector: "+str(e), RNS.LOG_ERROR)
|
RNS.log("An error occurred while requesting scheduled telemetry from collector: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
stale_entries = []
|
||||||
|
if len(self.live_tracked_objects) > 0:
|
||||||
|
now = time.time()
|
||||||
|
for object_hash in self.live_tracked_objects:
|
||||||
|
tracking_entry = self.live_tracked_objects[object_hash]
|
||||||
|
tracking_int = tracking_entry[0]
|
||||||
|
tracking_last = tracking_entry[1]
|
||||||
|
tracking_end = tracking_entry[2]
|
||||||
|
|
||||||
|
if now < tracking_end:
|
||||||
|
if now > tracking_last+tracking_int:
|
||||||
|
RNS.log("Next live tracking request time reached for "+str(RNS.prettyhexrep(object_hash)))
|
||||||
|
self.request_latest_telemetry(from_addr=object_hash, is_livetrack=True)
|
||||||
|
tracking_entry[1] = time.time()
|
||||||
|
else:
|
||||||
|
stale_entries.append(object_hash)
|
||||||
|
|
||||||
|
for object_hash in stale_entries:
|
||||||
|
RNS.log("Terminating live tracking for "+RNS.prettyhexrep(object_hash)+", tracking duration reached", RNS.LOG_DEBUG)
|
||||||
|
self.live_tracked_objects.pop(object_hash)
|
||||||
|
|
||||||
|
|
||||||
def __start_jobs_deferred(self):
|
def __start_jobs_deferred(self):
|
||||||
if self.is_service:
|
if self.is_service:
|
||||||
self.service_thread = threading.Thread(target=self._service_jobs, daemon=True)
|
self.service_thread = threading.Thread(target=self._service_jobs, daemon=True)
|
||||||
|
@ -148,6 +148,15 @@ class ObjectDetails():
|
|||||||
else:
|
else:
|
||||||
self.from_objects = False
|
self.from_objects = False
|
||||||
|
|
||||||
|
if self.viewing_self:
|
||||||
|
self.screen.ids.track_button.disabled = True
|
||||||
|
else:
|
||||||
|
self.screen.ids.track_button.disabled = False
|
||||||
|
if self.app.sideband.is_tracking(source_dest):
|
||||||
|
self.screen.ids.track_button.text = "Stop Live Tracking"
|
||||||
|
else:
|
||||||
|
self.screen.ids.track_button.text = "Start Live Tracking"
|
||||||
|
|
||||||
self.coords = None
|
self.coords = None
|
||||||
self.telemetry_list.data = []
|
self.telemetry_list.data = []
|
||||||
pds = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(source_dest))).encode("utf-8")).decode("utf-8")
|
pds = multilingual_markup(escape_markup(str(self.app.sideband.peer_display_name(source_dest))).encode("utf-8")).decode("utf-8")
|
||||||
@ -218,6 +227,15 @@ class ObjectDetails():
|
|||||||
self.clear_widget()
|
self.clear_widget()
|
||||||
self.update()
|
self.update()
|
||||||
|
|
||||||
|
def live_tracking(self, sender):
|
||||||
|
if not self.viewing_self:
|
||||||
|
if not self.app.sideband.is_tracking(self.object_hash):
|
||||||
|
self.app.sideband.start_tracking(self.object_hash, interval=59, duration=7*24*60*60)
|
||||||
|
self.screen.ids.track_button.text = "Stop Live Tracking"
|
||||||
|
else:
|
||||||
|
self.app.sideband.stop_tracking(self.object_hash)
|
||||||
|
self.screen.ids.track_button.text = "Start Live Tracking"
|
||||||
|
|
||||||
def send_update(self):
|
def send_update(self):
|
||||||
if not self.viewing_self:
|
if not self.viewing_self:
|
||||||
result = self.app.sideband.send_latest_telemetry(to_addr=self.object_hash)
|
result = self.app.sideband.send_latest_telemetry(to_addr=self.object_hash)
|
||||||
@ -643,10 +661,9 @@ class RVDetails(MDRecycleView):
|
|||||||
alt_str = RNS.prettydistance(alt)
|
alt_str = RNS.prettydistance(alt)
|
||||||
formatted_values = f"Coordinates [b]{fcoords}[/b], altitude [b]{alt_str}[/b]"
|
formatted_values = f"Coordinates [b]{fcoords}[/b], altitude [b]{alt_str}[/b]"
|
||||||
if speed != None:
|
if speed != None:
|
||||||
if speed > 0.02:
|
if speed > 0.1:
|
||||||
speed_formatted_values = f"Speed [b]{speed} Km/h[/b], heading [b]{heading}°[/b]"
|
speed_formatted_values = f"Speed [b]{speed} Km/h[/b], heading [b]{heading}°[/b]"
|
||||||
else:
|
else:
|
||||||
# speed_formatted_values = f"Speed [b]0 Km/h[/b]"
|
|
||||||
speed_formatted_values = f"Object is [b]stationary[/b]"
|
speed_formatted_values = f"Object is [b]stationary[/b]"
|
||||||
else:
|
else:
|
||||||
speed_formatted_values = None
|
speed_formatted_values = None
|
||||||
@ -972,22 +989,22 @@ MDScreen:
|
|||||||
on_release: root.delegate.request_update()
|
on_release: root.delegate.request_update()
|
||||||
disabled: False
|
disabled: False
|
||||||
|
|
||||||
# MDBoxLayout:
|
MDBoxLayout:
|
||||||
# orientation: "horizontal"
|
orientation: "horizontal"
|
||||||
# spacing: dp(16)
|
spacing: dp(16)
|
||||||
# size_hint_y: None
|
size_hint_y: None
|
||||||
# height: self.minimum_height
|
height: self.minimum_height
|
||||||
# padding: [dp(24), dp(16), dp(24), dp(24)]
|
padding: [dp(24), dp(0), dp(24), dp(24)]
|
||||||
|
|
||||||
# MDRectangleFlatIconButton:
|
MDRectangleFlatIconButton:
|
||||||
# id: delete_button
|
id: track_button
|
||||||
# icon: "trash-can-outline"
|
icon: "crosshairs-gps"
|
||||||
# text: "Delete All Telemetry"
|
text: "Start Live Tracking"
|
||||||
# padding: [dp(0), dp(14), dp(0), dp(14)]
|
padding: [dp(0), dp(14), dp(0), dp(14)]
|
||||||
# icon_size: dp(24)
|
icon_size: dp(24)
|
||||||
# font_size: dp(16)
|
font_size: dp(16)
|
||||||
# size_hint: [1.0, None]
|
size_hint: [1.0, None]
|
||||||
# on_release: root.delegate.copy_telemetry(self)
|
on_release: root.delegate.live_tracking(self)
|
||||||
# disabled: False
|
disabled: False
|
||||||
|
|
||||||
"""
|
"""
|
@ -39,13 +39,13 @@ class Utilities():
|
|||||||
self.app.root.ids.screen_manager.add_widget(self.screen)
|
self.app.root.ids.screen_manager.add_widget(self.screen)
|
||||||
|
|
||||||
self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect
|
self.screen.ids.telemetry_scrollview.effect_cls = ScrollEffect
|
||||||
info = "\nYou can use various RNS utilities from Sideband. "
|
info = "This section contains various utilities and diagnostics tools, "
|
||||||
info += ""
|
info += "that can be helpful while using Sideband and Reticulum."
|
||||||
|
|
||||||
if self.app.theme_cls.theme_style == "Dark":
|
if self.app.theme_cls.theme_style == "Dark":
|
||||||
info = "[color=#"+self.app.dark_theme_text_color+"]"+info+"[/color]"
|
info = "[color=#"+self.app.dark_theme_text_color+"]"+info+"[/color]"
|
||||||
|
|
||||||
self.screen.ids.telemetry_info.text = info
|
self.screen.ids.utilities_info.text = info
|
||||||
|
|
||||||
|
|
||||||
### rnstatus screen
|
### rnstatus screen
|
||||||
@ -151,14 +151,14 @@ MDScreen:
|
|||||||
orientation: "vertical"
|
orientation: "vertical"
|
||||||
size_hint_y: None
|
size_hint_y: None
|
||||||
height: self.minimum_height
|
height: self.minimum_height
|
||||||
padding: [dp(28), dp(48), dp(28), dp(16)]
|
padding: [dp(28), dp(32), dp(28), dp(16)]
|
||||||
|
|
||||||
|
# MDLabel:
|
||||||
|
# text: "Utilities & Tools"
|
||||||
|
# font_style: "H6"
|
||||||
|
|
||||||
MDLabel:
|
MDLabel:
|
||||||
text: "Utilities & Tools"
|
id: utilities_info
|
||||||
font_style: "H6"
|
|
||||||
|
|
||||||
MDLabel:
|
|
||||||
id: telemetry_info
|
|
||||||
markup: True
|
markup: True
|
||||||
text: ""
|
text: ""
|
||||||
size_hint_y: None
|
size_hint_y: None
|
||||||
@ -194,6 +194,17 @@ MDScreen:
|
|||||||
on_release: root.delegate.logviewer_action(self)
|
on_release: root.delegate.logviewer_action(self)
|
||||||
disabled: False
|
disabled: False
|
||||||
|
|
||||||
|
MDRectangleFlatIconButton:
|
||||||
|
id: advanced_button
|
||||||
|
icon: "network-pos"
|
||||||
|
text: "Advanced RNS Configuration"
|
||||||
|
padding: [dp(0), dp(14), dp(0), dp(14)]
|
||||||
|
icon_size: dp(24)
|
||||||
|
font_size: dp(16)
|
||||||
|
size_hint: [1.0, None]
|
||||||
|
on_release: root.delegate.advanced_action(self)
|
||||||
|
disabled: False
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
layout_rnstatus_screen = """
|
layout_rnstatus_screen = """
|
||||||
|
Loading…
Reference in New Issue
Block a user