84 lines
3.1 KiB
GDScript
84 lines
3.1 KiB
GDScript
@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
|