energy-app-middle is a BFF + API aggregation layer for the distributed energy management platform. It exposes REST APIs to three client types (Owner / Provider / Platform) and orchestrates calls to IoT Core, IoT PaaS, IAM, algorithm services, and time-series databases.
Client TypeBase PathAudienceOwner API/api/owner/*Energy asset ownersProvider API/api/provider/*Service providersPlatform API/platform-api/*Platform adminsgRPC Serverport 9090Internal servicesManagementport 38081Actuator / metrics
/api/owner/)#MethodPathDescriptionGET/api/owner/der/control_record/{resourceId}DER control records (paginated)GET/POST/api/owner/der/control_automation/{resourceId}DER automation settingsPOST/api/owner/der/control_automation/{resourceId}/switchToggle automation on/offPOST/api/owner/der/control_automation/{resourceId}/deviceDevice automation propertiesGET/POST/api/owner/project/price/{projectId}Electricity pricingGET/api/owner/project/statistics/*Project electricity statisticsGET/api/owner/project/trend/*Project trend chartsGET/POST/api/owner/der/plan_prompt/*DER plan prompts
/api/provider/)#MethodPathDescriptionGET/api/provider/der/{resourceId}/billing_typeBilling type (TOU/Market)GET/POST/api/provider/der/{resourceId}/market_price_configMarket price configs
/platform-api/)#MethodPathDescriptionGET/platform-api/market/config?marketCode={code}Market metric configurationsPOST/platform-api/dataQuery market metric data
Token validation is delegated to IAM via gRPC. All requests must carry:
HeaderDescriptionX-ACCESS-TOKENJWT token (validated by IAM)X-AppApp codeX-TenantTenant codeX-UIDUser UID (set by gateway)X-PUIDParent UID (for sub-accounts)
All data is tenant-scoped — tenantCode is extracted from request context and applied to every query.
xml
<dependency>
<groupId>com.feilun</groupId>
<artifactId>energy-app-middle-grpc-interface</artifactId>
</dependency>
yaml
grpc:
client:
energy-app-middle:
address: dns:///energy-app-middle.${K8S_POD_NS}.svc.cluster.local:9090
negotiationType: PLAINTEXT
enableKeepAlive: true
ServiceProtocolPurposeiamgRPCToken validation, authorizationiot-coregRPCDevice management & queriesiot-paasgRPCDevice grouping, batch tasksbasicgRPCInfrastructure servicesalgorithm-der-power-forecastHTTPPV power forecastingalgorithm-dispatchHTTPDR dispatch planningalgorithm-bess-optHTTPBattery storage optimizationalgorithm-bidHTTPVPP spot biddingMySQLJDBCTransactional dataTDEngineJDBCTime-series device metricsRisingWaveJDBCReal-time metric aggregationApache PulsarMessagingDevice events, market dataPowerJobHTTPDistributed job scheduling
text
DerAutomationSettingsReq:
dailyMaxImport/Export, dailyMinimalImport/Export (Double)
maximumExportPower/ImportPower (Double)
opportunityImportPrice/ExportPrice (Double)
DerControlRecordRes:
resourceId, controlCode, status
startTime, endTime, controlDate
controlCurve (JSON array of power points)
MarketMetricDataReq:
marketCode (AEMO_REGIONS: NSW1/QLD1/VIC1/SA1/TAS1)
metrics (List<String>), targetId, startTime, endTime
VariablePurposeK8S_POD_NSKubernetes namespace (used in gRPC addresses)BIZ_NAMEBusiness code ( energy-app-middle)SPRING_PROFILES_ACTIVEProfile ( localdev / prod)k8s.all.mysql.host/portMySQL connectionk8s.eam.mysql.databaseMySQL database namek8s.all.tdengine.hostTDEngine hostk8s.all.risingwave.host/portRisingWave connectionk8s.all.pulsar.service-urlPulsar broker URLk8s.all.powerjob.worker.server-addressPowerJob server
MistakeFixMissing X-Tenant headerRequired for all requests — tenant isolation is enforcedCalling gRPC without X-UID/ X-PUIDIoT PaaS interceptor requires both headersQuerying metrics without time rangeTDEngine/RisingWave queries require startTime + endTimeWrong marketCodeAEMO regions: NSW1, QLD1, VIC1, SA1, TAS1 only