Skip to content

Insights

Insights & Data Tags

In the Kelvin UI and in the Kelvin SDK, Data Tags are now known as Insights.

In the Kelvin SDK, the Data Tag names are deprecated in favor of the Insight names. Use Insight, app.on_insight and filters.is_insight instead of DataTag, app.on_data_tag and filters.is_data_tag in new code.

Backwards compatibility only

DataTag, app.on_data_tag and filters.is_data_tag still work, but for backwards compatibility only. Any new programs should use Insight, app.on_insight and filters.is_insight.

If possible, update your older programs that use the old names to the new ones to future-proof them.

Note

The rename applies to the Kelvin SDK only. The Kelvin API and the Kelvin API Client (Python) still use the Data Tag names, for example app.api.data_tag. In app.yaml the section is still data_tags.

Insights Management

You can also manage your insights using the Kelvin SDK and Kelvin API.

You can read all the details in the Platform Administration in the Insights section.

Insight Messages

Applications can receive Insight messages published by other Applications or created manually through the Kelvin UI. This allows your Application to react to labeled events on Asset time series data.

Each received Insight has an acceptance attribute, set by the platform. It is accepted, or snoozed while the Insight type is snoozed for the Asset.

Live

Receive insights in real time as they are published. Use this for event-driven reactions within a running Application.

app.yaml setup

To consume insights, declare the tag names your Application should receive in the data_tags.inputs section of your app.yaml. Each entry is the tag name as a string:

app.yaml Example
1
2
3
4
data_tags:
  inputs:
    - cycle_detected
    - temperature_too_high

Decorator (Preferred)

The preferred method is to use the @app.on_insight decorator. You can filter by tag name using app.app_configuration to limit processing to only the tags your Application cares about.

on_insight Decorator Example
from kelvin.application import KelvinApp
from kelvin.message import Insight

app = KelvinApp()

@app.on_insight
async def on_insight(insight: Insight):
    configured_tags = app.app_configuration.get("consume_tag_names", [])
    if configured_tags and insight.tag_name not in configured_tags:
        return

    logger.info(
        "Insight received",
        asset=getattr(insight.resource, "asset", None),
        tag_name=insight.tag_name,
        resource=str(insight.resource),
    )

app.run()

Callback

For advanced scenarios, assign a handler function directly to app.on_insight:

on_insight Callback Example
from kelvin.application import KelvinApp
from kelvin.message import Insight

app = KelvinApp()

async def on_insight(insight: Insight) -> None:
    logger.info("Received insight", tag_name=insight.tag_name, resource=str(insight.resource))

app.on_insight = on_insight

app.run()

Historical

Query insights over a past time range using the Kelvin API. Use this for catching events that occurred before your Application started, or for periodic reconciliation.

Historical Data Tag Queries

In addition to receiving live insights via on_insight, you can query historical insights over a time range using app.api.data_tag.list_data_tag(). The Kelvin API Client (Python) keeps the Data Tag names. This is useful for catching events that occurred before your Application started, or for periodic reconciliation.

API permission required

You must declare the required read permission for data_tag in your app.yaml. Confirm the exact permission string from the method docstring in kelvin.api.client.api.data_tag before setting it.

app.yaml — API permissions
api_permissions:
  - <permission-string-from-docstring>

See the API Integration page for full details on using app.api.

The example below fetches all "Temperature Too High" tags for a specific Asset over the past 3 days:

Fetch Historical Data Tags
from datetime import datetime, timedelta, timezone
from kelvin.logs import logger

TARGET_TAG = "Temperature Too High"

async def fetch_recent_temperature_high_tags(app, asset_name: str):
    end_time = datetime.now(timezone.utc)
    start_time = end_time - timedelta(days=3)
    asset_krn = f"krn:asset:{asset_name}"

    tags = await app.api.data_tag.list_data_tag(
        data={
            "start_date": start_time,
            "end_date": end_time,
        },
    )

    matching = [
        tag for tag in tags
        if tag.tag_name == TARGET_TAG and str(tag.resource) == asset_krn
    ]

    for tag in matching:
        logger.info(
            "Historical data tag",
            tag_name=tag.tag_name,
            resource=str(tag.resource),
            start_date=tag.start_date,
        )

Recommended architecture

  • Use on_insight for live events.
  • Add a startup task or scheduled job (for example, running every hour) to call the historical fetch. This ensures you do not miss events caused by downtime or redeployments.

See Background Tasks for how to schedule periodic work in a Application.