@tool extends PanelContainer @export var mode_icon: Texture2D: set(value): mode_icon = value if is_node_ready(): %ModeIcon.texture = value @export var stale_after_seconds := 2.0 @export var pulse_alerts := true: set(value): pulse_alerts = value if is_node_ready(): %StatusArt.pulse_alerts = value var _received_ms := -1 var _severity := 0 var _name := "" var _code := "" var _detail := "" var _action := "" var _stale := false func _ready() -> void: %ModeIcon.texture = mode_icon _refresh_status() _refresh_references() ## Severity and fault explanations come from vehicle telemetry, not gauge zones. func set_status(name_text: String, severity: int = 0, code: String = "", detail: String = "", action: String = "") -> void: _name = name_text _severity = clampi(severity, 0, 2) _code = code _detail = detail _action = action _refresh_status() func set_telemetry(voltage: float, current: float, power: float, internal_temperature: float) -> void: for number in [voltage, current, power, internal_temperature]: if not is_finite(number): return _refresh_references() _received_ms = Time.get_ticks_msec() var values := [voltage, current, power, internal_temperature] var labels := [%VoltageValue, %CurrentValue, %PowerValue, %TemperatureValue] var gauges := [%VoltageGauge, %CurrentGauge, %PowerGauge, %TemperatureGauge] for index in range(4): labels[index].text = (["%.1f V", "%.1f A", "%.0f W", "%.1f °C"][index]) % values[index] gauges[index].value = values[index] gauges[index].available = true gauges[index].queue_redraw() _refresh_status() 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_status() func _refresh_status() -> void: if not is_node_ready(): return _stale = _received_ms >= 0 and Time.get_ticks_msec() - _received_ms > stale_after_seconds * 1000 var missing := _received_ms < 0 var unavailable := missing or _stale %StatusArt.severity = 3 if unavailable else _severity %StatusArt.pulse_alerts = pulse_alerts %StatusArt.queue_redraw() %ModeIcon.visible = not unavailable and _severity == 0 %Severity.text = "NO DATA" if missing else ("STALE" if _stale else ["", "WARNING", "FAULT"][_severity]) %StatusName.text = "Waiting for telemetry" if missing else (_name if not _name.is_empty() else "Mode unavailable") %Code.text = _code %Code.visible = not _code.is_empty() and not missing %Detail.text = "" if missing else _detail %Action.text = "Values held · connection overdue" if _stale else ("" if missing else _action) var variant := ("VehicleWarningText" if _severity == 1 else "VehicleFaultText") if _severity in [1, 2] and not unavailable else "Label" for label in [%Severity, %StatusName, %Code, %Detail, %Action]: label.theme_type_variation = variant func _refresh_references() -> void: %VoltageReference.text = "/ %.0f V" % %VoltageGauge.nominal %CurrentReference.text = "/ %.0f A" % %CurrentGauge.fault_high %PowerReference.text = "/ %.0f W" % %PowerGauge.fault_high %TemperatureReference.text = "/ %.0f °C" % %TemperatureGauge.fault_high