# Aggregators Calculation

Aggregators are parameters that describe the machine and are written in all tables because they are particularly useful for filtering and aggregating data.

## /apis/aggregators/\<assetId>

## GET Method

<details>

<summary>Request</summary>

```
HTTP
GET https://{BASE_URL}/apis/aggregators/<assetId>
```

where:&#x20;

* `assetId` : ID of the machine to consider.

#### Query

```
JSON
{
    "subAssetId": "subAssetId"
}
```

where:&#x20;

* `subAssetId` : ID of the sub-machine to consider. This field can be omitted if the asset being considered is not a multi-machine system.

</details>

By invoking this endpoint with the HTTP GET method, you can retrieve all the aggregators available for the specified machine.

An example of the response is shown below. As you can see, each key in the response indicates an available aggregator, while the associated value contains useful information such as the human-readable meaning of the aggregator and its unique ID.

<details>

<summary>Response</summary>

```json
JSON
{
    "aggr0": {
        "id": "aggr0",
        "meaning": "Product ID"
    },
    "aggr1": {
        "id": "aggr1",
        "meaning": "Operator ID"
    },
    "aggr2": {
        "id": "aggr2",
        "meaning": "Format"
    }
}
```

</details>

## Example

<details>

<summary>Request</summary>

```
HTTP
GET https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

</details>

In this example, the goal is to obtain the list of all aggregators for the machine "40-line," but only valid for the sub-machine "M1."

An example of the response is shown in the figure.

<details>

<summary>Response</summary>

```json
JSON
{
    "aggr0": {
        "id": "aggr0",
        "meaning": "Product ID"
    },
    "aggr1": {
        "id": "aggr1",
        "meaning": "Operator ID"
    },
    "aggr2": {
        "id": "aggr2",
        "meaning": "Format"
    }
}
```

</details>

### Code

{% tabs %}
{% tab title="Python" %}

```python
import requests
import json

# Example data for the header
headers = {
    'App-Name': 'matdev-be',
    'Authorization': 'Bearer ey....xy1w'
}

# URL of the third-party API
myDomain = 'matdev.40mat.com'
myAssetId = '40-line'
endpoint = f'/apis/aggregators/{myAssetId}'
url = f'https://{myDomain}{endpoint}'


# Make the POST request
response = requests.get(url, headers=headers, )

# Check the response status and return the data
if response.status_code == 200:
    print('Success:')
    print(json.dumps(response.json(), indent=4))
else:
    print('Request failed:')
    print(f'Status code: {response.status_code}')
    print(response.text)
```

{% endtab %}
{% endtabs %}

### OpenAPI

{% openapi src="<https://content.gitbook.com/content/L65nhvmBlLI1fH4sd9ut/blobs/KAvOsMKNpCkRaukQxFnU/OpenAPI_simpliefiedAPIs.yml>" path="/apis/aggregators/{assetId}" method="get" %}
[OpenAPI\_simpliefiedAPIs.yml](https://content.gitbook.com/content/L65nhvmBlLI1fH4sd9ut/blobs/KAvOsMKNpCkRaukQxFnU/OpenAPI_simpliefiedAPIs.yml)
{% endopenapi %}

## POST Method

This endpoint allows you to retrieve the values recorded in the table for the requested aggregator. The functionality of this endpoint is very similar to the one that allows you to retrieve KPI values (`/apis/kpis/<assetId>`).

<details>

<summary>Request</summary>

```
HTTP
POST https://{BASE_URL}/apis/aggregators/<assetId>
```

where:&#x20;

* `assetId` : ID of the machine to consider.&#x20;

#### Query

```
JSON
{
    "subAssetId": "subAssetId"
}
```

where:&#x20;

* `subAssetId` : ID of the sub-machine to consider. This field can be omitted if the asset being considered is not a multi-machine system.

#### Body

<pre><code>JSON
{
    "aggregatorName": "aggr0",
    "resampleBy": "1d",
<strong>    "from": "2024-05-10T22:00:00.000Z",
</strong>    "to": "2024-05-13T21:59:59.999Z",
    "limit":1,
    "filterBy": {"aggr1": "Mario"},
    "groupBy": "aggr1",
    "getPossibleValues": true,
    "calendar": 0
}
</code></pre>

The parameters that can be passed in the body are as follows:

* `aggregatorName`: this parameter contains the identifier of the aggregator you want to download. The list of available aggregators can be retrieved by invoking the [`/apis/aggregators/<assetId>` endpoint with the GET method](#get-method). Note that this field can be a list of strings, where each string represents an aggregator to be requested;
* `from`: the starting point from which you want to begin calculating the data, expressed in UTC in the format "YYYY-MM-DDThh:mm .sssZ" (ISO 8601 Standard);
* `to`: the endpoint of the interval for which you want to calculate the data, expressed in UTC in the format "YYYY-MM-DDThh:mm .sssZ" (ISO 8601 Standard). If this field is omitted or set to null, it will automatically be set to the current time of the request;
* `limit`: this numeric field allows you to specify a maximum number of rows of data to return. If you imagine the data as being written in tables, a "limit" operation allows you to take the last {n} rows of the table. Specifically, "limit" refers to the most recent rows written in the table. If the "resampleBy" field is present, "limit" will be ignored and will have no effect. Additionally, this field can be used in various ways:
  * "limit" without "from" and "to": the last {n} rows written in the table, or more generally, the last {n} data points available, will be retrieved;
  * "limit" with "from" and without "to": the behavior in this case is the same as the previous one. The last {n} data points available will be returned;
  * "limit" with "from" and without "to": in this case, the last {n} rows of data will be returned, taking the "to" field as the endpoint of the interval. The data will be the last ones written before the time specified in the "to" field;
  * "limit" with "to" and without "from": this option is not allowed and will result in an error.
* `resampleBy`: this parameter allows you to define the frequency with which to calculate the specified KPI. Since data in the MAT ecosystem is recorded over time, it can be returned with reference to a time period or as a time series. Note that, because aggregators are often expressed as strings, if multiple values are recorded within the same resample unit, they will be presented concatenated with the "$$" character. This field allows you to specify how the data should be returned. The allowed values are:
  * unique: this parameter indicates that you want to obtain a single numerical value calculated over the entire interval;
  * {n}m: allows the KPI to be calculated with a frequency of {n} minutes over the selected interval;
  * {n}h: allows the KPI to be calculated with a frequency of {n} hours over the selected interval;
  * {n}d: allows the KPI to be calculated with a frequency of {n} days over the selected interval;
  * {n}w: allows the KPI to be calculated with a frequency of {n} weeks over the selected interval;
* `groupBy`: this field allows you to group the data according to one of the specified values. The value should be a string indicating the field on which you want to aggregate. For more advanced use, you can specify a list of strings;
* `filterBy`: this field allows you to specify a filter to apply to the data. The value must be a dictionary where the keys represent the fields to filter on, and the value represents what you want to include for that field;
* `getPossibleValues`: a boolean that allows you to indicate whether you want to download only the values that the aggregator has assumed over time (True) or if you are interested in their trend (False);
* `calendar` : boolean value indicating whether the calendar should be considered in data analysis. By default, this value is set to false.

</details>

## Esempio - resampleBy

<details>

<summary>Request</summary>

```
HTTP
POST https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

#### Body

```
JSON
{
    "aggregatorName": "aggr1",
    "resampleBy": "1d",
    "from": "2024-05-10T22:00:00.000Z",
    "to": "2024-05-13T21:59:59.999Z"
}
```

</details>

Questo esempio ritorna i valori assunti dall'aggregatore "aggr1" nel tempo resamplati per ora. Nella risposta sarà presente il separatore "$$" poiché tale aggregatore, nel nostro esempio, è di tipo stringa.

La risposta è la seguente:

<details>

<summary>Response</summary>

```json
JSON
[
    {
        "_time": "2024-05-11T00:00:00.000",
        "aggr1": "Waluigi$$Wario$$Luigi$$Peach$$Mario$$Yoshi"
    },
    {
        "_time": "2024-05-12T00:00:00.000",
        "aggr1": "Waluigi$$Wario$$Luigi$$Peach$$Mario$$Yoshi"
    },
    {
        "_time": "2024-05-13T00:00:00.000",
        "aggr1": "Waluigi$$Wario$$Luigi$$Peach$$Mario$$Yoshi"
    }
]
```

</details>

## Example - limit

<details>

<summary>Request</summary>

```
HTTP
POST https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

#### Body

```
JSON
{
    "aggregatorName": "aggr1",
    "from": "2024-05-12T22:00:00.000Z",
    "to": "2024-05-13T21:59:59.999Z",
    "limit":1
}
```

</details>

The objective of this example is to determine who the last active operator on the machine was on May 13th. To achieve this, in addition to specifying the correct time interval, the "limit" parameter is set to 1. This way, the last recorded operator within the final timestamp indicated in the "to" field will be returned.

The response is as follows:

<details>

<summary>Response</summary>

```json
JSON
[
    {
        "_time": "2024-05-13T23:59:59.999",
        "aggr1": "Mario"
    }
]
```

</details>

## Example - filterBy

<details>

<summary>Request</summary>

```
HTTP
POST https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

#### Body

```
JSON
{
            "from": "2024-05-20T12:00:00.000Z",
            "to": "2024-05-20T12:59:59.999Z",
            "aggregatorName": "aggr2",
            "filterBy": {"aggr1": "Mario"}
 }
```

</details>

In this example, I want to obtain all the formats used by the operator "Mario" in the last hour. To get this information, I filtered the data so that only the records where the operator "Mario" is active are returned.

The response is as follows:

<details>

<summary>Response</summary>

```json
JSON
[
    {
        "_time": "2024-05-20T14:12:45.661",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:17:45.838",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:22:46.006",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:27:46.185",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:32:46.358",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:34:06.054",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:39:06.228",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:44:06.405",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:49:06.576",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:54:06.746",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:57:46.829",
        "aggr2": "format-E"
    },
    {
        "_time": "2024-05-20T14:59:59.999",
        "aggr2": "format-D"
    }
]
```

</details>

## Example - groupBy

Below is an example of a grouping operation on the "aggr1" field. The objective is to find out which formats have been used over time by the various operators.

<details>

<summary>Request</summary>

```
HTTP
POST https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

#### Body

```
JSON
{
            "from": "2024-05-20T12:00:00.000Z",
            "to": "2024-05-20T12:59:59.999Z",
            "aggregatorName": "aggr2",
            "groupBy": "aggr1"
}
```

</details>

The response is as follows:&#x20;

<details>

<summary>Response</summary>

```json
JSON
{
    "Mario": [
        {
            "_time": "2024-05-20T14:12:45.661",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:17:45.838",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:22:46.006",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:27:46.185",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:32:46.358",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:34:06.054",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:39:06.228",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:44:06.405",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:49:06.576",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:54:06.746",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:57:46.829",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:59:59.999",
            "aggr2": "format-D"
        }
    ],
    "Yoshi": [
        {
            "_time": "2024-05-20T14:05:00.083",
            "aggr2": "format-E"
        },
        {
            "_time": "2024-05-20T14:07:45.487",
            "aggr2": "format-E"
        }
    ]
}
```

</details>

## Example - getPossibleValues

In this example, the goal is to obtain all the operators who worked on the machine during the specified week. Specifically, by using the "getPossibleValues" parameter, you can identify all the different values that the specified aggregator has assumed within the given time interval.

<details>

<summary>Request</summary>

```
HTTP
POST https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

#### Body

```
JSON
{
            "from": "2024-05-12T22:00:00.000Z",
            "to": "2024-05-19T21:59:59.999Z",
            "aggregatorName": "aggr1",
            "getPossibleValues": true
}
```

</details>

The response will be formatted as follows:

<details>

<summary>Response</summary>

```json
JSON
[
    "Yoshi",
    "Peach",
    "Luigi",
    "Mario",
    "Waluigi",
    "Wario"
]
```

</details>

## Example- aggregatorName as List

<details>

<summary>Request</summary>

```
HTTP
POST https://matdev.40mat.com/apis/aggregators/40-line?subAssetId=M1
```

#### Query

```
JSON
{
    "subAssetId": "M1"
}
```

#### Body

```
JSON
{
            "from": "2024-05-12T22:00:00.000Z",
            "to": "2024-05-19T21:59:59.999Z",
            "aggregatorName": ["aggr1", "aggr2"],
            "resampleBy": "1d"
}
```

</details>

The response will be formatted as follows:

<details>

<summary>Response</summary>

```json
[
    {
        "_time": "2024-05-13T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-B$$format-D$$format-A$$format-C$$format-E"
    },
    {
        "_time": "2024-05-14T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-B$$format-A$$format-D$$format-C"
    },
    {
        "_time": "2024-05-15T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-B$$format-D$$format-A$$format-C$$format-E"
    },
    {
        "_time": "2024-05-16T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-E$$format-D$$format-C"
    },
    {
        "_time": "2024-05-17T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-E$$format-B$$format-C"
    },
    {
        "_time": "2024-05-18T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-B$$format-A$$format-D$$format-C$$format-E"
    },
    {
        "_time": "2024-05-19T00:00:00.000",
        "aggr1": "Mario$$Luigi$$Yoshi$$Wario$$Waluigi$$Peach",
        "aggr2": "format-B$$format-A$$format-D$$format-C$$format-E"
    }
]
```

</details>

### Codic

### Code

{% tabs %}
{% tab title="Python" %}
The following script can be used to make a POST request to the `/apis/aggregators` endpoint. Be sure to configure the parameters correctly in the body of the request.

```python
import requests
import json

# Example data for the header
headers = {
    'App-Name': 'matdev-be',
    'Authorization': 'Bearer ey....xy1w'
}

# Example data for the body
body = {
    "aggregatorName": "aggr0",
    "resampleBy": "1d",
    "from": "2024-05-10T22:00:00.000Z",
    "to": "2024-05-13T21:59:59.999Z",
    "limit":1,
    "filterBy": {"aggr1": "Mario"},
    "groupBy": "aggr1",
    "getPossibleValues": true
}

# Example data for the query string
query_params = {
    "subAssetId": "M1"
}

# URL of the third-party API
myDomain = 'matdev.40mat.com'
myAssetId = '40-line'
endpoint = f'/apis/aggregators/{myAssetId}'
url = f'https://{myDomain}{endpoint}'

# Make the POST request
response = requests.post(url, headers=headers, json=body, params=query_params )

# Check the response status and return the data
if response.status_code == 200:
    print('Success:')
    print(json.dumps(response.json(), indent=4))
else:
    print('Request failed:')
    print(f'Status code: {response.status_code}')
    print(response.text)
```

{% endtab %}
{% endtabs %}

### OpenAPI

{% openapi src="<https://content.gitbook.com/content/L65nhvmBlLI1fH4sd9ut/blobs/KAvOsMKNpCkRaukQxFnU/OpenAPI_simpliefiedAPIs.yml>" path="/apis/aggregators/{assetId}" method="post" %}
[OpenAPI\_simpliefiedAPIs.yml](https://content.gitbook.com/content/L65nhvmBlLI1fH4sd9ut/blobs/KAvOsMKNpCkRaukQxFnU/OpenAPI_simpliefiedAPIs.yml)
{% endopenapi %}
