From 8cfaf468e9c5ae48cf29b3a834db3b8445aad5ce Mon Sep 17 00:00:00 2001 From: Sergey Savelyev Date: Thu, 25 Dec 2025 12:44:26 -0500 Subject: [PATCH] add boolean type --- examples/simple_producer/src/main.rs | 4 +++ frontend/src/components/BooleanText.vue | 29 ++++++++++++++++++ frontend/src/components/NumericText.vue | 21 ++++++++++--- frontend/src/components/TelemetryLine.vue | 35 +++++++++++++++++----- frontend/src/components/TelemetryValue.vue | 1 + frontend/src/components/ValueLabel.vue | 12 ++++++-- frontend/src/graph/line.ts | 1 + server/proto/core.proto | 2 ++ server/src/grpc.rs | 2 ++ server/src/serialization/primitives.rs | 13 ++++++++ server/src/telemetry/data_value.rs | 1 + server/src/telemetry/history.rs | 6 ++++ 12 files changed, 113 insertions(+), 14 deletions(-) create mode 100644 frontend/src/components/BooleanText.vue diff --git a/examples/simple_producer/src/main.rs b/examples/simple_producer/src/main.rs index 380aeb5..8aaecb7 100644 --- a/examples/simple_producer/src/main.rs +++ b/examples/simple_producer/src/main.rs @@ -170,6 +170,9 @@ async fn main() -> Result<(), Box> { let cos_tlm_handle = tlm .register("simple_producer/cos".into(), TelemetryDataType::Float64) .await?; + let bool_tlm_handle = tlm + .register("simple_producer/bool".into(), TelemetryDataType::Boolean) + .await?; let sin2_tlm_handle = tlm .register("simple_producer/sin2".into(), TelemetryDataType::Float32) @@ -239,6 +242,7 @@ async fn main() -> Result<(), Box> { Value::Float64((f64::TAU() * (index as f64) / (1000.0_f64)).cos()), publish_time, )); + tasks.push(bool_tlm_handle.publish(Value::Boolean(index % 1000 > 500), publish_time)); tasks.push(sin2_tlm_handle.publish( Value::Float32((f32::TAU() * (index as f32) / (500.0_f32)).sin()), publish_time, diff --git a/frontend/src/components/BooleanText.vue b/frontend/src/components/BooleanText.vue new file mode 100644 index 0000000..dc0cda9 --- /dev/null +++ b/frontend/src/components/BooleanText.vue @@ -0,0 +1,29 @@ + + + + + diff --git a/frontend/src/components/NumericText.vue b/frontend/src/components/NumericText.vue index 9c6e2f2..82e1f1e 100644 --- a/frontend/src/components/NumericText.vue +++ b/frontend/src/components/NumericText.vue @@ -6,6 +6,7 @@ const props = defineProps<{ value: number; max_width: number; copyable?: boolean; + include_span?: boolean; }>(); const emit = defineEmits<{ (e: 'update', value: string): void; @@ -14,6 +15,9 @@ const emit = defineEmits<{ const copyable = computed(() => { return props.copyable || false; }); +const include_span = computed(() => { + return props.include_span || false; +}); const display_value = computed(() => { if (props.value == 0) { @@ -61,9 +65,15 @@ const display_value = computed(() => { } return precision; }); -watch([display_value], ([display_str]) => { - emit('update', display_str); -}); +watch( + [display_value], + ([display_str]) => { + emit('update', display_str); + }, + { + immediate: true, + }, +); - diff --git a/frontend/src/components/TelemetryLine.vue b/frontend/src/components/TelemetryLine.vue index 9207650..8c7fe01 100644 --- a/frontend/src/components/TelemetryLine.vue +++ b/frontend/src/components/TelemetryLine.vue @@ -96,12 +96,21 @@ watch([value], ([val]) => { if (val) { const val_t = Date.parse(val.timestamp); if (val_t >= min_x) { - const item_val = val.value[ - telemetry_data.value!.data_type - ] as number; + const raw_item_val = val.value[telemetry_data.value!.data_type]; + let item_val = 0; + if ( + ['Float32', 'Float64'].some( + (e) => e == telemetry_data.value!.data_type, + ) + ) { + item_val = raw_item_val as number; + } else if (telemetry_data.value!.data_type == 'Boolean') { + item_val = (raw_item_val as boolean) ? 1 : 0; + } const new_item = { x: val_t, y: item_val, + value: raw_item_val, } as Point; memo.value.insert(new_item, data_min_sep.value); if (item_val < min.value) { @@ -131,10 +140,21 @@ watch( const response = (await res.json()) as TelemetryDataItem[]; for (const data_item of response) { const val_t = Date.parse(data_item.timestamp); - const item_val = data_item.value[type] as number; + const raw_item_val = data_item.value[type]; + let item_val = 0; + if ( + ['Float32', 'Float64'].some( + (e) => e == telemetry_data.value!.data_type, + ) + ) { + item_val = raw_item_val as number; + } else if (type == 'Boolean') { + item_val = (raw_item_val as boolean) ? 1 : 0; + } const new_item = { x: val_t, y: item_val, + value: raw_item_val, } as Point; memo.value.insert(new_item); if (item_val < min.value) { @@ -392,7 +412,7 @@ function onMouseExit(event: MouseEvent) { class="fade_other_selected label" :x="graph_data.x_map(toValue(graph_data.max_x)) + text_offset" :y="axis_data.y_map(current_data_point.y)" - :value="current_data_point.y" + :value="current_data_point.value" >