> For the complete documentation index, see [llms.txt](https://docs.buildings.ability.abb/collection/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.buildings.ability.abb/collection/german-14.2-freezed/dokumentation/engineering/skript-engine/python-skripte-schreiben.md).

# Python Skripte schreiben

{% hint style="warning" %}
Mit der Einführung von Eliona Version 12.2 wurden wichtige Änderungen vorgenommen, die es erforderlich machen, Skripte anzupassen, um das neue API-Design zu nutzen.
{% endhint %}

## Skript-Definition

Wenn ein neues Skript im Eliona-System erstellt wird, wird automatisch ein Funktionsheader generiert. Dieser Header enthält zwei Parameter:

* **`id`**: Die eindeutige ID des Skripts.
* **`eliona`**: Ein Objekt, über das der Benutzer mit dem Eliona-System interagieren kann.

Der Funktionsheader sieht wie folgt aus:

```python
# you may add imports only inside the function
# don't change or delete the function definition
def UserFunction(id, eliona):
	# add your code here
```

### Importieren von Modulen

Alle notwendigen Module müssen innerhalb der Funktion importiert werden. Es ist wichtig, dass Module nur innerhalb der Funktion importiert und keine globalen Importe verwendet werden.

Beispiel:

```python
def UserFunction(id, eliona):
    import random
    # Weitere Codezeilen folgen
```

***

## Methoden des Eliona-Objekts

Das **`eliona`**-Objekt stellt eine Reihe von Methoden zur Verfügung, die es Benutzern ermöglichen, mit dem Eliona-System zu interagieren. Hier sind die wichtigsten Methoden zusammen mit ihren Parametern und Beschreibungen:

<table data-full-width="true"><thead><tr><th width="173">Methode</th><th>Parameter</th><th>Beschreibung</th></tr></thead><tbody><tr><td><strong>GetHeap</strong></td><td><code>gai: str</code>, <code>subtype: str</code>, <code>attribute: str</code></td><td>Ruft den aktuellen Wert eines Attributs oder das gesamte Daten-JSON eines Assets aus dem Heap ab.</td></tr><tr><td><strong>SetHeap</strong></td><td><code>gai: str</code>, <code>subtype: str</code>, <code>data: dict</code>, <code>source: str</code></td><td>Sendet Daten an den Calculator, um sie zu verarbeiten und im Heap zu speichern.</td></tr><tr><td><strong>GetAssetIDByGAI</strong></td><td><code>gai: str</code></td><td>Gibt die numerische Asset-ID für die angegebene GAI zurück.</td></tr><tr><td><strong>GetAll</strong></td><td><code>ids: list[intstr], subtype: str</code></td><td>Ruft alle Daten für eine Liste von Assets ab, die durch ihre IDs und einen Subtyp identifiziert werden.</td></tr><tr><td><strong>SQLQuery</strong></td><td><code>query: str</code></td><td>Führt eine beliebige SQL-Abfrage aus und gibt die Ergebnisse als Liste von Tupeln zurück.</td></tr><tr><td><strong>MakeSource</strong></td><td><code>id: int</code></td><td>Erzeugt einen Quell-String für Heap-Operationen auf Basis der Function-ID.</td></tr><tr><td><strong>OpenFile</strong></td><td><code>name: str</code>, <code>mode: str</code></td><td>Öffnet eine Datei im Eliona-Arbeitsverzeichnis (analog zu Python’s <code>open()</code>).</td></tr><tr><td><strong>AddAssetTag</strong></td><td><code>gai: str</code>, <code>tag: str</code></td><td>Fügt einem Asset ein Tag hinzu (falls nicht schon vorhanden).</td></tr><tr><td><strong>RemoveAssetTag</strong></td><td><code>gai: str</code>, <code>tag: str</code></td><td>Entfernt ein Tag von einem Asset (falls vorhanden).</td></tr><tr><td><strong>GetTrendRecords</strong></td><td><code>asset_id: int</code>, <code>subtype: str</code>, <code>attr: str</code>, <code>begin: datetime</code></td><td>Ruft historische Messwerte als Liste von <code>TrendRecord(ts, value)</code> ab dem angegebenen Zeitpunkt ab.</td></tr><tr><td><strong>WriteTrendRecords</strong></td><td><code>asset_id: int</code>, <code>subtype: str</code>, <code>attr: str</code>, <code>`recs: TrendRecord</code></td><td>Schreibt einen oder mehrere <code>TrendRecord</code>-Datensätze ins System.</td></tr><tr><td><strong>GetAggregate</strong></td><td><code>agg: Aggregate</code>, <code>asset_id: int</code>, <code>subtype: str</code>, <code>attr: str</code>,<code>raster: str</code>, <code>start: datetime</code>,<code>end: datetime = now()</code></td><td>Berechnet aggregierte Werte (Avg, Sum, Cusum) in festem Raster über einen Zeitraum.</td></tr><tr><td><strong>GetLastAggregate</strong></td><td><code>agg: Aggregate</code>, <code>asset_id: int</code>, <code>subtype: str</code>, <code>attr: str</code>, <code>raster: str</code></td><td>Liefert das aktuellste kumulierte Aggregate im gewählten Raster (inkl. <code>last_ts</code>).</td></tr></tbody></table>

***

## Beispielskripte

### GetHeap

**Beschreibung:**\
Ruft den aktuellen Wert eines Attributs oder das gesamte JSON eines Assets aus dem Heap ab.

**Parameter:**

* `gai: str` (erforderlich) – GAI des Assets, z. B. `"K86_WP01"`
* `subtype: str` (erforderlich) – Daten-Subtyp, z. B. `"input"`
* `attribute: str` (erforderlich) – Attributname, z. B. `"Aussentemperatur"`

**Code-Beispiel:**

```python
value = eliona.GetHeap("K86_WP01", "input", "Aussentemperatur")
```

**Beispiel-Output:**

```
23.5
```

***

### SetHeap

**Beschreibung:**\
Sendet ein Wörterbuch von Werten an den Calculator, um sie zu verarbeiten und im Heap zu speichern.

**Parameter:**

* `gai: str` (erforderlich)
* `subtype: str` (erforderlich)
* `data: dict` (erforderlich) – z. B. `{"Aussentemperatur": 23.5}`
* `source: str` (erforderlich) – typischerweise `eliona.MakeSource(id)`

**Code-Beispiel:**

```python
data   = {"Aussentemperatur": 23.5}
source = eliona.MakeSource(id)
eliona.SetHeap("K86_WP01", "input", data, source)
```

***

### GetAssetIDByGAI

**Beschreibung:**\
Gibt die numerische Asset-ID für die angegebene GAI zurück.

**Parameter:**

* `gai: str` (erforderlich)

**Code-Beispiel:**

```python
asset_id = eliona.GetAssetIDByGAI("K86_WP01")
```

***

### GetAll

**Beschreibung:**\
Ruft alle Datenpunkte eines bestimmten Subtyps für eine Liste von Assets ab und gibt diese als Dictionary zurück (GAI → Daten).

**Parameter:**

* `ids: list[int|str]` (erforderlich) – z. B. `["K86_WP01", 1073]`
* `subtype: str` (erforderlich)

**Code-Beispiel:**

```python
all_data = eliona.GetAll(["K86_WP01"], "input")
```

***

### SQLQuery

**Beschreibung:**\
Führt eine beliebige SQL-Abfrage aus und gibt die Ergebnisse als Liste von Tupeln zurück.

**Parameter:**

* `query: str` (erforderlich)

**Code-Beispiel:**

```python
res = eliona.SQLQuery(
    "SELECT data->>'Aussentemperatur' "
    "FROM public.heap "
    "WHERE gai='K86_WP01' AND subtype='input' "
    "ORDER BY timestamp DESC LIMIT 1;"
)
```

**Beispiel-Output:**

```css
[('23.5',)]
```

***

### MakeSource

**Beschreibung:**\
Erzeugt einen Quell-String (z. B. `"ssr:123"`) für Heap-Operationen basierend auf der Function-ID.

**Parameter:**

* `id: int` (erforderlich)

**Code-Beispiel:**

```python
pythonKopierenBearbeitensrc = eliona.MakeSource(id)
```

***

### OpenFile

**Beschreibung:**\
Öffnet eine Datei im Eliona-Arbeitsverzeichnis (analog zu Python’s `open()`).

**Parameter:**

* `name: str` (erforderlich) – Dateiname, z. B. `"log.txt"`
* `mode: str` (erforderlich) – z. B. `"w"`, `"r"`

**Code-Beispiel:**

```python
pythonKopierenBearbeitenf = eliona.OpenFile("aussentemp_log.txt", "w")
f.write("Temperatur: 23.5\n")
f.close()
```

***

### AddAssetTag

**Beschreibung:**\
Fügt einem Asset ein Tag hinzu, wenn es noch nicht zugewiesen ist.

**Parameter:**

* `gai: str` (erforderlich)
* `tag: str` (erforderlich)

**Code-Beispiel:**

```python
eliona.AddAssetTag("K86_WP01", "has-aussentemp")
```

***

### RemoveAssetTag

**Beschreibung:**\
Entfernt ein Tag von einem Asset, falls vorhanden.

**Parameter:**

* `gai: str` (erforderlich)
* `tag: str` (erforderlich)

**Code-Beispiel:**

```python
eliona.RemoveAssetTag("K86_WP01", "has-aussentemp")
```

***

### GetTrendRecords

**Beschreibung:**\
Lädt eine Liste historischer Messwerte (`TrendRecord(ts, value)`) ab dem angegebenen Start-Zeitpunkt.

**Parameter:**

* `asset_id: int` (erforderlich)
* `subtype: str` (erforderlich)
* `attr: str` (erforderlich)
* `begin: datetime` (erforderlich)

**Code-Beispiel:**

```python
from datetime import datetime, timedelta

aid   = eliona.GetAssetIDByGAI("K86_WP01")
begin = datetime.now() - timedelta(hours=1)
records = eliona.GetTrendRecords(aid, "input", "Aussentemperatur", begin)
```

***

### WriteTrendRecords

**Beschreibung:**\
Schreibt einen oder mehrere `TrendRecord`-Datensätze ins System.

**Parameter:**

* `asset_id: int` (erforderlich)
* `subtype: str` (erforderlich)
* `attr: str` (erforderlich)
* `recs: TrendRecord | list[TrendRecord]` (erforderlich)

**Code-Beispiel:**

```python
from datetime import datetime, timedelta
import eliona_types

aid = eliona.GetAssetIDByGAI("K86_WP01")
now = datetime.now()
r1  = eliona_types.TrendRecord(now, 18.7)
r2  = eliona_types.TrendRecord(now + timedelta(minutes=30), 19.2)
eliona.WriteTrendRecords(aid, "input", "Aussentemperatur", [r1, r2])
```

***

### GetAggregate

**Beschreibung:**\
Berechnet aggregierte Werte (Durchschnitt, Summe, kumulative Summe) in festem Raster über einen Zeitraum.

**Parameter:**

* `agg: Aggregate` (erforderlich) – z. B. `eliona_types.Aggregate.Avg`
* `asset_id: int` (erforderlich)
* `subtype: str` (erforderlich)
* `attr: str` (erforderlich)
* `raster: str` (erforderlich) – ISO 8601-Duration, z. B. `"PT1H"` für stündlich
* `start: datetime` (erforderlich)
* `end: datetime` (optional, default: `now()`)

**Code-Beispiel:**

```python
from datetime import datetime, timedelta
import eliona_types

aid   = eliona.GetAssetIDByGAI("K86_WP01")
end   = datetime.now()
start = end - timedelta(days=1)
aggs  = eliona.GetAggregate(
    eliona_types.Aggregate.Avg,
    aid, "input", "Aussentemperatur",
    "PT1H", start, end
)
```

**Beispiel-Output-Struktur:**

```python
[
  TrendAggregate(ts=<datetime>, cnt=<int>, avg=<float>,
                 sum=<float>, first=<float>,
                 min=<float>, max=<float>, last=<float>),
  ...
]
```

***

### GetLastAggregate

**Beschreibung:**\
Gibt das aktuellste kumulierte Aggregate im gewählten Raster zurück (inklusive `last_ts`).

**Parameter:**

* `agg: Aggregate` (erforderlich)
* `asset_id: int` (erforderlich)
* `subtype: str` (erforderlich)
* `attr: str` (erforderlich)
* `raster: str` (erforderlich)

**Code-Beispiel:**

```python
import eliona_types

aid  = eliona.GetAssetIDByGAI("K86_WP01")
last = eliona.GetLastAggregate(
    eliona_types.Aggregate.Cusum,
    aid, "input", "Aussentemperatur", "P1D"
)
```

**Beispiel-Output-Struktur:**

```python
RunningAggregate(
  ts=<datetime>, cnt=<int>, avg=<float>,
  sum=<float>, first=<float>,
  min=<float>, max=<float>, last=<float>,
  last_ts=<datetime>
)
```

***

### Einfaches Skript zur Manipulation von Daten

Dieses Beispiel zeigt, wie ein Skript einen zufälligen Wert generiert und diesen in den Heap eines Assets schreibt:

```python
def UserFunction(id, eliona):
    import random

    data = {
        "power_val": random.randint(10, 100)
    }

    eliona.SetHeap("TestInactIn", "input", data, eliona.MakeSource(id))
```

**Beschreibung:**

* Das Skript importiert das Modul `random`.
* Es wird ein Wörterbuch `data` erstellt, das einen Schlüssel `power_val` enthält, dem ein zufälliger Wert zwischen 10 und 100 zugewiesen wird.
* Der generierte Wert wird mit der Methode `SetHeap` in den Heap des Assets `TestInactIn` geschrieben.

***

### Daten abrufen und modifizieren

In diesem Beispiel wird der Wert eines Attributs von einem Asset abgerufen, modifiziert und in einem anderen Asset gespeichert:

```python
def UserFunction(id, eliona):
    from datetime import datetime

    heap = eliona.GetHeap("TestInactIn", "input")

    data = {
        "energy_val": heap["power_val"] * 3
    }

    eliona.SetHeap("TestInactIn", "input", data, eliona.MakeSource(id))
```

**Beschreibung:**

* Das Skript importiert das Modul `datetime`.
* Der aktuelle Wert des Attributs `power_val` wird aus dem Heap des Assets `TestInactIn` abgerufen.
* Dieser Wert wird verdreifacht und als `energy_val` in dasselbe Asset geschrieben.

***

### Erweiterte Funktionen und SQL-Abfragen

Mit der Methode `SQLQuery` können beliebige SQL-Abfragen direkt aus dem Skript heraus ausgeführt werden:

```python
def UserFunction(id, eliona):
    result = eliona.SQLQuery("SELECT * FROM public.asset WHERE gai = 'TestInactIn';")
    # Weitere Verarbeitung des Ergebnisses
```

**Beschreibung:**

* Die SQL-Abfrage ruft alle Informationen zu dem Asset mit der GAI `TestInactIn` ab.
* Das Ergebnis kann anschließend weiterverarbeitet werden.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.buildings.ability.abb/collection/german-14.2-freezed/dokumentation/engineering/skript-engine/python-skripte-schreiben.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
