@tool extends PanelContainer @export var maximum_depth_m := 1000.0 @export var maximum_pressure_mpa := 10.0 @export var shallow_scale_knee_m := 1.0 @export_range(0, 1) var warning_fraction := 0.8 @export_range(0, 1) var fault_fraction := 0.95 @export var stale_after_seconds := 2.0 var _depth := 0.0 var _pressure := 0.0 var _temperature := 0.0 var _received_ms := -1 var _stale := false func _ready() -> void: _refresh() ## Depth in metres, pressure in MPa, water temperature in Celsius; supplied independently. func set_telemetry(depth_m: float, pressure_mpa: float, water_temperature_c: float) -> bool: if not is_finite(depth_m) or not is_finite(pressure_mpa) or not is_finite(water_temperature_c) or pressure_mpa < 0: return false _depth = depth_m _pressure = pressure_mpa _temperature = water_temperature_c _received_ms = Time.get_ticks_msec() _refresh() return true func clear_telemetry() -> void: _received_ms = -1 _refresh() func _severity(ratio: float) -> int: return 2 if ratio >= maxf(warning_fraction, fault_fraction) else (1 if ratio >= warning_fraction else 0) 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 measured := _received_ms >= 0 _stale = measured and Time.get_ticks_msec() - _received_ms > stale_after_seconds * 1000 var depth_ratio := _depth / maxf(maximum_depth_m, 0.001) var pressure_ratio := _pressure / maxf(maximum_pressure_mpa, 0.001) var worst_ratio := maxf(depth_ratio, pressure_ratio) var variants := ["Label", "InstrumentWarning", "InstrumentFault"] %DepthValue.text = "%.2f m" % _depth if measured else "— m" %PressureValue.text = "%.2f MPa" % _pressure if measured else "— MPa" %TemperatureValue.text = "%.1f °C" % _temperature if measured else "— °C" %DepthReference.text = "/ %s m" % String.num(maximum_depth_m, 2).trim_suffix(".0") %PressureReference.text = "/ %s MPa" % String.num(maximum_pressure_mpa, 2).trim_suffix(".0") %DepthTitle.theme_type_variation = variants[_severity(depth_ratio)] if measured else "Label" %PressureTitle.theme_type_variation = variants[_severity(pressure_ratio)] if measured else "Label" %State.text = "NO TELEMETRY" if not measured else ("STALE" if _stale else ("OVER LIMIT" if worst_ratio > 1 else ("NEAR LIMIT" if _severity(worst_ratio) > 0 else ""))) %State.theme_type_variation = "InstrumentMuted" if not measured else ("InstrumentWarning" if _stale else variants[_severity(worst_ratio)]) %DepthScale.depth_m = _depth %DepthScale.maximum_depth_m = maxf(maximum_depth_m, 0.001) %DepthScale.knee_m = maxf(shallow_scale_knee_m, 0.001) %DepthScale.warning_fraction = warning_fraction %DepthScale.fault_fraction = maxf(warning_fraction, fault_fraction) %DepthScale.available = measured %DepthScale.queue_redraw()