Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Functions에서 시계열 사용

먼저 온톨로지에 TSP를 구성하고 Functions 코드 저장소에 사용할 객체 유형을 가져옵니다. 객체 기반 함수는 해당 객체의 시계열 속성을 직접 사용할 수 있습니다. Live preview에서 입력과 결과를 확인하거나 함수 버전을 게시하여 다른 앱에서 사용합니다.

아래 Aircraft, MachineRoot와 ObjectTypeEx는 예제의 생성된 온톨로지 타입을 뜻합니다. 실제 저장소에서 가져온 모델과 숫자형 TSP 이름을 맞춥니다. 예제 함수들은 실제 객체를 입력으로 받습니다.

Python으로 읽기

FoundryTS는 Functions와 호환되지 않습니다. Python 함수에서는 OSDK의 TSP 접근을 사용합니다. to_pandas 또는 to_polars 결과에는 timestamp와 value 두 열이 있습니다. timestamp는 해당 라이브러리의 시각 자료형, value는 숫자 또는 범주 문자열입니다.

다음 평균 예제는 값이 있는 숫자형 altimeter TSP를 전제로 합니다.

from functions.api import function
from ontology_sdk.ontology.objects import Aircraft


@function
def aircraft_altimeter_mean_pandas(aircraft: Aircraft) -> float:
    dataframe = aircraft.altimeter.to_pandas(all_time=True)
    return float(dataframe["value"].mean())

Polars에서는 같은 열을 표현식으로 집계합니다.

import polars as pl
from functions.api import function
from ontology_sdk.ontology.objects import Aircraft


@function
def aircraft_altimeter_mean_polars(aircraft: Aircraft) -> float:
    dataframe = aircraft.altimeter.to_polars(all_time=True)
    return float(dataframe.select(pl.col("value").mean()).item())

Python 함수에서 시계열 반환

timeseries-sdk의 TimeSeries.serialize는 timestamp와 숫자형 value를 가진 pandas DataFrame을 list[bytes]로 직렬화합니다. Quiver의 Code function time series 카드에서 표시할 수 있습니다. 범주형 시계열 출력은 지원하지 않습니다.

다음은 가상 관측 세 개를 반환하는 예시입니다.

import pandas as pd
from functions.api import function
from timeseries_sdk.types import TimeSeries


@function
def sample_series() -> list[bytes]:
    dataframe = pd.DataFrame({
        "timestamp": [
            pd.Timestamp("2025-03-19 08:00:00"),
            pd.Timestamp("2025-03-19 09:00:00"),
            pd.Timestamp("2025-03-19 10:00:00"),
        ],
        "value": [1.0, 2.0, 2.5],
    })
    return TimeSeries.serialize(dataframe)

다음 고도계 예제는 시간순이며 같은 Timestamp가 중복되지 않는 유한한 숫자 관측을 전제로 합니다. 최대 열 개 관측의 이동 평균을 구하고 초당 변화량을 계산한 뒤 최대 절댓값으로 정규화합니다. 첫 변화량처럼 계산 결과가 없는 위치는 0으로 둡니다.

from functions.api import function
from ontology_sdk.ontology.objects import Aircraft
from timeseries_sdk.types import TimeSeries


@function
def normalized_altimeter_rate(aircraft: Aircraft) -> list[bytes]:
    dataframe = aircraft.altimeter.to_pandas(all_time=True)
    if dataframe.empty:
        return TimeSeries.serialize(dataframe)

    dataframe["value"] = dataframe["value"].rolling(
        window=10, min_periods=1
    ).mean()
    elapsed_seconds = dataframe["timestamp"].diff().dt.total_seconds()
    dataframe["value"] = (
        dataframe["value"].diff() / elapsed_seconds
    ).fillna(0)

    max_absolute_rate = dataframe["value"].abs().max()
    if max_absolute_rate > 0:
        dataframe["value"] = dataframe["value"] / max_absolute_rate

    return TimeSeries.serialize(dataframe)

라이브러리 설치와 Quiver 연결은 함수 기반 시계열을 따릅니다.

TypeScript v1

다음 클래스는 숫자형 temperatureId TSP를 가진 MachineRoot 모델을 사용합니다. 누락된 속성은 optional chaining으로 처리하여 undefined를 반환할 수 있습니다.

import { Double, Function, Timestamp } from "@foundry/functions-api";
import { MachineRoot } from "@foundry/ontology-api";

export class TemperatureFunctions {
    @Function()
    public async getLatestTemperature(
        machine: MachineRoot,
    ): Promise<Double | undefined> {
        const point = await machine.temperatureId?.getLastPointV2();
        return point?.value;
    }

    @Function()
    public async getEarliestTemperature(
        machine: MachineRoot,
    ): Promise<Double | undefined> {
        const point = await machine.temperatureId?.getFirstPointV2();
        return point?.value;
    }

    @Function()
    public async getAverageTemperature(
        machine: MachineRoot,
    ): Promise<Double | undefined> {
        const result = await machine.temperatureId?.aggregate()
            .overEntireRange()
            .mean()
            .compute();
        return result?.mean;
    }

    @Function()
    public async getAverageTemperatureChange(
        machine: MachineRoot,
    ): Promise<Double | undefined> {
        const result = await machine.temperatureId?.derivative()
            .aggregate()
            .overEntireRange()
            .mean()
            .compute();
        return result?.mean;
    }

    @Function()
    public async getAverageTemperatureOverRange(
        machine: MachineRoot,
        start: Timestamp,
        end: Timestamp,
    ): Promise<Double | undefined> {
        const result = await machine.temperatureId?.timeRange({ min: start, max: end })
            .aggregate()
            .overEntireRange()
            .mean()
            .compute();
        return result?.mean;
    }
}

첫 점과 마지막 점에서 값 또는 시각을 사용할 수 있습니다. 평균과 변화율 평균은 서로 다른 함수이며, timeRange로 제한한 뒤 overEntireRange를 적용하면 제한한 구간을 집계합니다.

TypeScript v2 OSDK 접근

숫자형 timeseriesProp이 있는 ObjectTypeEx를 가져온 SDK와 실제 조회된 객체를 사용하는 예시입니다. 아래 헬퍼는 필요한 조회만 실행하고 결과를 반환합니다. getAllPoints는 점 배열의 Promise를 반환합니다.

import type { Osdk } from "@osdk/client";
import type { TimeSeriesPoint } from "@osdk/api";
import type { ObjectTypeEx } from "@ontology/sdk";

export async function allPoints(
    object: Osdk.Instance<ObjectTypeEx>,
): Promise<TimeSeriesPoint<number>[] | undefined> {
    return object.timeseriesProp?.getAllPoints();
}

export async function previousHourPoints(
    object: Osdk.Instance<ObjectTypeEx>,
): Promise<TimeSeriesPoint<number>[] | undefined> {
    return object.timeseriesProp?.getAllPoints({
        $before: 1,
        $unit: "hours",
    });
}

export async function absoluteRangePoints(
    object: Osdk.Instance<ObjectTypeEx>,
): Promise<TimeSeriesPoint<number>[] | undefined> {
    return object.timeseriesProp?.getAllPoints({
        $startTime: "2022-08-13T12:34:56Z",
        $endTime: "2022-08-14T12:34:56Z",
    });
}

export async function firstPoint(
    object: Osdk.Instance<ObjectTypeEx>,
): Promise<TimeSeriesPoint<number> | undefined> {
    return object.timeseriesProp?.getFirstPoint();
}

export async function lastPoint(
    object: Osdk.Instance<ObjectTypeEx>,
): Promise<TimeSeriesPoint<number> | undefined> {
    return object.timeseriesProp?.getLastPoint();
}

상대 범위는 $before 또는 $after와 $unit을 사용합니다. 단위는 milliseconds, seconds, minutes, hours, days, weeks, months, years 등을 사용할 수 있습니다. 절대 범위는 $startTime과 $endTime으로 지정합니다. 반환 점의 value는 측정값이고 time은 ISO8601 시각 문자열입니다.