Skip to content

Display Elements

Display elements are read-only values shown in the Doover portal. They present data from tags, config, or static values. Users can view them but cannot interact with them directly.

NumericVariable

Displays a numeric value with optional precision, gauge widgets, ranges, and thresholds.

from pydoover.ui import NumericVariable, Range, Threshold, Colour, Widget, tag_ref
from pydoover.tags import Tags, Number

class MyTags(Tags):
    temperature = Number(default=0.0)

# Basic numeric display
temp = NumericVariable("Temperature", value=MyTags.temperature, units="C")

# With precision and gauge widget
pressure = NumericVariable(
    "Pressure",
    value=tag_ref("pressure", tag_type="number"),
    precision=2,
    units="kPa",
    form=Widget.radial,
)

Ranges

Ranges define coloured zones on the variable's plot. Each Range specifies a labelled band between a minimum and maximum value.

battery = NumericVariable(
    "Battery Voltage",
    value=tag_ref("battery_v", tag_type="number"),
    units="V",
    precision=1,
    ranges=[
        Range(label="Critical", min_val=0, max_val=11.0, colour=Colour.red),
        Range(label="Low", min_val=11.0, max_val=12.0, colour=Colour.yellow),
        Range(label="Normal", min_val=12.0, max_val=14.5, colour=Colour.green),
    ],
    default_range_view="zone",
)

Range parameters:

ParameterDescription
labelDisplay label for the range
min_valLower bound of the range
max_valUpper bound of the range
colourColour of the zone (default: Colour.blue)
show_on_graphWhether to display on the graph (default: True)

Thresholds

Thresholds draw horizontal lines on the variable's plot at specific values.

temperature = NumericVariable(
    "Temperature",
    value=tag_ref("temp", tag_type="number"),
    units="C",
    thresholds=[
        Threshold(label="High Alarm", value=40, colour=Colour.red),
        Threshold(label="Low Alarm", value=5, colour=Colour.yellow),
    ],
    default_range_view="line",
)

Threshold parameters:

ParameterDescription
labelLabel shown alongside the line
valueY-axis value where the line is drawn
colourColour of the line (default: Colour.blue)

Gauge Widgets

The form parameter controls how the value is visually presented, in addition to the standard number display.

WidgetDescription
Widget.linearA horizontal bar gauge
Widget.radialA circular dial gauge

Additional Parameters

ParameterDescription
precisionNumber of decimal places to display
earliest_data_timeEarliest datetime for which historical data is available
default_range_sincetimedelta controlling how far back the plot shows on load (default: 1 week)
default_zoomDefault zoom level for the built-in plot viewer
default_range_viewInitial range view mode: "line", "zone", or "off"
log_thresholdChange threshold for logging (0 = log every change, None = no change logging)
graphableWhether the variable can be plotted (default: True)

TextVariable

Displays a text string value.

from pydoover.ui import TextVariable, tag_ref

status = TextVariable("Status", value="Online")

# With tag binding
firmware = TextVariable(
    "Firmware Version",
    value=tag_ref("firmware_version", tag_type="string"),
)

BooleanVariable

Displays a boolean on/off state.

from pydoover.ui import BooleanVariable, tag_ref

pump_status = BooleanVariable(
    "Pump Running",
    value=tag_ref("pump_running", tag_type="boolean"),
    log_threshold=0,  # Log every change
)

The log_threshold parameter controls change-based logging. A value of 0 means every change is logged. A value of None disables change logging entirely.

DateTimeVariable

Displays a date and/or time value.

from datetime import datetime
from pydoover.ui import DateTimeVariable, tag_ref

last_calibration = DateTimeVariable(
    "Last Calibration",
    value=tag_ref("last_cal_time", tag_type="string"),
)

Timestamp

Displays a timestamp value with millisecond precision. The value is serialised as epoch milliseconds for the portal.

from pydoover.ui import Timestamp, tag_ref

last_reading = Timestamp(
    "Last Reading",
    value=tag_ref("last_reading_ts", tag_type="number"),
)

Multiplot

Displays a multi-series chart that overlays multiple data streams on a single plot — ideal for dashboards where operators need to compare related readings at a glance, such as temperature vs humidity across multiple sensors, or correlated process variables over time. Each series maps to a tag value and can have its own colour, units, axis, ranges, and thresholds.

from pydoover.ui import Multiplot, Series, Range, Colour, RangeView, tag_ref

environmental_plot = Multiplot(
    title="Environmental",
    series=[
        Series(
            "Temperature",
            value=tag_ref("temperature", tag_type="number"),
            data_type="number",
            colour=Colour.red,
            units="C",
            range=(0, 50),
            thresholds=[
                Threshold(label="High", value=40, colour=Colour.red),
            ],
        ),
        Series(
            "Humidity",
            value=tag_ref("humidity", tag_type="number"),
            data_type="number",
            colour=Colour.blue,
            units="%",
            range=(0, 100),
            shared_axis=False,
        ),
    ],
    default_range_view=RangeView.line,
    default_zoom="1d",
)

Series Parameters

ParameterDescription
display_nameLabel for the series in the legend
valueTag reference for the data source
data_typeData type: "number", "string", "boolean", or "unknown"
activeWhether the series is visible by default
colourSeries line colour
iconIcon identifier for the series
shared_axisTrue/False or axis name string for sharing Y axes
unitsUnits label for the series
step_labelsLabels for step-type series
range(min, max) tuple for the Y axis; values can be numeric or "auto"
rangesList of Range objects for zone display
thresholdsList of Threshold objects for line display

Multiplot Parameters

ParameterDescription
titleChart title (also used as display_name)
seriesList of Series objects
earliest_data_timeEarliest datetime for historical data
default_zoomDefault zoom level (e.g., "1d", "7d")
default_range_viewInitial range view: "line", "zone", or "off"
Information Circle
Example — Dynamic Series

A monitoring UI builds the Multiplot dynamically in setup() based on which sensors are flagged for the overview chart. Each sensor contributes multiple series with distinct colours:

from pydoover import ui

series = []
for elem in self.config.sensor_labels.elements:
    if not elem.show_on_overview.value:
        continue

    s_id = elem.id.value
    label = elem.name.value
    temp_name, humid_name = sensor_tag_names(s_id)

    series.append(ui.Series(
        f"{label} Temp",
        value=ui.tag_ref(temp_name),
        units="°C",
        colour=ui.Colour.tomato,
        data_type="number",
        active=True,
    ))
    series.append(ui.Series(
        f"{label} RH",
        value=ui.tag_ref(humid_name),
        units="%",
        colour=ui.Colour.blue,
        data_type="number",
        active=False,
    ))

self.add_element(ui.Multiplot("Overview", series=series, position=2))

This pattern — building the series list from config and adding the Multiplot via add_element() — is useful when the number of data streams varies per deployment.

ConnectionInfo

Displays the device's connection status in the portal. This element is typically defined once per application and informs the portal about the expected connection behaviour.

from pydoover.ui import ConnectionInfo, ConnectionType

# Always-connected device
conn = ConnectionInfo(
    connection_type=ConnectionType.constant,
    offline_after=120,  # Show offline after 2 minutes of silence
)

# Periodically-connecting device
conn = ConnectionInfo(
    connection_type=ConnectionType.periodic,
    connection_period=3600,      # Connects every hour
    next_connection=3600,        # Next connection in 1 hour
    offline_after=7200,          # Offline after 2 hours
    allowed_misses=2,            # Tolerate 2 missed connections
)
ParameterDescription
connection_typeConnectionType.constant or ConnectionType.periodic
connection_periodSeconds between connections (periodic only)
next_connectionSeconds until next expected connection (periodic only)
offline_afterSeconds of silence before showing as offline
allowed_missesNumber of missed connection periods before showing offline (periodic only)
Warning

connection_period, next_connection, and allowed_misses can only be set when connection_type is ConnectionType.periodic. Setting them with ConnectionType.constant raises a RuntimeError.

CameraLiveView

Displays a live camera stream in the portal with optional PTZ (pan-tilt-zoom) controls.

from pydoover.ui import CameraLiveView

live_camera = CameraLiveView(
    camera_name="front_gate",
    stream_name="main",
    allow_ptz_control=True,
    display_name="Front Gate Camera",
)
ParameterDescription
camera_nameIdentifier for the camera device
stream_nameName of the video stream
allow_ptz_controlWhether to show PTZ controls
display_nameLabel in the portal (default: "Live View")

CameraHistory

Displays historical camera footage with playback controls.

from pydoover.ui import CameraHistory

camera_history = CameraHistory(
    camera_name="front_gate",
    display_name="Front Gate History",
)
ParameterDescription
camera_nameIdentifier for the camera device
display_nameLabel in the portal (default: "History")

Next Steps