@tool extends PanelContainer enum Connection { CONNECTED, DEGRADED, DISCONNECTED } @export var downlink_capacity_gbps := 10.0 @export var uplink_capacity_gbps := 10.0 @export_range(0, 1) var warning_fraction := 0.8 @export_range(0, 1) var fault_fraction := 0.95 @export var loss_window_seconds := 10.0 @export var stale_after_seconds := 2.0 @export var link_icon: Texture2D: set(value): link_icon = value if is_node_ready(): %LinkIcon.texture = value var _received_ms := -1 var _state := Connection.CONNECTED var _down := 0.0 var _up := 0.0 var _loss := 0.0 var _stale := false func _ready() -> void: %LinkIcon.texture = link_icon theme_changed.connect(_update_icon) _update_icon() _refresh() ## Rates in Gbps; loss in percent over loss_window_seconds. func set_telemetry(down: float, up: float, loss_percent: float, state: int = Connection.CONNECTED) -> bool: if not is_finite(down) or not is_finite(up) or not is_finite(loss_percent) or down < 0 or up < 0 or loss_percent < 0 or loss_percent > 100 or state < 0 or state > 2: return false _down = down _up = up _loss = loss_percent _state = state _received_ms = Time.get_ticks_msec() _refresh() return true func clear_telemetry() -> void: _received_ms = -1 _refresh() func _process(_delta: float) -> void: var stale := _received_ms >= 0 and Time.get_ticks_msec() - _received_ms > stale_after_seconds * 1000 if stale != _stale: _refresh() func _refresh() -> void: if not is_node_ready(): return var missing := _received_ms < 0 _stale = not missing and Time.get_ticks_msec() - _received_ms > stale_after_seconds * 1000 var measured := not missing and _state != Connection.DISCONNECTED %State.text = "NO TELEMETRY" if missing else ("STALE" if _stale else ["CONNECTED", "DEGRADED", "DISCONNECTED"][_state]) %State.theme_type_variation = "LinkMuted" if missing else ("LinkRateWarning" if _stale or _state == Connection.DEGRADED else ("LinkRateFault" if _state == Connection.DISCONNECTED else "Label")) var gauges := [%Downlink, %Uplink] for index in range(2): gauges[index].capacity_gbps = maxf([downlink_capacity_gbps, uplink_capacity_gbps][index], 0.001) gauges[index].warning_fraction = warning_fraction gauges[index].fault_fraction = maxf(warning_fraction, fault_fraction) gauges[index].rate_gbps = [_down, _up][index] gauges[index].available = measured gauges[index].refresh() %LossValue.text = "%.2f%%" % _loss if measured else "—" %LossWindow.text = "%.0f s window" % loss_window_seconds + (" · held" if _stale else "") func _update_icon() -> void: var tint := get_theme_color("status_icon", "SurfaceSide") tint.a = 0.06 %LinkIcon.self_modulate = tint