Energy Data Format
Energy Consumption Data Model
{
"version": "1.0",
"standard": "WIA-ENE-014",
"timestamp": "2025-12-25T10:30:00Z",
"energyData": {
"consumption": {
"total": 1250.5,
"unit": "kWh",
"breakdown": {
"residential": 450.2,
"commercial": 550.8,
"industrial": 249.5
}
},
"generation": {
"total": 1300.0,
"unit": "kWh",
"sources": {
"solar": 420.5,
"wind": 380.2,
"hydro": 250.0,
"grid": 249.3
}
},
"storage": {
"capacity": 500.0,
"current": 325.5,
"unit": "kWh",
"status": "charging"
}
},
"metadata": {
"location": "Seoul, South Korea",
"gridId": "KR-SE-001",
"quality": "high",
"confidence": 0.98
}
}
Virtual Power Plant Data
{
"vppId": "VPP-KR-001",
"name": "Seoul Smart Grid VPP",
"capacity": 50000,
"unit": "kW",
"resources": [
{
"id": "SOLAR-001",
"type": "solar",
"capacity": 15000,
"current": 12500,
"efficiency": 0.83,
"location": { "lat": 37.5665, "lng": 126.9780 }
},
{
"id": "WIND-002",
"type": "wind",
"capacity": 20000,
"current": 18000,
"efficiency": 0.90,
"location": { "lat": 37.5700, "lng": 126.9850 }
},
{
"id": "BATTERY-003",
"type": "storage",
"capacity": 15000,
"current": 10000,
"soc": 0.67,
"location": { "lat": 37.5600, "lng": 126.9750 }
}
],
"aggregatedOutput": 40500,
"status": "operational",
"lastUpdate": "2025-12-25T10:30:00Z"
}
Data Format Generator
Energy Management Algorithms
Demand Forecasting Algorithm
// LSTM-based Energy Demand Forecasting
class EnergyDemandForecaster {
constructor(config) {
this.lookbackPeriod = config.lookbackPeriod || 168; // 7 days in hours
this.forecastHorizon = config.forecastHorizon || 24; // 24 hours ahead
this.features = ['hour', 'dayOfWeek', 'temperature', 'humidity', 'historical'];
}
async forecast(historicalData) {
// Normalize input data
const normalized = this.normalize(historicalData);
// Extract features
const features = this.extractFeatures(normalized);
// LSTM prediction
const prediction = await this.lstmPredict(features);
// Denormalize and return
return this.denormalize(prediction);
}
extractFeatures(data) {
return data.map((point, index) => ({
hour: new Date(point.timestamp).getHours(),
dayOfWeek: new Date(point.timestamp).getDay(),
temperature: point.weather.temperature,
humidity: point.weather.humidity,
historical: data.slice(Math.max(0, index - this.lookbackPeriod), index)
.map(p => p.consumption)
}));
}
normalize(data) {
const max = Math.max(...data.map(d => d.consumption));
const min = Math.min(...data.map(d => d.consumption));
return data.map(d => ({
...d,
consumption: (d.consumption - min) / (max - min)
}));
}
async lstmPredict(features) {
// TensorFlow.js LSTM model inference
// Returns array of predicted values for next 24 hours
return features; // Simplified for demo
}
}
Virtual Power Plant Optimization
// Genetic Algorithm for VPP Resource Allocation
class VPPOptimizer {
optimize(vpp, demand, constraints) {
const population = this.initializePopulation(100);
const generations = 50;
for (let gen = 0; gen < generations; gen++) {
// Evaluate fitness
const fitness = population.map(individual =>
this.evaluateFitness(individual, demand, constraints)
);
// Selection
const selected = this.tournamentSelection(population, fitness);
// Crossover
const offspring = this.crossover(selected);
// Mutation
const mutated = this.mutate(offspring);
population = mutated;
}
return this.getBestSolution(population, demand, constraints);
}
evaluateFitness(allocation, demand, constraints) {
let fitness = 0;
// Minimize cost
const cost = allocation.reduce((sum, resource) =>
sum + resource.output * resource.costPerKWh, 0
);
fitness -= cost;
// Maximize renewable usage
const renewableRatio = allocation
.filter(r => r.type === 'solar' || r.type === 'wind')
.reduce((sum, r) => sum + r.output, 0) / demand;
fitness += renewableRatio * 1000;
// Penalty for unmet demand
const totalOutput = allocation.reduce((sum, r) => sum + r.output, 0);
if (totalOutput < demand) {
fitness -= (demand - totalOutput) * 10;
}
return fitness;
}
}
Run Demand Forecast Simulation
Current Demand
1,250 kW
Predicted (1h)
1,320 kW
Predicted (24h)
1,450 kW
Accuracy
94.2%
Communication Protocols
REST API Endpoints
// Energy Cloud REST API v1.0
BASE_URL: https://api.energy-cloud.wia.org/v1
# Authentication
POST /auth/login
POST /auth/refresh
POST /auth/logout
# Virtual Power Plants
GET /vpp # List all VPPs
GET /vpp/:id # Get VPP details
POST /vpp # Create new VPP
PUT /vpp/:id # Update VPP
DELETE /vpp/:id # Delete VPP
GET /vpp/:id/resources # Get VPP resources
POST /vpp/:id/optimize # Run optimization
# Energy Data
GET /energy/consumption # Get consumption data
GET /energy/generation # Get generation data
POST /energy/forecast # Request forecast
GET /energy/real-time # WebSocket upgrade endpoint
# Trading
GET /trading/markets # List energy markets
POST /trading/orders # Place order
GET /trading/orders/:id # Get order status
DELETE /trading/orders/:id # Cancel order
GET /trading/history # Trading history
# Analytics
GET /analytics/dashboard # Dashboard metrics
POST /analytics/query # Custom analytics query
GET /analytics/reports/:id # Get report
# Example Request
curl -X POST https://api.energy-cloud.wia.org/v1/vpp/VPP-001/optimize \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"demand": 50000,
"constraints": {
"minRenewable": 0.6,
"maxCost": 0.15
}
}'
WebSocket Real-Time Data Stream
// WebSocket Connection for Real-Time Energy Data
const ws = new WebSocket('wss://api.energy-cloud.wia.org/v1/energy/real-time');
ws.onopen = () => {
console.log('Connected to Energy Cloud');
// Subscribe to energy data streams
ws.send(JSON.stringify({
action: 'subscribe',
channels: [
'consumption.real-time',
'generation.solar',
'vpp.VPP-001.status',
'trading.market.KRW-KWH'
]
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
switch(data.channel) {
case 'consumption.real-time':
updateConsumptionMetrics(data.payload);
break;
case 'generation.solar':
updateSolarGeneration(data.payload);
break;
case 'vpp.VPP-001.status':
updateVPPStatus(data.payload);
break;
case 'trading.market.KRW-KWH':
updateMarketPrice(data.payload);
break;
}
};
// Message Format
{
"channel": "consumption.real-time",
"timestamp": "2025-12-25T10:30:00Z",
"payload": {
"total": 1250.5,
"breakdown": {
"residential": 450.2,
"commercial": 550.8,
"industrial": 249.5
}
}
}
MQTT for IoT Device Integration
// MQTT Topics for Smart Grid Devices
# Topic Structure: energy-cloud/{region}/{deviceType}/{deviceId}/{metric}
# Publishing (Device โ Cloud)
energy-cloud/seoul/solar-panel/SP-001/generation
energy-cloud/seoul/battery/BAT-001/soc
energy-cloud/seoul/smart-meter/SM-001/consumption
energy-cloud/busan/wind-turbine/WT-001/output
# Subscribing (Cloud โ Device)
energy-cloud/seoul/battery/BAT-001/command
energy-cloud/seoul/inverter/INV-001/config
energy-cloud/+/+/+/status # Wildcard subscription
# Example: Solar Panel Publishing Data
import mqtt from 'mqtt';
const client = mqtt.connect('mqtts://mqtt.energy-cloud.wia.org', {
clientId: 'SP-001',
username: 'device-token',
password: 'YOUR_DEVICE_TOKEN',
clean: true
});
client.on('connect', () => {
setInterval(() => {
const generation = getCurrentGeneration();
client.publish(
'energy-cloud/seoul/solar-panel/SP-001/generation',
JSON.stringify({
timestamp: new Date().toISOString(),
value: generation,
unit: 'kW',
quality: 'high'
}),
{ qos: 1 }
);
}, 5000); // Every 5 seconds
});
// Subscribe to commands
client.subscribe('energy-cloud/seoul/solar-panel/SP-001/command');
client.on('message', (topic, message) => {
const command = JSON.parse(message.toString());
executeCommand(command);
});
Protocol Tester
System Integration
Smart Meter Integration
// Smart Meter Integration SDK
import { EnergyCloudClient } from '@wia/energy-cloud-sdk';
class SmartMeterIntegration {
constructor(config) {
this.client = new EnergyCloudClient({
apiKey: config.apiKey,
region: config.region
});
this.meterId = config.meterId;
}
async sendConsumptionData(data) {
try {
const response = await this.client.energy.consumption.create({
meterId: this.meterId,
timestamp: data.timestamp,
consumption: data.consumption,
voltage: data.voltage,
current: data.current,
powerFactor: data.powerFactor,
metadata: {
meterType: 'smart-meter-v2',
firmware: '2.1.5'
}
});
console.log('Data sent successfully:', response.id);
return response;
} catch (error) {
console.error('Failed to send data:', error);
throw error;
}
}
async getBillingData(startDate, endDate) {
return await this.client.energy.consumption.query({
meterId: this.meterId,
startDate,
endDate,
aggregation: 'hourly'
});
}
async subscribeToCommands(callback) {
this.client.on(`meter.${this.meterId}.command`, callback);
}
}
// Usage Example
const meter = new SmartMeterIntegration({
apiKey: 'your-api-key',
region: 'kr-seoul',
meterId: 'SM-001'
});
// Send real-time data every minute
setInterval(async () => {
const data = await readMeterData();
await meter.sendConsumptionData(data);
}, 60000);
SCADA System Integration
// SCADA to Energy Cloud Bridge
class SCADABridge {
constructor(scadaConfig, cloudConfig) {
this.scada = this.connectSCADA(scadaConfig);
this.cloud = new EnergyCloudClient(cloudConfig);
this.mappings = new Map();
}
// Map SCADA tags to Cloud entities
mapSCADATag(scadaTag, cloudEntity) {
this.mappings.set(scadaTag, cloudEntity);
}
async startBridge() {
// Subscribe to SCADA data changes
this.scada.on('data', async (tag, value) => {
const cloudEntity = this.mappings.get(tag);
if (cloudEntity) {
await this.cloud.updateEntity(cloudEntity, {
value: value.value,
timestamp: value.timestamp,
quality: value.quality
});
}
});
// Subscribe to Cloud commands
this.cloud.on('command', async (entity, command) => {
const scadaTag = this.findSCADATag(entity);
if (scadaTag) {
await this.scada.writeTag(scadaTag, command.value);
}
});
}
// Example mappings
setupMappings() {
this.mapSCADATag('SUBSTATION_1.VOLTAGE', 'vpp.VPP-001.voltage');
this.mapSCADATag('SUBSTATION_1.CURRENT', 'vpp.VPP-001.current');
this.mapSCADATag('TRANSFORMER_1.LOAD', 'vpp.VPP-001.load');
this.mapSCADATag('BREAKER_1.STATUS', 'vpp.VPP-001.breaker-status');
}
}
Blockchain Energy Trading Integration
// Blockchain-based P2P Energy Trading
import { ethers } from 'ethers';
import { EnergyCloudClient } from '@wia/energy-cloud-sdk';
class EnergyTradingBridge {
constructor(config) {
// Connect to blockchain
this.provider = new ethers.JsonRpcProvider(config.rpcUrl);
this.wallet = new ethers.Wallet(config.privateKey, this.provider);
this.contract = new ethers.Contract(
config.contractAddress,
EnergyTradingABI,
this.wallet
);
// Connect to Energy Cloud
this.cloud = new EnergyCloudClient(config.cloudApiKey);
}
async createEnergyListing(amount, price) {
// Verify available energy in cloud
const available = await this.cloud.energy.getAvailable();
if (available < amount) {
throw new Error('Insufficient energy available');
}
// Create blockchain listing
const tx = await this.contract.createListing(
ethers.parseUnits(amount.toString(), 18),
ethers.parseUnits(price.toString(), 18),
Math.floor(Date.now() / 1000) + 3600 // 1 hour expiry
);
await tx.wait();
// Register in Energy Cloud
await this.cloud.trading.registerListing({
blockchainTxHash: tx.hash,
amount,
price,
seller: this.wallet.address
});
return tx.hash;
}
async executeTrade(listingId) {
const listing = await this.contract.listings(listingId);
// Execute blockchain transaction
const tx = await this.contract.executeTrade(listingId, {
value: listing.price
});
await tx.wait();
// Update Energy Cloud records
await this.cloud.trading.recordTrade({
listingId,
buyer: this.wallet.address,
seller: listing.seller,
amount: listing.amount,
price: listing.price,
blockchainTxHash: tx.hash,
timestamp: new Date().toISOString()
});
// Transfer energy allocation
await this.cloud.energy.transfer({
from: listing.seller,
to: this.wallet.address,
amount: listing.amount
});
return tx.hash;
}
// Listen for blockchain events
async subscribeToTrades() {
this.contract.on('TradeExecuted', async (listingId, buyer, seller, amount, price) => {
console.log('Trade executed:', { listingId, buyer, seller, amount, price });
// Sync with Energy Cloud
await this.cloud.trading.syncBlockchainTrade({
listingId: listingId.toString(),
buyer,
seller,
amount: ethers.formatUnits(amount, 18),
price: ethers.formatUnits(price, 18)
});
});
}
}
Integration Status Dashboard
| System | Status | Last Sync | Messages/min |
|---|---|---|---|
| Smart Meters | Connected | 2 seconds ago | 1,250 |
| SCADA Systems | Connected | 5 seconds ago | 450 |
| Blockchain Network | Connected | 1 minute ago | 25 |
| Weather API | Connected | 30 seconds ago | 12 |
| DER Controllers | Connected | 3 seconds ago | 820 |
Testing Suite
Unit Tests
// Jest Unit Tests for Energy Cloud SDK
import { EnergyCloudClient } from '@wia/energy-cloud-sdk';
import { VPPOptimizer } from './algorithms/vpp-optimizer';
describe('EnergyCloudClient', () => {
let client;
beforeEach(() => {
client = new EnergyCloudClient({
apiKey: 'test-api-key',
environment: 'test'
});
});
test('should authenticate successfully', async () => {
const response = await client.auth.login({
username: 'test@example.com',
password: 'password123'
});
expect(response.token).toBeDefined();
expect(response.expiresIn).toBe(3600);
});
test('should fetch VPP data', async () => {
const vpp = await client.vpp.get('VPP-001');
expect(vpp.id).toBe('VPP-001');
expect(vpp.resources).toBeInstanceOf(Array);
expect(vpp.capacity).toBeGreaterThan(0);
});
test('should create consumption record', async () => {
const record = await client.energy.consumption.create({
meterId: 'SM-001',
consumption: 125.5,
timestamp: new Date().toISOString()
});
expect(record.id).toBeDefined();
expect(record.consumption).toBe(125.5);
});
});
describe('VPPOptimizer', () => {
let optimizer;
beforeEach(() => {
optimizer = new VPPOptimizer({
populationSize: 100,
generations: 50
});
});
test('should optimize resource allocation', () => {
const vpp = {
resources: [
{ id: 'SOLAR-001', type: 'solar', capacity: 1000, costPerKWh: 0.05 },
{ id: 'WIND-001', type: 'wind', capacity: 1500, costPerKWh: 0.06 },
{ id: 'GRID-001', type: 'grid', capacity: 5000, costPerKWh: 0.12 }
]
};
const result = optimizer.optimize(vpp, 2000, { minRenewable: 0.7 });
const totalOutput = result.reduce((sum, r) => sum + r.output, 0);
expect(totalOutput).toBeGreaterThanOrEqual(2000);
const renewableRatio = result
.filter(r => r.type === 'solar' || r.type === 'wind')
.reduce((sum, r) => sum + r.output, 0) / totalOutput;
expect(renewableRatio).toBeGreaterThanOrEqual(0.7);
});
});
Integration Tests
// Integration Tests for Energy Cloud Platform
describe('Energy Cloud Integration', () => {
test('End-to-end VPP optimization flow', async () => {
// 1. Create VPP
const vpp = await client.vpp.create({
name: 'Test VPP',
capacity: 10000,
location: { lat: 37.5665, lng: 126.9780 }
});
expect(vpp.id).toBeDefined();
// 2. Add resources
await client.vpp.addResource(vpp.id, {
type: 'solar',
capacity: 5000,
location: { lat: 37.5700, lng: 126.9800 }
});
// 3. Run optimization
const optimization = await client.vpp.optimize(vpp.id, {
demand: 8000,
constraints: { minRenewable: 0.8 }
});
expect(optimization.status).toBe('completed');
expect(optimization.allocation).toBeDefined();
// 4. Apply allocation
const result = await client.vpp.applyAllocation(vpp.id, optimization.allocation);
expect(result.success).toBe(true);
// 5. Verify actual output
await new Promise(resolve => setTimeout(resolve, 5000));
const status = await client.vpp.getStatus(vpp.id);
expect(status.currentOutput).toBeCloseTo(8000, -2);
});
test('Real-time data flow: Smart Meter โ Cloud โ Analytics', async () => {
const meterId = 'SM-TEST-001';
// 1. Send consumption data
await client.energy.consumption.create({
meterId,
consumption: 150.5,
timestamp: new Date().toISOString()
});
// 2. Wait for processing
await new Promise(resolve => setTimeout(resolve, 2000));
// 3. Query analytics
const analytics = await client.analytics.query({
metric: 'consumption',
filters: { meterId },
timeRange: 'last-1-hour'
});
expect(analytics.data.length).toBeGreaterThan(0);
expect(analytics.data[0].consumption).toBe(150.5);
});
test('Energy trading workflow', async () => {
// 1. Create listing
const listing = await client.trading.createListing({
amount: 100,
price: 0.10,
expiry: Date.now() + 3600000
});
expect(listing.id).toBeDefined();
// 2. Execute trade
const trade = await client.trading.executeTrade(listing.id);
expect(trade.status).toBe('completed');
// 3. Verify energy transfer
const balance = await client.energy.getBalance();
expect(balance).toBe(100);
});
});
Performance Tests
// Load Testing with Artillery
config:
target: 'https://api.energy-cloud.wia.org'
phases:
- duration: 60
arrivalRate: 10
name: "Warm up"
- duration: 300
arrivalRate: 50
name: "Sustained load"
- duration: 120
arrivalRate: 100
name: "Peak load"
scenarios:
- name: "VPP Status Check"
flow:
- get:
url: "/v1/vpp/{{ vppId }}"
headers:
Authorization: "Bearer {{ token }}"
- think: 1
- name: "Real-time Consumption Data"
flow:
- post:
url: "/v1/energy/consumption"
json:
meterId: "{{ meterId }}"
consumption: "{{ $randomNumber(50, 500) }}"
timestamp: "{{ $timestamp }}"
- think: 0.5
- name: "Demand Forecast"
flow:
- post:
url: "/v1/energy/forecast"
json:
horizon: 24
location: "seoul"
- think: 2
# Expected Performance Metrics
# - Response time p95: < 200ms
# - Response time p99: < 500ms
# - Error rate: < 0.1%
# - Throughput: > 10,000 req/s
Test Execution Dashboard
Tests Passed
247
Tests Failed
5
Code Coverage
94.2%
Avg Response Time
145ms
[INFO] Test suite initialized
[PASS] EnergyCloudClient authentication tests (5/5)
[PASS] VPP optimization tests (12/12)
[PASS] Energy trading tests (8/8)
[WARN] Performance test: p99 latency 523ms (target: 500ms)
[PASS] Integration tests (25/25)
[INFO] All tests completed in 45.3s