> 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/english-v14/documentation/engineering/skript-engine/python-skripte-schreiben.md).

# Write Python scripts

{% hint style="warning" %}
With the introduction of Eliona version 12.2, important changes were made that require scripts to be adapted to use the new API design.
{% endhint %}

## Script definition

When a new script is created in the Eliona system, a function header is generated automatically. This header contains two parameters:

* **`id`**: The unique ID of the script.
* **`eliona`**: An object through which the user can interact with the Eliona system.

The function header looks like this:

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

### Importing modules

All necessary modules must be imported within the function. It is important that modules are imported only within the function and that no global imports are used.

Example:

```python
def UserFunction(id, eliona):
    import random
    # Further lines of code follow
```

***

## Methods of the Eliona object

The **`eliona`**&#x54;he object provides a range of methods that allow users to interact with the Eliona system. Here are the most important methods along with their parameters and descriptions:

<table data-full-width="true"><thead><tr><th width="173">Method</th><th>Parameter</th><th>Description</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>Retrieves the current value of an attribute or the entire data JSON of an asset from the heap.</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>Sends data to the Calculator to process it and store it in the heap.</td></tr><tr><td><strong>GetAssetIDByGAI</strong></td><td><code>gai: str</code></td><td>Returns the numeric asset ID for the specified GAI.</td></tr><tr><td><strong>GetAll</strong></td><td><code>ids: list[intstr], subtype: str</code></td><td>Retrieves all data for a list of assets identified by their IDs and a subtype.</td></tr><tr><td><strong>SQLQuery</strong></td><td><code>query: str</code></td><td>Executes any SQL query and returns the results as a list of tuples.</td></tr><tr><td><strong>MakeSource</strong></td><td><code>id: int</code></td><td>Generates a source string for heap operations based on the function ID.</td></tr><tr><td><strong>OpenFile</strong></td><td><code>name: str</code>, <code>mode: str</code></td><td>Opens a file in the Eliona working directory (analogous to Python’s <code>open()</code>).</td></tr><tr><td><strong>AddAssetTag</strong></td><td><code>gai: str</code>, <code>tag: str</code></td><td>Adds a tag to an asset (if it is not already present).</td></tr><tr><td><strong>RemoveAssetTag</strong></td><td><code>gai: str</code>, <code>tag: str</code></td><td>Removes a tag from an asset (if present).</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>Retrieves historical measurements as a list of <code>TrendRecord(ts, value)</code> from the specified time onward.</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>Writes one or more <code>TrendRecord</code>records to the 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>Calculates aggregated values (Avg, Sum, Cusum) in a fixed grid over a period.</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>Returns the most recent cumulative aggregate in the selected grid (including <code>last_ts</code>).</td></tr></tbody></table>

***

## Example scripts

### GetHeap

**Description:**\
Retrieves the current value of an attribute or the entire JSON of an asset from the heap.

**Parameters:**

* `gai: str` (required) – GAI of the asset, e.g. `"K86_WP01"`
* `subtype: str` (required) – data subtype, e.g. `"input"`
* `attribute: str` (required) – attribute name, e.g. `"outside temperature"`

**Code example:**

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

**Example output:**

```
23.5
```

***

### SetHeap

**Description:**\
Sends a dictionary of values to the Calculator to process them and store them in the heap.

**Parameters:**

* `gai: str` (required)
* `subtype: str` (required)
* `data: dict` (required) – e.g. `{"outside temperature": 23.5}`
* `source: str` (required) – typically `eliona.MakeSource(id)`

**Code example:**

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

***

### GetAssetIDByGAI

**Description:**\
Returns the numeric asset ID for the specified GAI.

**Parameters:**

* `gai: str` (required)

**Code example:**

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

***

### GetAll

**Description:**\
Retrieves all data points of a specific subtype for a list of assets and returns them as a dictionary (GAI → data).

**Parameters:**

* `ids: list[int|str]` (required) – e.g. `["K86_WP01", 1073]`
* `subtype: str` (required)

**Code example:**

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

***

### SQLQuery

**Description:**\
Executes any SQL query and returns the results as a list of tuples.

**Parameters:**

* `query: str` (required)

**Code example:**

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

**Example output:**

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

***

### MakeSource

**Description:**\
Creates a source string (e.g. `"ssr:123"`) for heap operations based on the function ID.

**Parameters:**

* `id: int` (required)

**Code example:**

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

***

### OpenFile

**Description:**\
Opens a file in the Eliona working directory (analogous to Python’s `open()`).

**Parameters:**

* `name: str` (required) – file name, e.g. `"log.txt"`
* `mode: str` (required) – e.g. `"w"`, `"r"`

**Code example:**

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

***

### AddAssetTag

**Description:**\
Adds a tag to an asset if it has not already been assigned.

**Parameters:**

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

**Code example:**

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

***

### RemoveAssetTag

**Description:**\
Removes a tag from an asset if present.

**Parameters:**

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

**Code example:**

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

***

### GetTrendRecords

**Description:**\
Loads a list of historical measurements (`TrendRecord(ts, value)`) from the specified start time.

**Parameters:**

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

**Code example:**

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

**Description:**\
Writes one or more `TrendRecord`records to the system.

**Parameters:**

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

**Code example:**

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

**Description:**\
Calculates aggregated values (average, sum, cumulative sum) in a fixed grid over a period.

**Parameters:**

* `agg: Aggregate` (required) – e.g. `eliona_types.Aggregate.Avg`
* `asset_id: int` (required)
* `subtype: str` (required)
* `attr: str` (required)
* `raster: str` (required) – ISO 8601 duration, e.g. `"PT1H"` for hourly
* `start: datetime` (required)
* `end: datetime` (optional, default: `now()`)

**Code example:**

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

**Example output structure:**

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

***

### GetLastAggregate

**Description:**\
Returns the most recent cumulative aggregate in the selected grid (including `last_ts`).

**Parameters:**

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

**Code example:**

```python
import eliona_types

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

**Example output structure:**

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

***

### Simple script for manipulating data

This example shows how a script generates a random value and writes it to an asset's heap:

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

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

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

**Description:**

* The script imports the module `random`.
* A dictionary `data` is created that contains a key `power_val` which is assigned a random value between 10 and 100.
* The generated value is written using the method `SetHeap` into the heap of the asset `TestInactIn` .

***

### Retrieve and modify data

In this example, the value of an attribute is retrieved from an asset, modified, and stored in another asset:

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

**Description:**

* The script imports the module `datetime`.
* The current value of the attribute `power_val` is retrieved from the heap of the asset `TestInactIn` .
* This value is tripled and written as `energy_val` to the same asset.

***

### Advanced functions and SQL queries

With the method `SQLQuery` any SQL queries can be executed directly from the script:

```python
def UserFunction(id, eliona):
    result = eliona.SQLQuery("SELECT * FROM public.asset WHERE gai = 'TestInactIn';")
    # Further processing of the result
```

**Description:**

* The SQL query retrieves all information about the asset with the GAI `TestInactIn` .
* The result can then be processed further.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.buildings.ability.abb/collection/english-v14/documentation/engineering/skript-engine/python-skripte-schreiben.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
