> 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/plattform/platform-core/script-engine/writing-python-scripts.md).

# Python-Skripte schreiben

## Python-Skripte schreiben

{% hint style="warning" %}
Mit der Einführung von BuildingPro Suites Version 12.2 wurden wichtige Änderungen vorgenommen, die eine Anpassung der Skripte an das neue API-Design erfordern.
{% endhint %}

## Skriptdefinition

Wenn im BuildingPro-Suites-System ein neues Skript erstellt wird, wird automatisch ein Funktionskopf generiert. Dieser Kopf enthält zwei Parameter:

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

Die Funktionsdeklaration sieht so aus:

```python
# Imports dürfen nur innerhalb der Funktion hinzugefügt werden
# Die Funktionsdefinition nicht ändern oder löschen
def UserFunction(id, eliona):
	# füge hier deinen Code ein
```

### Module importieren

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

Beispiel:

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

***

## Methoden des BuildingPro-Suites-Objekts

Das **`eliona`** Objekt stellt eine Reihe von Methoden bereit, mit denen Benutzer mit dem BuildingPro-Suites-System interagieren können. 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><th></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><td></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 Rechner, damit sie verarbeitet und im Heap gespeichert werden.</td><td></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><td></td></tr><tr><td><strong>GetAll</strong></td><td>`ids: list[int</td><td>str]<code>,</code> `subtype: str`</td><td>Ruft alle Datenpunkte eines bestimmten Subtyps für eine Liste von Assets ab und gibt sie als Dictionary zurück (GAI → Daten).</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><td></td></tr><tr><td><strong>MakeSource</strong></td><td><code>id: int</code></td><td>Erzeugt eine Quellzeichenfolge für Heap-Operationen basierend auf der Funktions-ID.</td><td></td></tr><tr><td><strong>OpenFile</strong></td><td><code>name: str</code>, <code>mode: str</code></td><td>Öffnet eine Datei im Arbeitsverzeichnis von BuildingPro Suites (analog zu Python’s <code>open()</code>).</td><td></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 noch nicht vorhanden).</td><td></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><td></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><td></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 ein oder mehrere <code>TrendRecord</code> Datensätze in das System.</td><td></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 einem festen Raster über einen Zeitraum.</td><td></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>Gibt das zuletzt kumulierte Aggregat im ausgewählten Raster zurück (einschl. <code>last_ts</code>).</td><td></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) – Datensubtyp, z. B., `"input"`
* `attribute: str` (erforderlich) – Attributname, z. B., `"Aussentemperatur"`

#### Beispielcode:

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

**Beispielausgabe:**

```python
23.5
```

***

### SetHeap

**Beschreibung:** Sendet ein Dictionary von Werten an den Rechner, um es 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 sie 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;"
)
```

**Beispielausgabe:**

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

***

### MakeSource

**Beschreibung:** Generiert eine Quellzeichenfolge (z. B. `"ssr:123"`) für Heap-Operationen basierend auf der Funktions-ID.

**Parameter:**

* `id: int` (erforderlich)

**Code-Beispiel:**

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

***

### OpenFile

**Beschreibung:** Öffnet eine Datei im Arbeitsverzeichnis von BuildingPro Suites (analog zu Python’s `open()`).

**Parameter:**

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

**Code-Beispiel:**

```python
f = 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 der angegebenen Startzeit.

**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 ein oder mehrere `TrendRecord` Datensätze in das 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 einem festen 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-Dauer, z. B., `"PT1H"` für stündlich
* `start: datetime` (erforderlich)
* `end: datetime` (optional, Standard: `now()`)
* `recs: TrendRecord | list[TrendRecord]` (erforderlich)

**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
)
```

**Beispielausgabe-Struktur:**

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

***

### GetLastAggregate

**Beschreibung:** Gibt das zuletzt kumulierte Aggregat im ausgewählten Raster zurück (einschließlich `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"
)
```

**Beispielausgabe-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 Datenmanipulation

Dieses Beispiel zeigt, wie ein Skript einen Zufallswert erzeugt und 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 `random` Modul.
* Ein Dictionary `data` wird erstellt, das einen Schlüssel `power_val` enthält, dem ein Zufallswert zwischen 10 und 100 zugewiesen wird.
* Der erzeugte Wert wird in den Heap des `TestInactIn` Assets mit der `SetHeap` Methode geschrieben.

***

## Daten abrufen und ändern

In diesem Beispiel wird der Wert eines Attributs von einem Asset abgerufen, geändert 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 `datetime` Modul.
* Der aktuelle Wert des `power_val` Attributs wird aus dem Heap des `TestInactIn` Assets abgerufen.
* Dieser Wert wird verdreifacht und als `energy_val`.

***

## Erweiterte Funktionen und SQL-Abfragen

Mit der `SQLQuery` Methode können beliebige SQL-Abfragen direkt aus dem Skript 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 über das Asset mit der GAI `TestInactIn`.
* Das Ergebnis kann dann 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/plattform/platform-core/script-engine/writing-python-scripts.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.
