Skip to content

feat (display): RTTank-based Thermometer backend — numeric scale, alarm limits, and glass bulb (opt-in via preference) - #3930

Open
emilioheredia-source wants to merge 7 commits into
ControlSystemStudio:masterfrom
emilioheredia-source:display/thermometer-scale
Open

emilioheredia-source wants to merge 7 commits into
ControlSystemStudio:masterfrom
emilioheredia-source:display/thermometer-scale

Conversation

@emilioheredia-source

@emilioheredia-source emilioheredia-source commented Sep 18, 2026

Copy link
Copy Markdown

Depends on #3767 and #3768. This branch is stacked on progressbar_scale: the first 6 commits are #3767 and #3768, only the last 3 commits are this PR (ThermometerWidget, RTTank thermometer look, RTThermometerRepresentation). Please review those two first; this PR will then show only its own diff. Until then the ReadTheDocs check may fail to compile against RTScaledWidgetRepresentation from #3767. Independent of that, #3929 touches the same limit-line block of RTTank as this PR (one hunk); whichever merges second gets a trivial rebase from me the same day.

Summary

Last PR of the scale series that started with the Tank in #3760. It gives the Thermometer the same opt-in RTTank backend that #3768 gives the Progress Bar:

org.csstudio.display.builder.representation/thermometer_scale_mode=false
  • false (default): the stock hand-drawn ThermometerRepresentation is used. Nothing changes for existing displays.
  • true: RTThermometerRepresentation draws the thermometer with RTTank in a thermometer style: a narrow tube with a bulb, a real numeric scale next to the tube, and alarm limit lines.
PR Widget
#3760 Tank: dual scale, alarm limits, ScaledPVWidget base class (merged)
#3766 RTTank: parallel_rendering preference (merged)
#3767 RTScaledWidgetRepresentation base class, show_scale_labels
#3768 Progress Bar backend
this Thermometer backend

Screenshots

New renderer (thermometer_scale_mode=true). From left to right: with scale; range and alarm limits from sim://sine; log scale with both scales and outline; defaults (no scale); wide widget with bulb_size=40 and 2 px outline; narrow widget; manual (dashed) limits with decimal format; custom colors:

thermometer_new_renderer

Stock renderer (default), same .bob file:

thermometer_stock_renderer

What the new renderer adds

  • Numeric scale next to the tube (scale_visible, off by default so a thermometer keeps its stock proportions until a scale is asked for) with format, precision, log_scale, show_minor_ticks, perpendicular_tick_labels (default on, horizontal labels read naturally next to a vertical tube), show_scale_labels, foreground_color
  • Optional second scale on the right wall (opposite_scale_visible)
  • Alarm limit lines LOLO / LO / HI / HIHI, from the PV or from level_* properties; PV limits solid, manual ones dashed
  • bulb_size (0..50 px): how much wider than the tube the bulb is; the bulb is always drawn
  • tank_border_width: glass outline around tube and bulb, 0 = none (same name as the Tank and the Progress Bar; a BOY file's generic border_width element does not become an outline)
  • inner_padding, background_color, font

Tube and bulb widen with the widget up to a cap, like the stock thermometer. The liquid level and the limit lines are placed through the scale's own transform, so they line up with the tick marks at every size, including when the scale is hidden.

Model changes

ThermometerWidget extends ScaledPVWidget like Tank and Progress Bar. Existing .bob and BOY files load unchanged: fill_color, limits_from_pv, minimum and maximum keep their names; older Phoebus versions ignore the new elements. ThermometerWidgetUnitTest covers a legacy .bob and a BOY .opi snippet. The property panel hides the scale-only properties while the stock renderer is selected (ThermometerWidget.SCALE_MODE_PROPS).

Design note

The thermometer look lives in RTTank behind a thermometer_style flag, next to the existing flat_track and inner_padding switches. computeLayout() and updateImageBuffer() dispatch on it; with the flag off, none of the thermometer code runs, so Tank and Progress Bar are unaffected. The tank body drawing moved into its own drawTank() so both looks read the same way. If a fourth look ever shows up, splitting the looks into RTTank subclasses would be the next step; for two looks the flag is the smaller change.

Files changed

Area Files
Widget model ThermometerWidget.java, ThermometerWidgetUnitTest.java, Messages.java, messages.properties
RTTank RTTank.java (thermometer layout and painting, setThermometerStyle, setBulbSize), RTTankTest.java (geometry at degenerate sizes)
Representation RTThermometerRepresentation.java (new), BaseWidgetRepresentations.java
Preference Preferences.java, display_representation_preferences.properties
Editor PropertyPanelSection.java

Testing

Default:

  1. Open displays with Thermometer, Tank and Progress Bar widgets without the preference: identical to before.

With thermometer_scale_mode=true:
2. Existing .bob files open normally; the property panel shows the new properties.
3. Resize from narrow to wide: tube and bulb grow up to the cap, scale stays flush to the tube.
4. scale_visible (off by default), opposite_scale_visible, perpendicular_tick_labels, show_scale_labels, show_minor_ticks, foreground_color.
5. log_scale=true with minimum=0.1, maximum=10000: log axis, level follows.
6. bulb_size 0..50, tank_border_width 0..5, inner_padding 0..20.
7. limits_from_pv with sim://sine(0,100,2) and show_alarm_limits=true: lines at 10/20/80/90; manual level_* gives dashed lines.
8. Vary the PV value: the liquid surface tracks the tick marks, with and without a visible scale.
9. Tank and Progress Bar widgets on the same display are unaffected.

Checklist

  • Testing:
    • The feature has automated tests (ThermometerWidgetUnitTest: defaults, legacy file loads unchanged, XML round trip of the new properties, default widget writes no new elements, hidden-property list matches real properties)
    • Tests were run (mvn install with tests on the touched modules, plus the manual checks above)
  • Documentation:
    • Release notes:
      • Added an entry when adding a new feature

…scale_labels to Tank

Move everything in TankRepresentation that only depends on the
ScaledPVWidget contract into an abstract RTScaledWidgetRepresentation:
creating the RTTank, forwarding value and range updates, evaluating the
alarm limits, the orientation transform and the update scheduling.
TankRepresentation keeps the Tank specific listeners and colors. The
behaviour of the Tank widget does not change.

Add a 'show_scale_labels' property (default true) to the Tank so that
stacked widgets can share one labelled scale: with the property off,
YAxisImpl draws the tick marks and the axis line only. Tick positions
are the same as with labels.

TankWidgetUnitTest covers the new property.
Move the progress bar onto the ScaledPVWidget base class that the Tank
already uses, so it carries the same range, scale and alarm limit
properties, plus an inner padding.

The scale look properties (font, foreground and fill color, log scale,
scale visibility, tick options, border width) now live in ScaledPVWidget
with a defineScaleLookProperties() helper, and the Tank uses the same
fields in its own order. The border keeps the Tank's 'tank_border_width'
name for all scaled widgets: legacy BOY files carry a 'border_width'
element for every widget, which must not become a bar border.

The stock renderer ignores the additions, and existing .bob files keep
loading unchanged since the pre-existing properties keep their names.
The BOY importer picks up 'show_scale', 'scale_font' and the 'level_hi'
and 'level_lo' names that differ from ours.

ProgressBarWidgetUnitTest covers defaults, legacy .bob and BOY files,
the XML round trip and the list of renderer-only properties.
Add RTProgressBarRepresentation, which draws the progress bar with the
RTTank engine shared with the Tank widget. This gives the bar a numeric
scale with format and precision, an optional opposite scale, minor
ticks, tick-only mode for stacked bars, and alarm limit lines.

RTTank gains an inner padding and a flat track for the progress bar
look. RTScaledWidgetRepresentation gains registerScaleLookListeners()
and applyScaleLook() for the scale look properties that ScaledPVWidget
defines; TankRepresentation and the new representation use them and
only handle their own extras.

The renderer is selected with the new preference

    org.csstudio.display.builder.representation/progressbar_scale_mode

which defaults to false. With the default, the stock JavaFX
ProgressBarRepresentation is used and nothing changes for existing
displays. The property panel hides the renderer-only properties while
the stock renderer is in use.
The EDM 'activeBar' carries a scale flag, a fixed range, a precision and
a border flag that the progress bar can now represent.
Move the thermometer onto the ScaledPVWidget base class, like the Tank
and the Progress Bar, so it carries the same range, scale and alarm
limit properties through defineScaleLookProperties(), plus background
color, inner padding and a bulb size. The scale is off by default, so
a thermometer keeps its stock proportions until a scale is asked for.

The stock renderer ignores the additions. Existing .bob and BOY files
keep loading unchanged since the pre-existing properties keep their
names and the border uses the 'tank_border_width' name.

ThermometerWidgetUnitTest covers defaults, legacy .bob and BOY files,
the XML round trip and the list of renderer-only properties.
@emilioheredia-source emilioheredia-source changed the title # feat (display): RTTank-based Thermometer backend — numeric scale, alarm limits, and glass bulb (opt-in via preference) feat (display): RTTank-based Thermometer backend — numeric scale, alarm limits, and glass bulb (opt-in via preference) Sep 18, 2026
Add a thermometer style to RTTank: a narrow tube, centered in the plot
area, with a bulb at the bottom. The scales sit right next to the tube
and only span the tube, so the liquid level and the alarm limit lines
are placed through the scale transform and always line up with the
tick marks. Tube and bulb widen with the widget up to a cap, like the
stock thermometer, and the bulb size can be adjusted. A widget that is
too narrow for scale and bulb keeps tube and bulb in view.

The tank look is not affected. The tank body drawing moves into its
own method so that updateImageBuffer() only dispatches on the style.

RTTankTest checks the thermometer geometry for degenerate sizes.
Add RTThermometerRepresentation, which draws the thermometer with the
RTTank engine in its thermometer style. This gives the thermometer a
numeric scale with format and precision, log scale, minor ticks, an
optional opposite scale, a glass outline and alarm limit lines, with
the foreground color for scale and outline.

The renderer is selected with the new preference

    org.csstudio.display.builder.representation/thermometer_scale_mode

which defaults to false. With the default, the stock hand drawn
ThermometerRepresentation is used and nothing changes for existing
displays. The property panel hides the renderer-only properties while
the stock renderer is in use.
@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants