---
# System prepended metadata

title: Flexchain Instruction Document - LITE

---

# Flexchain Instruction Document - LITE

## API Links:

##### (POST, GET): 
> FlexibilityOfferFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flexibilityOffers
> FlexibilityRequestFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flexibilityRequests
> Flex_MatchingAlgo_Function: https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_matching_algo_Results



##### (GET) (a specific entry)
> FlexibilityOfferGetFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flexibilityOffers/{UserID}
> FlexibilityRequestGetFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flexibilityRequests/{RequestID}
> Flex_MatchingAlgo_Get_Function: https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_matching_algo_Results/{RequestID}



##### (DELETE: specific entry) [by DSO: ALL USING {RequestID}]
> FlexibilityOfferDelFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flexibilityOffers/{RequestID}
> FlexibilityRequestDelFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flexibilityRequests/{RequestID}
> Flex_MatchingAlgoDelFunction: https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_matching_algo_Results/{RequestID}


##### (Blind MatchingAlgo GET):
> Flex_MatchingAlgo_Blind_Function: https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_matching_algo_Results_blind/{RequestID}


##### Validity Check Function (GET):
> ValidityCheck_Get_Function: https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_validity_check/
> 

#### Timer Trigger Functions

DeleteFlexOfferTimerTrigger: timerTrigger

DeleteFlexRequestTimerTrigger: timerTrigger

DeletematchingAlgoTimerTrigger: timerTrigger

MatchingAlgoPostTimerTrigger: timerTrigger


## Offer, Request, Matching Algo Body Format (JSON):

### Offer Format:

```
"UserId": "user001",
            "FlexOfferList": [
                {
                    "BidPriceCtpEUList": "null",
                    "endFlexShiftTimeSlot": "2021-10-05T21:00:00Z",
                    "RequestId": "Req000001",
                    "startFlexShiftTimeSlot": "2021-10-05T19:00:00Z",
                    "totalFlexOfferedEU": -6,
                    "id": null
                },
                {
                    "BidPriceCtpEUList": "null",
                    "endFlexShiftTimeSlot": "2021-10-05T19:15:00Z",
                    "RequestId": "Req000002",
                    "startFlexShiftTimeSlot": "2021-10-05T19:00:00Z",
                    "totalFlexOfferedEU": 2,
                    "id": null
                },
                {
                    "BidPriceCtpEUList": "8, 10, 12, 13",
                    "endFlexShiftTimeSlot": "2021-10-05T19:15:00Z",
                    "RequestId": "Req000006",
                    "startFlexShiftTimeSlot": "2021-10-05T19:00:00Z",
                    "totalFlexOfferedEU": 4,
                    "id": null
                },
                {
                    "BidPriceCtpEUList": "7",
                    "endFlexShiftTimeSlot": "2021-10-05T19:15:00Z",
                    "RequestId": "Req000007",
                    "startFlexShiftTimeSlot": "2021-10-05T19:00:00Z",
                    "totalFlexOfferedEU": 4,
                    "id": null
                }
            ]
```



### Request Format:

#### (for fixed price):

```
"RequestId": "Req000001",
            "Mode": "fcfs",
            "FullfillmentFactor": 50,
            "MarketType": "fixedPrice",
            "MaxPriceCtpEU": null,
            "PriceOfferCtpEU": "7",
            "ReferencePriceCtpEU": "null",
            "TimeSlot": "2021-10-05T15:15:00Z",
            "TotalFlexRequestedEU": "-11",
            “MatchingAlgoCheck”: false



 "RequestId": "Req000005",
            "Mode": "fcfs",
            "FullfillmentFactor": 0,
            "MarketType": "fixedPrice",
            "MaxPriceCtpEU": null,
            "PriceOfferCtpEU": "null",
            "ReferencePriceCtpEU": "null",
            "TimeSlot": "2021-06-13T22:16:00Z",
            "TotalFlexRequestedEU": "null",
            “MatchingAlgoCheck”: false
```


#### (for auction):

```
"RequestId": "Req000006",
            "Mode": "MiP",
            "FullfillmentFactor": 50,
            "MarketType": "auction",
            "MaxPriceCtpEU": 12,
            "PriceOfferCtpEU": "null",
            "ReferencePriceCtpEU": "10",
            "TimeSlot": "2021-10-05T15:00:00Z",
            "TotalFlexRequestedEU": "7",
            “MatchingAlgoCheck”: false



 "RequestId": "Req000008",
            "Mode": "MiP",
            "FullfillmentFactor": null,
            "MarketType": "auction",
            "MaxPriceCtpEU": null,
            "PriceOfferCtpEU": "null",
            "ReferencePriceCtpEU": "null",
            "TimeSlot": "2021-10-05T15:00:00Z",
            "TotalFlexRequestedEU": "null",
            “MatchingAlgoCheck”: false
```


### Matching Algo Result Format (The format in which matching algo results are stored in the table):

```
"response": [
        {
              "_id": {
                "$oid": "640aea889d4f350d11121249"
              },
              "requestId": "req0001",
              "reachedFullFillmentFactor": true,
              "results": [
                {
                  "userId": "us1",
                  "flexEU": 6
                },
                {
                  "userId": "us2",
                  "flexEU": 4
                },
                {
                  "userId": "us3",
                  "flexEU": 1
                }
              ]
            },
        {
          "_id": {
            "$oid": "640aea889d4f350d1112124c"
          },
          "requestId": "req00011",
          "reachedFullFillmentFactor": false,
          "results": null
        }
    ]

```


## Note:
### In Requests:
**‘market_type’ can be:**  

‘fixed_price’: The grid operator offers a fixed price (“reference_price_ctpEU”: null, “price_offered_ctpEU”: [int]) for flexibility 

‘auction’: A market based auction decides the price (“reference_price_ctpEU”: [int], “price_offered_ctpEU”: null) 

<!-- ‘isBlind’ can be:  

True: The volume requested by the grid operator is not known (“total_flex_requested_EU”: null) 

False: The volume requested by the grid operator is known (“total_flex_requested_EU”: [int])  -->


**‘loc’:** List of HEMS UserIds with suitable location

### In Offers:
In case **‘market_type’: ‘fixed_price’,** the price is already written in the flexibility request. Therefore: 
‘price_bid_ctEU_list’ list:null. 

In case **‘market_type’: ‘auction’,** the EU prices are sent as list 
‘price_bid_ctpEU_list’: […] 

**"start_flex_shift_timeslot ":** start of timeslot to which flex must be shifted, null if "traded_flexibility_EU":0 

**"end_flex_shift_timeslot ":** start of timeslot to which flex must be shifted, null if "traded_flexibility_EU":0 

## Details on the Modes:


#### Note:
For https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_matching_algo_Results

> We do not put any details (Json) as the body for POST request. **The server will take data from FlexibilityRequest and FlexibilityOffer and use the Matching Algorithm.** The result of the matching algorithm is stored in the the flex_matching_algo_Results table in the database.


## Cron Jobs

### DeleteALL Cron Job: 
#### Every 2 weeks.
```
request dropping collection

offers dropping collection

matching algo result dropping collection
```


### MatchingAlgo POST Cron Job:
#### Every 15 min.
```
matching algo result POST method
```

## (Blind MatchingAlgo GET):
To call 
`http://localhost:7071/api/flex_matching_algo_Results_blind/{RequestID}`

As **GET** method.

Body:
> {
> “userId” : “value”,
> “password” : “value”
> }


## Removing Duplicacy in Matching Algo Results
Since the Requests and Offers are only being removed once every 2 weeks, there can be a scenario where `A,B,C` requests and `W,X,Y,Z` offers give `P,Q,R` matching algorithm results at time `T`. Since the inputs are not removed, at time `T + 15min` another `P,Q,R` results will be created, thus making redundency.

To eliminate this, we have included a check called `MatchingAlgoCheck`. It is there for each request and it is set to false initially.

When matching algorithm is called, the `MatchingAlgoCheck` for all the used requests are set to true. And during matching algorithm calculation we are using an if statement that allows only requests with `MatchingAlgoCheck=false` to be included in the calculation.


## Blind Matching Algo
It is required when a user tries to check if their offer was accepted for a particular request (and if accepted, then how much) without gaining knowledge of the accepted offers from other users.

User has to use the endpoint with requestid:

https://flexchain-functionapp-testenv.azurewebsites.net/api/flex_matching_algo_Results_blind/{RequestID}

The body format for the GET request is:

{
```
"UserId": "us1",
"Password": "abc"
```
}

The response format is:

In case user offer was accepted:

```
{
    "status": 200,
    "errors": [],
    "warnings": [],
    "information": [],
    "response": {
        "us1": 6,
        "Total": 11
    }
}
```

In case user offer was not accepted:

```
{
    "status": 403,
    "errors": [
        {
            "message": "Offer Not Accepted",
            "type": "ForbiddenError",
            "data": null
        }
    ],
    "warnings": [],
    "information": [],
    "response": null
}
```

## Hash Format
```
RequestID + 

BidPriceCtpEUList + 

TotalFlexOfferedEU + 

StartFlexShiftTimeslot + 

EndFlexShiftTimeslot
```

So hash value: 
`SHA3(RequestID + BidPriceCtpEUList + TotalFlexOfferedEU + StartFlexShiftTimeslot + EndFlexShiftTimeslot)`


#### Merkle Tree
![](https://i.imgur.com/pkGha1O.png)


## TODO:


## Flowchart

![](https://i.imgur.com/eQMlt6Q.png)

# Hager MQTT API

### Abbreviations
EU = Energy Unit
Ctp = Cent per unit

## Get Flexibility Requests (Hager -> AWSI )

Topic: flexibility-request
```
{
    "userId": "user0001"
}
```


## Send Flexibility Response (AWSI -> Hager )
Topic: flexibility-response

```
{
    "requests": [
        {
            "id": "req001",
            "timeSlot": "2021-10-05T15:15:00Z",
            "totalFlexRequestedEU": -11,
            "marketType": "fixedPrice",
            "priceOfferCtpEUs": 7,
            "maxPriceCtpEU": null,
        },
        {
            "id": "req003",
            "timeSlot": "2021-10-05T15:45:00Z",
            "totalFlexRequestedEU": -8,
            "marketType": "fixedPrice",
            "priceOfferCtpEUs": 6,
            "maxPriceCtpEU": null,
        },
        {
            "id": "req007",
            "timeSlot": "2021-10-05T17:15:00Z",
            "totalFlexRequestedEU": 9,
            "marketType": "auction",
            "priceOfferCtpEUs": null,
            "maxPriceCtpEU": 14,
        }
    ]
}
```

## Send Flexibility Offer (Hager -> AWSI)
Topic: flexibility-offer

```
{
    "offer": {
        "userId": "user0001",
        "offers": [
            {
                "requestId": "req001",
                "endFlexShiftTimeSlot": "2021-10-05T21:00:00Z",
                "startFlexShiftTimeSlot": "2021-10-05T19:00:00Z",
                "totalFlexOfferedEU": -6,
                "bidPriceCtpEUList": []
            }
        ]
    },
    "hash": "<hash>"
}

```

## Send Matching Algo result (AWSI -> Hager)
Topic: flexibility-result
```
{
    "results": [
        {
            "requestId": "req001",
            "flexEU": -3,
            "matchingResult":  0,
        },
        {
            "requestId": "req003",
            "flexEU": -5
            "matchingResult":  0,
        },
        {
            "requestId": "req007",
            "flexEU": 0
            "matchingResult":  1,
        }
    ]
}
```
MatchingResult: 
 0 = offer has won & fullfillmentFactor was reached
 1 = offer was considered but did not win & fullfillmentFactor was reached
 2 = offer was considered, fullfillmentFactor was not reached
 3 = offer was not considered because the offer was invalid (wrong hash)

**Flexibility must only be provided if MatchingResult = 0**

## Send Flexibility Verification (Hager -> AWSI)
Topic: flexibility-verification
```
{
    "requestId": "req007",
    "userId": "user0001",
    "totalFlexDeliveredEU": 9
}
```