> 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 Anpassungen der Skripte erfordern, um das neue API-Design zu nutzen.
{% 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.

Der Funktionskopf sieht wie folgt aus:

```python
# Sie dürfen Importanweisungen nur innerhalb der Funktion hinzufügen
# Funktionsdefinition nicht ändern oder löschen
def UserFunction(id, eliona):
	# fügen Sie hier Ihren Code ein
```

### Module importieren

Alle notwendigen 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

Die **`eliona`** Das Objekt bietet eine Reihe von Methoden, die es Benutzern ermöglichen, mit dem BuildingPro Suites-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><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, um sie zu verarbeiten und im Heap zu speichern.</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 (GAI → Daten) zurück.</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 einen Quellstring 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 Pythons <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 einen 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 (Durchschnitt, Summe, Kumulierung) 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 berechnete kumulative Aggregat im ausgewählten Raster zurück (einschließlich <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"`

#### Beispiel-Code:

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

**Beispiel-Ausgabe:**

```python
23.5
```

***

### SetHeap

**Beschreibung:** Sendet ein Dictionary mit Werten an den Rechner, 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 sie als Dictionary (GAI → Daten) zurück.

**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-Ausgabe:**

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

***

### MakeSource

**Beschreibung:** Erzeugt einen Quellstring (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 Pythons `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 dem angegebenen Startzeitpunkt.

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

**Beispiel-Ausgabe-Struktur:**

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

***

### GetLastAggregate

**Beschreibung:** Gibt das zuletzt berechnete kumulative 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"
)
```

**Beispiel-Ausgabe-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 ihn 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 geschrieben unter Verwendung der `SetHeap` Methode.

***

## Daten abrufen und ändern

In diesem Beispiel wird der Wert eines Attributs aus 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 im selben Asset unter `energy_val`.

***

## gespeichert.

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 ab `TestInactIn`.
* 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/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.
