Skip to content

UI Components Overview

The pydoover UI system provides a comprehensive framework for building rich, interactive user interfaces for IoT devices. The UI components allow you to display real-time data, accept user input, and organize your interface into logical sections.

Architecture

The UI system is built around several key concepts:

  • UIManager: The central controller that manages UI state, handles communication with the cloud, and coordinates updates
  • Elements: The base building blocks that can be displayed in the UI
  • Variables: Read-only display elements that show device data (numeric, text, boolean, datetime)
  • Interactions: Elements that accept user input (parameters, actions, sliders, state commands)
  • Containers: Logical groupings that organize elements (submodules, applications)
  • Styling: Visual customization through colors, ranges, and widgets

Module Structure

The UI module exports all components from pydoover.ui:

from pydoover.ui import (
    # Manager
    UIManager,

    # Display Elements (Variables)
    Variable,
    NumericVariable,
    TextVariable,
    BooleanVariable,
    DateTimeVariable,

    # Interactive Elements
    Interaction,
    Action,
    StateCommand,
    Slider,
    Parameter,
    NumericParameter,
    TextParameter,
    BooleanParameter,
    DateTimeParameter,
    WarningIndicator,
    HiddenValue,

    # Containers
    Container,
    Submodule,
    Application,
    RemoteComponent,

    # Styling
    Colour,
    Range,
    Widget,
    Option,
    ApplicationVariant,

    # Decorators
    action,
    state_command,
    slider,
    hidden_value,
    warning_indicator,
    numeric_parameter,
    text_parameter,
    boolean_parameter,
    datetime_parameter,
    callback,

    # Special Elements
    Element,
    ConnectionType,
    ConnectionInfo,
    AlertStream,
    Multiplot,
)

Basic Usage

Here is a simple example of setting up a UI with the UIManager:

from pydoover.ui import (
    UIManager,
    NumericVariable,
    TextVariable,
    Action,
    Submodule,
    Colour,
    Range,
)

# Create the UI manager
ui = UIManager(app_key="my_app", client=my_client)

# Create display variables
temperature = NumericVariable(
    name="temperature",
    display_name="Temperature",
    curr_val=25.5,
    precision=1,
    ranges=[
        Range(label="Normal", min_val=18, max_val=28, colour=Colour.green),
        Range(label="Warning", min_val=28, max_val=35, colour=Colour.orange),
    ]
)

status = TextVariable(
    name="status",
    display_name="Status",
    curr_val="Running"
)

# Create an action button
restart_action = Action(
    name="restart",
    display_name="Restart Device",
    colour=Colour.red,
    requires_confirm=True
)

# Group elements in a submodule
sensor_module = Submodule(
    name="sensors",
    display_name="Sensor Data",
    children=[temperature, status]
)

# Add elements to the UI
ui.add_children(sensor_module, restart_action)

# Push updates to the cloud
ui.push()

Data Flow

The UI system manages bidirectional data flow:

  1. Device to Cloud: Variables are updated locally and pushed to the cloud via UIManager.push()
  2. Cloud to Device: User interactions (commands) are received and trigger callbacks
# Updating a variable value
ui.update_variable("temperature", 26.3)

# Handling incoming commands
@ui.callback("restart")
def handle_restart(element, new_value):
    print("Restart command received!")
    # Perform restart logic

Synchronization

The UIManager handles synchronization between local state and the cloud:

  • Pull: Fetches the current UI state and commands from the cloud
  • Push: Sends local changes to the cloud
  • Automatic Updates: When observed by users, updates are sent more frequently
# Manual synchronization
ui.pull()  # Get latest state from cloud
ui.push()  # Send local changes to cloud

# Automatic handling (recommended)
ui.handle_comms()  # Intelligently manages push/pull based on observation state

Async Support

The UI system supports both synchronous and asynchronous operation:

# Synchronous
ui.push()
ui.pull()

# Asynchronous
await ui.push_async()
await ui.pull_async()
await ui.handle_comms_async()

Key Features

  • Differential Updates: Only changed elements are sent to minimize bandwidth
  • Critical Updates: Mark important changes for immediate synchronization
  • Observation-Aware: Adjusts update frequency based on whether users are viewing the UI
  • Callback System: Flexible callback registration for handling user interactions
  • Decorator Support: Use decorators to define interactions inline with your code

Next Steps