Skip to main content

Predictions, ROI, Weather & Settings

ML prediction management, ROI calculations, weather data, and user preference endpoints.


Predictions

Base Route: /api/predictions
Authorization: Required

Train Model

Initiates ML model training for a Sun Source. This is an asynchronous operation — poll the status endpoint to track progress.

POST /api/predictions/train

Request Body

{
"sunSourceId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}

Response 200 OK

{
"jobId": "train_7c9e6679_1718900520",
"status": "pending",
"predictions": null,
"metrics": null,
"error": null
}

Run Prediction

Generates energy predictions for the next 8 days using the trained model.

POST /api/predictions/predict

Request Body

{
"sunSourceId": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}

Response 200 OK

{
"jobId": "predict_7c9e6679_1718900520",
"status": "pending",
"predictions": null,
"metrics": null,
"error": null
}

Get Job Status

Polls the status of a training or prediction job.

GET /api/predictions/status/{jobId}

Response 200 OK

{
"jobId": "train_7c9e6679_1718900520",
"status": "completed",
"progress": 100,
"message": "Training completed successfully.",
"error": null,
"type": "train",
"sunSourceId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"updatedAt": "2025-06-20T14:30:00Z",
"metrics": {
"mae": 1.23,
"rmse": 2.45,
"r2": 0.92
},
"predictions": null,
"dataPointsUsed": 4320,
"modelMetrics": { ... }
}

Job Status Values

StatusDescription
pendingJob queued, not yet started
runningJob actively processing
completedJob finished successfully
failedJob failed (see error field)

Get Latest Prediction

Returns the most recent prediction result for a Sun Source.

GET /api/predictions/latest/{sunSourceId}

Response 200 OK

{
"exists": true,
"data": {
"predictions": [
{
"date": "2025-06-21",
"solarProductionKwh": 22.5,
"loadConsumptionKwh": 14.2,
"batteryChargeKwh": 8.3
}
]
}
}

Get Model Info

Returns metadata about the trained model for a Sun Source.

GET /api/predictions/model-info/{sunSourceId}

Response 200 OK

{
"exists": true,
"data": {
"trainedAt": "2025-06-20T14:30:00Z",
"dataPointsUsed": 4320,
"metrics": {
"mae": 1.23,
"rmse": 2.45,
"r2": 0.92
}
}
}

ROI & Pricing

Base Route: /api/roi
Authorization: Required

List Price History

Returns all KWh price entries for a Sun Source, ordered by effective date.

GET /api/roi/{sunSourceId}/prices

Response 200 OK

[
{
"id": "a1b2c3d4-e5f6-...",
"sunSourceId": "7c9e6679-...",
"pricePerKwh": 0.25,
"effectiveFrom": "2024-01-01T00:00:00Z",
"createdAt": "2024-01-01T10:00:00Z"
},
{
"id": "b2c3d4e5-f6a7-...",
"sunSourceId": "7c9e6679-...",
"pricePerKwh": 0.28,
"effectiveFrom": "2025-01-01T00:00:00Z",
"createdAt": "2025-01-01T10:00:00Z"
}
]

Add Price Entry

POST /api/roi/{sunSourceId}/prices

Request Body

{
"pricePerKwh": 0.28,
"effectiveFrom": "2025-01-01T00:00:00Z"
}

Response 200 OK

Returns the created KwhPriceHistoryDto.

Update Price Entry

PUT /api/roi/prices/{priceId}

Request Body

{
"pricePerKwh": 0.30,
"effectiveFrom": "2025-01-01T00:00:00Z"
}

Delete Price Entry

DELETE /api/roi/prices/{priceId}

Returns 204 No Content.

Calculate ROI

Computes the full return-on-investment summary including daily breakdown, payback period, and monthly averages.

GET /api/roi/{sunSourceId}/calculate

Response 200 OK

{
"totalEnergyProducedKwh": 4250.00,
"totalSavings": 1062.50,
"currency": "EUR",
"firstDataDate": "2024-06-01T00:00:00Z",
"lastDataDate": "2025-06-20T00:00:00Z",
"dailyBreakdown": [
{
"date": "2025-06-20T00:00:00Z",
"energyProducedKwh": 21.50,
"pricePerKwh": 0.28,
"savings": 6.02,
"cumulativeSavings": 1062.50,
"isPrediction": false
}
],
"systemCost": 12500.00,
"roiPercentage": 8.50,
"paybackPeriodYears": 11.76,
"monthlyAvgSavings": 88.54,
"hasInvestmentData": true
}

Weather

Base Route: /api/weather
Authorization: Required

Get Weather Data

Returns weather forecast data for the next 8 days.

GET /api/weather/{sunSourceId}

Response 200 OK

[
{
"id": "...",
"sunSourceId": "7c9e6679-...",
"date": "2025-06-20T00:00:00Z",
"temperatureMax": 32.5,
"temperatureMin": 18.0,
"shortwaveRadiationSum": 25.8,
"weatherCode": 1,
"uvIndexMax": 9.2,
"precipitationSum": 0.0,
"sunrise": "2025-06-20T05:30:00",
"sunset": "2025-06-20T21:15:00"
}
]

Refresh Weather Data

Manually triggers a weather data refresh from Open-Meteo.

POST /api/weather/{sunSourceId}/refresh

Returns 200 OK on success, 503 Service Unavailable if Open-Meteo is unreachable.


Settings

Base Route: /api/settings
Authorization: Required

Setting Types

Type IDNameValuesDescription
0DarkMode"0" / "1"UI dark mode preference
1AutoRunPredictions"0" / "1"Enable auto-predictions (DailyPredictionJob)
2AutoUpdateWeatherData"0" / "1"Enable auto weather refresh (UpdateWeatherDataJob)

Get Setting

GET /api/settings/{settingType}

Response 200 OK

{
"value": "1"
}

Set Setting

POST /api/settings/{settingType}

Request Body

{
"value": "1"
}

Response 200 OK

{
"value": "1"
}

Sharing

Base Route: /api/sharing

Get Sharing Configuration

Authorization: Required

GET /api/sharing/{sunSourceId}

Response 200 OK

{
"sunSourceId": "7c9e6679-...",
"isEnabled": true,
"shareMonitor": true,
"shareWeather": true,
"shareForecast": false,
"shareReturns": false
}

Update Sharing Configuration

Authorization: Required

PUT /api/sharing/{sunSourceId}

Request Body

{
"isEnabled": true,
"shareMonitor": true,
"shareWeather": true,
"shareForecast": true,
"shareReturns": false
}

Public Endpoints (No Authentication)

These endpoints are accessible without authentication when sharing is enabled for the Sun Source.

EndpointSharing FlagDescription
GET /api/sharing/public/{sunSourceId}isEnabledBasic source info
GET /api/sharing/public/{sunSourceId}/metricsshareMonitorLatest metrics
GET /api/sharing/public/{sunSourceId}/metrics/historyshareMonitorHistorical metrics
GET /api/sharing/public/{sunSourceId}/weathershareWeatherWeather data
GET /api/sharing/public/{sunSourceId}/forecastshareForecastML predictions
GET /api/sharing/public/{sunSourceId}/roishareReturnsROI summary

Public Metrics History Parameters

ParameterTypeDefaultConstraints
startTimeDateTime24h agoOptional
endTimeDateTimeNowOptional
limitint1001–1,000

Export

Base Route: /api/export
Authorization: Required

Export as CSV

GET /api/export/{sunSourceId}/csv?startDate=2025-06-01&endDate=2025-06-20

Export as Excel

GET /api/export/{sunSourceId}/excel?startDate=2025-06-01&endDate=2025-06-20

Parameters (Both Endpoints)

ParameterTypeRequiredConstraints
startDateDateTimeYesStart of export range
endDateDateTimeYesEnd of export range

Maximum range: 33 days. Exceeding this returns 400 Bad Request.

Response

Returns the file download with appropriate Content-Type and Content-Disposition headers:

  • CSV: text/csvexport_{name}_{date}.csv
  • Excel: application/vnd.openxmlformats-officedocument.spreadsheetml.sheetexport_{name}_{date}.xlsx

Upload

Base Route: /api/upload
Authorization: Required

Upload Image

POST /api/upload/image
Content-Type: multipart/form-data

Form Fields

FieldTypeDescription
fileIFormFileImage file

Validation

RuleConstraint
Max file size5 MB
Allowed MIME typesimage/jpeg, image/png, image/gif, image/webp
Magic byte validationJPEG (FF D8 FF), PNG (89 50 4E 47), GIF (47 49 46 38), WebP (52 49 46 46)

Response 200 OK

{
"url": "https://minio.ampra.solar/ampra-uploads/users/{userId}/{filename}"
}

Delete Image

DELETE /api/upload/image?url=https://minio.ampra.solar/ampra-uploads/users/{userId}/image.png

Validation

  • URL must be absolute HTTP/HTTPS
  • File must belong to the authenticated user (path must contain their user ID)

Response 200 OK

{
"message": "Image deleted."
}

Webhooks

Base Route: /api/webhook
Authorization: None (validated by webhook secret)

Receive Telemetry Data

POST /api/webhook/sunsource/{sunSourceId}
Content-Type: application/json

Payload

Raw JSON body containing telemetry data with the webhook secret. Maximum payload size: 64 KB.

The webhook secret is validated from the payload body. The data is then normalized using the same field alias system as MQTT ingestion and stored in MongoDB.

Response

StatusCondition
200 OKData accepted and stored
400 Bad RequestInvalid payload or missing secret
404 Not FoundSun Source not found or inactive

MQTT Auth (Internal)

Base Route: /api/internal/mqtt
Authorization: Internal API key (X-Internal-API-Key header)

info

These endpoints are called by the EMQX broker for client authentication and ACL checks. They are not intended for direct consumption.

Authenticate MQTT Client

POST /api/internal/mqtt/auth
X-Internal-API-Key: {internal-api-key}

Request Body

{
"clientId": "sunsource_7c9e6679",
"username": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"password": "ak_xxxxxxxxxxxxxxxxxxxxxxxx"
}

Response

{ "result": "allow", "is_superuser": false }

or

{ "result": "deny" }

Check MQTT ACL

POST /api/internal/mqtt/acl
X-Internal-API-Key: {internal-api-key}

Request Body

{
"clientId": "sunsource_7c9e6679",
"username": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"topic": "sunsource/7c9e6679-7425-40de-944b-e07fc1f90ae7/data",
"action": "publish"
}

Response

{ "result": "allow" }

Validates that the client is only allowed to publish to their own sunsource/{id}/data topic.