Skip to content

Zelos Agent SDK

One Python entry point — connect() — for talking to a running Zelos Agent. Browse signals, query time-series, run actions, manage extensions, and re-open .trz files with the same handle.

What You Can Do

  • Browse Live Signals

    See what's flowing through the agent right now, with type and unit metadata.

  • Query Time-Series

    Pull a window of samples — raw or downsampled — into Arrow or pandas.

  • Read Latest Values

    Get the most recent reading for one signal or many, with units attached.

  • Save and Re-Open .trz

    Capture a slice of live data, then re-open the file later with the same API.

  • Run Actions

    Execute typed Actions exposed by the agent or its extensions.

  • Manage Extensions

    List, start, stop, restart, and configure installed extensions.

Connect

from zelos_sdk.agent import connect

with connect("localhost:2300") as agent:
    print(agent.target)        # "http://localhost:2300"
    print(agent.health())      # agent-reported status string

connect() returns an Agent you use as a context manager (or close explicitly with agent.close()). With no argument, it reads ZELOS_AGENT_URL, falling back to http://localhost:2300. A bare host or host:port gets http:// added automatically.

Need more detail than health()?

agent.info() returns a richer snapshot — health, log/config dirs, memory, settings. Anything that can't be loaded is None and named in info.failures.

A 60-Second Tour

One script that exercises every piece of the SDK. Each block is independent — comment out the ones you don't need.

from zelos_sdk.agent import connect

with connect("localhost:2300") as agent:
    # 1. Discover what's live
    catalog = agent.signals()
    voltage = catalog.search("voltage")        # case-insensitive substring
    paths = [s.path for s in voltage[:3]]

    # 2. Pull the last 30 seconds, downsampled for plotting
    frame = agent.query(paths, start="-30s", end="now", downsample=400)
    df = frame.to_pandas()                     # pandas DataFrame, UTC index
    series = frame[paths[0]]                   # SignalSeries with units
    print(series.legend, "min:", series.min(), "max:", series.max())

    # 3. Read the most recent value of each signal
    for path, lv in agent.latest(paths).items():
        print(path, "=", lv.formatted())

    # 4. Snapshot + change stream over a 5-second window
    window = agent.window(paths, start="-5s", duration=5.0)
    print(len(window.snapshot), "opening values,", len(window.changes), "changes")

    # 5. Watch live values for ~5 seconds
    for tick in agent.watch(paths, interval=1.0, until=5.0):
        print({p: lv.formatted() for p, lv in tick.items()})

    # 6. Save the last minute, then re-open it
    agent.export("/tmp/run.trz", start="-1m", overwrite=True)
    trace = agent.open_trace("/tmp/run.trz")
    offline = trace.query(paths, relative_start=0, relative_end=30)
    print(len(offline), "rows from the saved file")

    # 7. List actions and extensions
    print([a.name for a in agent.actions.list()])
    for ext in agent.extensions.list():
        print(ext.id, ext.version, ext.state)

Wildcards work anywhere a path does

agent.query("bus0/*.cell_voltage", ...), agent.latest("eth0/sensor_events.event_type"), agent.window("bus1/*", ...) all expand against the live catalog. Mix exact paths and patterns in a list.

Units flow through arithmetic

Series carry their units, so cell_voltage * pack_current arrives as power in V·A, and .integrate() over time gives energy in V·A·s. .derivative(), .clip(), and .where() compose the same way.

Where to Next

  • Quick Start

    Connect to an agent and run your first query in under 2 minutes.

  • Query Live Data

    Time-series queries, latest values, replay windows, and live watching.

  • Open Trace Files

    Re-open .trz files individually or as overlays.

  • Run Actions

    Inspect schemas, execute typed Actions, and handle results.

  • Manage Extensions

    Discover, start, stop, and configure installed extensions.

Resources