This endpoint retrieves generation data of multiple inverters.
此端点用于提交分组设备的多个逆变器的发电数据。
Table of Contents
Table of Contents | ||
---|---|---|
|
Changelogs
Version | Date | Changes by | Description of change |
V1.0 | Mar 29, 2024 | Que Nguyen |
|
V1.0.1 | April 5, 2024 | Que Nguyen |
|
V1.0.2 | April 8, 2024 | Que Nguyen |
|
V1.0.3 | April 10, 2024 | Que Nguyen |
|
V1.0.4 | May 13, 2024 | Que Nguyen |
|
V1.0.5 |
| Que Nguyen |
|
V1.0.6 |
| Que Nguyen |
|
Release status
Environment | Status | Released Date | Version | ||||||
DEV |
|
| V1.0.6 | ||||||
UAT |
|
| V1.0.6 | ||||||
PROD |
|
| V1.0.5 |
Device Inverters Resource
Devices (required) - array[object] - Array of Inverter Daily Data Resource This refers to data generation for daily data of multiple devices Maximum generation of all devices received per request payload: 3000 records 这是指多个设备日常数据的数据生成。 一次性最大接受提交的电量记录数为3000,即一次性最多发送3000天的数据。 |
Code Block | ||
---|---|---|
| ||
{ "Devices": [ { "RemoteInvId": "STR10000000338444", "Data": [ { "Timestamp": "2023-05-01", "PeriodProductionInKWh": "0.123", "AccumulatedEnergyInKWh": "5.123" }, { "Timestamp": "2023-05-02", "PeriodProductionInKWh": "0.234", "AccumulatedEnergyInKWh": "5.357" } ] } ] } |
Inverter Daily Data Resource
RemoteInvId (required) text This refers to a unique identifier assigned to an inverter. ex: STR1000000033862740 这指的是分配给逆变器的唯一标识符 例如:STR1000000033862740 |
Data (required) array[object] - Array of Daily Data Resource This refers to data generation at a particular frequency type Maximum generation data received per request payload: 3000 records 这指的是在特定频率类型下的数据生成。 一次性最大接受提交的电量记录数为3000,即一次性最多发送3000天的数据。 |
Code Block | ||
---|---|---|
| ||
{ "Data": [ { "Timestamp": "2023-05-01", "PeriodProductionInKWh": "0.123", "AccumulatedEnergyInKWh": "5.123" }, { "Timestamp": "2023-05-02", "PeriodProductionInKWh": "0.234", "AccumulatedEnergyInKWh": "5.357" }, { "Timestamp": "2023-05-03", "PeriodProductionInKWh": "0.456", "AccumulatedEnergyInKWh": "5.813" } ], "RemoteInvId": "STR10000000338444" } |
Daily Data Resource
Timestamp (required) text The time to capture data in the format 'YYYY-MM-DD' ex: 2023-04-05 捕获数据的时间,格式为 'YYYY-MM-DD' 例如:2023-04-05 |
PeriodProductionInKWh (required) number Energy generation ex: 0.123 日发电量 例如:0.123 |
AccumulatedEnergyInKWh (required) number Accumulated Energy generation 累计发电量 ex: 100.123 |
Code Block | ||
---|---|---|
| ||
{ "Timestamp": "2023-05-01", "PeriodProductionInKWh": "0.123", "AccumulatedEnergyInKWh": "5.123" } |
API Definition
Status | ||||
---|---|---|---|---|
|
/public/v2/generation-datas/batches
Request
Headers
Content-Type |
|
Authorization |
|
Payload
Devices (required) - array[object] - Array of Inverter Daily Data Resource This refers to data generation for daily data of multiple devices Maximum generation of all devices received per request payload: 3000 records 这是指多个设备日常数据的数据生成。 一次性最大接受提交的电量记录数为3000,即一次性最多发送3000天的数据。 |
Devices[n].RemoteInvId (required) text This refers to a unique identifier assigned to an inverter. ex: STR1000000033862740 这指的是分配给逆变器的唯一标识符 例如:STR1000000033862740 |
Devices[n].Data[m].Timestamp (required) text The time to capture data in the format 'YYYY-MM-DD' ex: 2023-04-05 捕获数据的时间,格式为 'YYYY-MM-DD' 例如:2023-04-05 |
Devices[n].Data[m].PeriodProductionInKWh (required) number Energy generation ex: 0.123 日发电量 例如:0.123 |
Devices[n].Data[m].AccumulatedEnergyInKWh (required) number Accumulated Energy generation 累计发电量 ex: 100.123 |
Code Block |
---|
curl --location 'https://uat-api.redex.eco/public/v2/generation-datas/batches' \ --header 'Authorization: Bearer {{access_token}}' \ --header 'Content-Type: application/json' \ --data '{ "Devices": [ { "RemoteInvId": "TLGMIV500002000338634980432-INV20EN", "Data": [ { "Timestamp": "2022-05-13", "PeriodProductionInKWh": 3157.288, "AccumulatedEnergyInKWh": 3361.328 } ] }, { "RemoteInvId": "TLGMIV500002000338634980432-INV30EN", "Data": [ { "Timestamp": "2022-05-13", "PeriodProductionInKWh": 3157.288, "AccumulatedEnergyInKWh": 3361.328 } ] } ] }' |
Response
Headers
Content-Type |
|
Response Body
Response Body |
---|
Data.ProcessId uuid Process unique identifier |
Errors list of error objects Please see "Getting Started - #Error Object" for more details 请查看Getting Started - #Error Object以获得更多信息。 |
Meta null object Return null object |
StatusCode integer Http Status codes standard. Example http状态码,如200,201,404 |
Message text Response message: Success or error message. 返回成功或错误的信息。 |
Info |
---|
201 Success |
Code Block | ||
---|---|---|
| ||
{ "StatusCode": 201, "Errors": null, "Meta": null, "Data": { "ProcessId": 2024 }, "Message": "Send Power Data successfully" } |
Warning |
---|
400 Bad Request |
Code Block | ||
---|---|---|
| ||
{ "Data": null "StatusCode": 400, "Errors": [], "Meta": null, "Message": "Bad Request" } |
Warning |
---|
422 Unprocessable Entity |
Code Block | ||
---|---|---|
| ||
{ "Data": null, "StatusCode": 422, "Errors": [], "Meta": null, "Message": "Unprocessable Entity" } |
Warning |
---|
401 Unauthorized |
Code Block | ||
---|---|---|
| ||
{ "Data": null, "StatusCode": 401, "Errors": [], "Meta": null, "Message": "Unauthorized" } |
Warning |
---|
403 Forbidden |
Code Block | ||
---|---|---|
| ||
{ "Data": null, "StatusCode": 403, "Errors": [], "Meta": null, "Message": "Forbidden" } |
Rate limit
Rate Limit Algorithm: Fixed Window
In fixed window rate limiting, a fixed time window (e.g., one minute, one hour) is used to track the number of requests or actions allowed within that window. Requests exceeding the limit are either rejected or throttled until the window resets.
Rate Limiting Overview
Our API employs rate limiting to ensure fair usage and protect the performance and availability of the service. Combination of Global Policy and Operation Policy
Global Policy
Rate Limit: 3000 requests per 5 minute(s)
Renewal Period: 300 second(s)
Key: IP Address
Increment Condition: Any Request
Operation Policy
Rate Limit: 5 requests per 5 second(s)
Renewal Period: 5 second(s)
Key:
accound-id
business account Id.Increment Condition: Any Request
Rate Limit Details
Rate Limit by Key:
Key: This ensures that rate limits are applied uniquely for each business account id.
Request Limit: Each key is allowed to make up to 5 requests per 5 seconds.
Reset Interval: The limit resets every 5 seconds.
Response Headers:
Retry-After: Sent when the rate limit is exceeded, indicating how long to wait before making another request.
Exceeding the Rate Limit
When the rate limit is exceeded, the API will return a 429 Too Many Requests
status code. The response will include a Retry-After
header specifying the number of seconds to wait before making a new request.
Example Response When Rate Limit is Exceeded
Code Block | ||
---|---|---|
| ||
HTTP/1.1 429 Too Many Requests Retry-After: 60 Content-Type: application/json { "Data": null, "Errors": null, "StatusCode": 429, "Message": "Rate limit exceeded", "Meta": null } |
Demo(for reference only)
Code Block | ||
---|---|---|
| ||
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Demo;
public class Program
{
private static readonly HttpClient client = new HttpClient();
private static readonly SemaphoreSlim semaphore = new SemaphoreSlim(5); // Control concurrency
private const int DataBatchSize = 3000; // Number of data items per batch
private const int MaxRequestsPer5Seconds = 5; // Maximum requests per 5 seconds
private static readonly TimeSpan RequestInterval = TimeSpan.FromSeconds(5); // Request interval
private static string AccessToken = "YOUR_ACCESS_TOKEN_HERE"; // Replace with your actual AccessToken
private const string ApiEndpoint = "YOUR_API_ENDPOINT_HERE"; // API endpoint URL
public static async Task Main(string[] args)
{
// Sample data using the PowerGenerationData class
var dataList = new List<PowerGenerationData>
{
new PowerGenerationData
{
RemoteInvId = "MY78222522114",
Timestamp = "2023-07-01",
PeriodProductionInKWh = "0.123",
AccumulatedEnergyInKWh = "5.123"
},
new PowerGenerationData
{
RemoteInvId = "MY78222522115",
Timestamp = "2023-07-02",
PeriodProductionInKWh = "0.234",
AccumulatedEnergyInKWh = "5.357"
}
// Continue adding data items
};
await ProcessAndSendDataInBatchesAsync(dataList);
}
private static async Task ProcessAndSendDataInBatchesAsync(List<PowerGenerationData> dataList)
{
// Calculate total number of data batches
int totalDataBatches = (int)Math.Ceiling(dataList.Count / (double)DataBatchSize);
// Process data in batches
for (int batchIndex = 0; batchIndex < totalDataBatches; batchIndex++)
{
var batchData = dataList.Skip(batchIndex * DataBatchSize).Take(DataBatchSize).ToList();
// Group data by RemoteInvId and map to DataItem
var groupedDevices = batchData
.GroupBy(item => item.RemoteInvId)
.Select(g => new Device
{
RemoteInvId = g.Key,
Data = g.Select(d => new DataItem
{
Timestamp = d.Timestamp,
PeriodProductionInKWh = d.PeriodProductionInKWh,
AccumulatedEnergyInKWh = d.AccumulatedEnergyInKWh
}).ToList()
})
.ToList();
// Create request body
var requestBody = new RequestBody { Devices = groupedDevices };
var json = JsonConvert.SerializeObject(requestBody);
// Control request rate
await semaphore.WaitAsync();
try
{
// Send request
await PostDataAsync(json);
// Wait to limit request frequency
if ((batchIndex + 1) % MaxRequestsPer5Seconds == 0)
{
await Task.Delay(RequestInterval);
}
}
catch(Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
semaphore.Release();
}
}
}
private static async Task PostDataAsync(string jsonData)
{
var requestMessage = new HttpRequestMessage(HttpMethod.Post, ApiEndpoint)
{
Content = new StringContent(jsonData, Encoding.UTF8, "application/json")
};
// Add Authorization header
requestMessage.Headers.Authorization = new AuthenticationHeaderValue("Bearer", AccessToken);
var response = await client.SendAsync(requestMessage);
if (response.IsSuccessStatusCode)
{
Console.WriteLine("Data sent successfully.");
}
else
{
var responseContent = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Failed to send data: {responseContent}");
}
}
}
public class RequestBody
{
[JsonProperty("Devices")]
public List<Device> Devices { get; set; }
}
public class Device
{
[JsonProperty("RemoteInvId")]
public string RemoteInvId { get; set; }
[JsonProperty("Data")]
public List<DataItem> Data { get; set; }
}
public class DataItem
{
[JsonProperty("Timestamp")]
public string Timestamp { get; set; }
[JsonProperty("PeriodProductionInKWh")]
public string PeriodProductionInKWh { get; set; }
[JsonProperty("AccumulatedEnergyInKWh")]
public string AccumulatedEnergyInKWh { get; set; }
}
public class PowerGenerationData
{
[JsonProperty("RemoteInvId")]
public string RemoteInvId { get; set; }
[JsonProperty("Timestamp")]
public string Timestamp { get; set; }
[JsonProperty("PeriodProductionInKWh")]
public string PeriodProductionInKWh { get; set; }
[JsonProperty("AccumulatedEnergyInKWh")]
public string AccumulatedEnergyInKWh { get; set; }
} |