♻️ Chapter 7: Integration Patterns

WIA-ENE-004 eBook Series | Estimated reading time: 35 minutes

7.1 Integration Architecture Overview

WIA-ENE-004 supports diverse integration scenarios, from simple API connections to complex multi-system orchestrations. Understanding the right integration pattern for your use case is crucial for success.

Integration Patterns

PatternUse CaseComplexityReal-time
Point-to-Point API Simple integrations, direct connections Low Yes
Message Queue Asynchronous communication, decoupling Medium Yes
Event-Driven Reactive systems, microservices Medium Yes
API Gateway Unified access, multiple backends Medium Yes
ETL/Batch Bulk data transfer, legacy systems Low No
GraphQL Federation Unified schema across services High Yes

7.2 RESTful API Integration

RESTful APIs are the most common integration method for WIA-ENE-004 systems.

Complete Integration Example

// TypeScript SDK Integration
import { RenewableEnergyClient } from '@wia/ene-004-sdk'

// Initialize client
const client = new RenewableEnergyClient({
  apiEndpoint: 'https://api.renewable-energy.example.com',
  apiKey: process.env.WIA_ENE_API_KEY,
  version: 'v1'
})

// List all energy sources
const sources = await client.sources.list({
  type: 'SOLAR-PV',
  status: 'ACTIVE',
  limit: 100
})

console.log(`Found ${sources.total} solar sources`)

// Get specific source details
const source = await client.sources.get('SOLAR-PV-001')
console.log(`Source: ${source.name}, Capacity: ${source.capacity}kW`)

// Get production data
const production = await client.production.get('SOLAR-PV-001', {
  period: '24h',
  resolution: '15min'
})

console.log(`Total production: ${production.summary.total}kWh`)

// Subscribe to real-time updates
client.realtime.subscribe('SOLAR-PV-001', {
  events: ['production', 'status', 'alerts'],
  callback: (event) => {
    console.log('Real-time event:', event)

    if (event.type === 'alert' && event.severity === 'HIGH') {
      // Handle high-severity alert
      handleAlert(event)
    }
  }
})

// Create alert rule
await client.alerts.createRule({
  sourceId: 'SOLAR-PV-001',
  name: 'Low Production Alert',
  condition: {
    metric: 'efficiency',
    operator: 'less_than',
    threshold: 80,
    duration: '15min'
  },
  actions: [
    { type: 'email', recipients: ['ops@example.com'] },
    { type: 'slack', channel: '#renewable-energy' }
  ]
})

Error Handling Best Practices

// Robust error handling
async function getProductionDataSafely(sourceId, options) {
  const maxRetries = 3
  let lastError

  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      const data = await client.production.get(sourceId, options)
      return data
    } catch (error) {
      lastError = error

      if (error.code === 'RATE_LIMIT_EXCEEDED') {
        // Exponential backoff
        const delay = Math.pow(2, attempt) * 1000
        await sleep(delay)
        continue
      }

      if (error.code === 'SOURCE_NOT_FOUND') {
        // Don't retry on client errors
        throw error
      }

      if (error.code === 'SERVICE_UNAVAILABLE' && attempt < maxRetries) {
        // Retry on server errors
        continue
      }

      throw error
    }
  }

  throw new Error(`Failed after ${maxRetries} attempts: ${lastError.message}`)
}

7.3 MQTT Integration for IoT Devices

MQTT provides lightweight, efficient communication for IoT devices and edge gateways.

MQTT Publisher Example

// Python: MQTT publisher for edge device
import paho.mqtt.client as mqtt
import json
import time

# MQTT Configuration
BROKER = 'mqtt.renewable-energy.example.com'
PORT = 8883  # TLS
TOPIC_PREFIX = 'wia-ene/sources'

# Initialize MQTT client
client = mqtt.Client(client_id='solar-pv-001-gateway')
client.username_pw_set('device-001', 'secret-token')
client.tls_set(ca_certs='/path/to/ca.crt')

# Connect to broker
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()

# Publish production data
def publish_production_data(source_id, data):
    topic = f'{TOPIC_PREFIX}/{source_id}/production'
    payload = json.dumps({
        'timestamp': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
        'sourceId': source_id,
        'production': data
    })

    result = client.publish(topic, payload, qos=1)

    if result.rc == mqtt.MQTT_ERR_SUCCESS:
        print(f'Published: {topic}')
    else:
        print(f'Failed to publish: {result.rc}')

# Main data collection loop
while True:
    production_data = {
        'instantaneous': {
            'value': read_inverter_power(),
            'unit': 'kW'
        },
        'cumulative': {
            'today': read_daily_energy(),
            'unit': 'kWh'
        }
    }

    publish_production_data('SOLAR-PV-001', production_data)
    time.sleep(60)  # Publish every minute

MQTT Subscriber Example

// Node.js: MQTT subscriber for analytics service
const mqtt = require('mqtt')

const client = mqtt.connect('mqtts://mqtt.renewable-energy.example.com:8883', {
  username: 'analytics-service',
  password: process.env.MQTT_PASSWORD,
  ca: fs.readFileSync('/path/to/ca.crt')
})

// Subscribe to all production topics
client.subscribe('wia-ene/sources/+/production', { qos: 1 })

// Handle incoming messages
client.on('message', async (topic, message) => {
  try {
    const data = JSON.parse(message.toString())

    // Extract source ID from topic
    const sourceId = topic.split('/')[2]

    // Store in time-series database
    await storeProductionData(sourceId, data)

    // Run real-time analytics
    await analyzeProduction(sourceId, data)

    // Check alert conditions
    await checkAlertConditions(sourceId, data)

  } catch (error) {
    console.error('Error processing message:', error)
  }
})

client.on('error', (error) => {
  console.error('MQTT error:', error)
})

client.on('reconnect', () => {
  console.log('Reconnecting to MQTT broker...')
})

7.4 Grid Integration

Connecting renewable energy sources to electrical grids requires specialized protocols and compliance.

Grid Integration Protocols

ProtocolPurposeRegionWIA-ENE-004 Support
IEC 61850 Substation automation Global Native adapter
DNP3 SCADA communications North America Protocol gateway
Modbus Industrial control Global Native support
OpenADR Demand response Global Built-in integration
SunSpec Solar inverter communication Global Device driver

Demand Response Integration

// OpenADR 2.0b Integration
{
  "demandResponse": {
    "enabled": true,
    "protocol": "OpenADR-2.0b",
    "vtnUrl": "https://vtn.utility.example.com/OpenADR2/Simple/2.0b",
    "venId": "ven-renewable-001",
    "registration": {
      "venName": "Solar Farm Alpha",
      "httpPullModel": true,
      "reportOnly": false
    },
    "capabilities": {
      "curtailment": {
        "enabled": true,
        "maxReduction": 20,
        "minNotice": 600
      },
      "loadShift": {
        "enabled": true,
        "batteryCapacity": 500
      }
    },
    "events": {
      "optIn": "automatic",
      "optOut": "manual-approval",
      "preHeat": true,
      "reporting": {
        "baseline": "meter-before",
        "interval": 300
      }
    }
  }
}

7.5 Third-Party Platform Integration

WIA-ENE-004 integrates seamlessly with popular cloud platforms and energy management systems.

Cloud Platform Integrations

AWS Integration Example

// AWS IoT Integration
{
  "aws": {
    "iot": {
      "endpoint": "a3example123.iot.us-west-2.amazonaws.com",
      "certificate": "/path/to/device-cert.pem",
      "privateKey": "/path/to/private-key.pem",
      "caFile": "/path/to/root-ca.pem",
      "clientId": "solar-pv-001"
    },
    "topics": {
      "telemetry": "renewable-energy/solar-pv-001/telemetry",
      "shadow": "$aws/things/solar-pv-001/shadow/update",
      "commands": "renewable-energy/solar-pv-001/commands"
    },
    "rules": [
      {
        "name": "StoreTelemetryInTimestream",
        "sql": "SELECT * FROM 'renewable-energy/+/telemetry'",
        "actions": [
          {
            "timestream": {
              "database": "RenewableEnergy",
              "table": "ProductionData"
            }
          }
        ]
      },
      {
        "name": "AlertOnLowProduction",
        "sql": "SELECT * FROM 'renewable-energy/+/telemetry' WHERE efficiency < 80",
        "actions": [
          {
            "sns": {
              "targetArn": "arn:aws:sns:us-west-2:123456789:alerts"
            }
          }
        ]
      }
    ]
  }
}

7.6 Data Exchange Formats

WIA-ENE-004 supports multiple data formats to accommodate diverse integration requirements.

Supported Formats

FormatUse CaseAdvantagesLimitations
JSON API responses, web apps Human-readable, universal support Verbose, no schema enforcement
JSON Schema API validation Schema validation, type safety Additional complexity
Protocol Buffers High-performance, microservices Compact, fast, schema-based Not human-readable
CSV Bulk exports, legacy systems Simple, Excel-compatible No nested structures
XML Enterprise integrations, SOAP Industry standard, schema support Verbose, complex parsing

Format Conversion Example

// Convert WIA-ENE-004 data to multiple formats
class DataConverter {
  static toJSON(data) {
    return JSON.stringify(data, null, 2)
  }

  static toCSV(dataArray) {
    const headers = Object.keys(dataArray[0])
    const rows = dataArray.map(obj =>
      headers.map(h => JSON.stringify(obj[h])).join(',')
    )
    return [headers.join(','), ...rows].join('\n')
  }

  static toXML(data, rootElement = 'data') {
    const escape = (str) => String(str)
      .replace(/&/g, '&')
      .replace(//g, '>')

    const objToXml = (obj, indent = 0) => {
      const pad = '  '.repeat(indent)
      let xml = ''

      for (const [key, value] of Object.entries(obj)) {
        if (typeof value === 'object' && !Array.isArray(value)) {
          xml += `${pad}<${key}>\n${objToXml(value, indent + 1)}${pad}\n`
        } else if (Array.isArray(value)) {
          value.forEach(item => {
            xml += `${pad}<${key}>${escape(item)}\n`
          })
        } else {
          xml += `${pad}<${key}>${escape(value)}\n`
        }
      }
      return xml
    }

    return `\n<${rootElement}>\n${objToXml(data, 1)}`
  }

  static toProtobuf(data, schema) {
    // Using protobufjs library
    const root = protobuf.parse(schema).root
    const MessageType = root.lookupType('ProductionData')
    const message = MessageType.create(data)
    return MessageType.encode(message).finish()
  }
}

7.7 Webhook Integration

Webhooks enable real-time notifications to external systems when specific events occur.

Webhook Configuration

// Create webhook subscription
POST /api/v1/webhooks
{
  "name": "Production Alert Webhook",
  "url": "https://external-system.example.com/webhooks/wia-ene",
  "events": [
    "production.threshold_exceeded",
    "source.status_changed",
    "alert.created"
  ],
  "headers": {
    "X-Webhook-Secret": "shared-secret-key"
  },
  "retry": {
    "maxAttempts": 3,
    "backoff": "exponential"
  },
  "filters": {
    "sourceType": ["SOLAR-PV", "WIND-ON"],
    "severity": ["HIGH", "CRITICAL"]
  }
}

// Webhook payload example
POST https://external-system.example.com/webhooks/wia-ene
{
  "eventId": "evt_1234567890",
  "eventType": "production.threshold_exceeded",
  "timestamp": "2025-12-25T14:30:00Z",
  "data": {
    "sourceId": "SOLAR-PV-001",
    "metric": "efficiency",
    "value": 75.2,
    "threshold": 80.0,
    "severity": "MEDIUM"
  },
  "signature": "sha256=a1b2c3d4..."
}

Webhook Receiver Example

// Express.js webhook receiver
const express = require('express')
const crypto = require('crypto')

const app = express()
app.use(express.json())

const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET

function verifySignature(payload, signature) {
  const hash = crypto
    .createHmac('sha256', WEBHOOK_SECRET)
    .update(JSON.stringify(payload))
    .digest('hex')

  return `sha256=${hash}` === signature
}

app.post('/webhooks/wia-ene', (req, res) => {
  const signature = req.headers['x-webhook-signature']

  if (!verifySignature(req.body, signature)) {
    return res.status(401).json({ error: 'Invalid signature' })
  }

  const { eventType, data } = req.body

  // Process webhook based on event type
  switch (eventType) {
    case 'production.threshold_exceeded':
      handleProductionAlert(data)
      break
    case 'source.status_changed':
      handleStatusChange(data)
      break
    case 'alert.created':
      handleNewAlert(data)
      break
    default:
      console.log(`Unknown event type: ${eventType}`)
  }

  // Acknowledge receipt
  res.status(200).json({ received: true })
})

app.listen(3000, () => {
  console.log('Webhook server listening on port 3000')
})

7.8 Batch Data Integration

For systems that don't require real-time updates, batch integration provides an efficient alternative.

Batch Export Example

// Schedule daily batch export
{
  "batchExport": {
    "schedule": "0 2 * * *",  // Daily at 2 AM
    "format": "csv",
    "compression": "gzip",
    "destination": {
      "type": "s3",
      "bucket": "renewable-energy-exports",
      "path": "production-data/{date}/",
      "credentials": {
        "accessKeyId": "${AWS_ACCESS_KEY_ID}",
        "secretAccessKey": "${AWS_SECRET_ACCESS_KEY}"
      }
    },
    "query": {
      "timeRange": "yesterday",
      "sources": ["SOLAR-*", "WIND-*"],
      "metrics": ["production", "efficiency", "environmentalConditions"],
      "resolution": "15min"
    },
    "notifications": {
      "onSuccess": ["data-team@example.com"],
      "onFailure": ["ops@example.com"]
    }
  }
}

Batch Import Example

// Batch import historical data
curl -X POST https://api.wia.org/v1/import/batch \
  -H "Authorization: Bearer ${TOKEN}" \
  -F "file=@historical_data.csv" \
  -F "config={\"sourceId\":\"SOLAR-PV-001\",\"timestampColumn\":\"datetime\",\"mappings\":{\"power\":\"production.instantaneous.value\",\"energy\":\"production.cumulative.today\"}}"

# Response
{
  "importId": "imp_abc123",
  "status": "processing",
  "totalRecords": 35040,
  "processedRecords": 0,
  "errors": [],
  "estimatedCompletion": "2025-12-25T15:00:00Z"
}

# Check import status
curl https://api.wia.org/v1/import/batch/imp_abc123 \
  -H "Authorization: Bearer ${TOKEN}"

7.9 GraphQL Integration

GraphQL provides a flexible, efficient alternative to REST for complex data requirements.

GraphQL Query Examples

# Fetch multiple resources in single request
query {
  source(id: "SOLAR-PV-001") {
    id
    name
    capacity
    location {
      latitude
      longitude
    }
    currentProduction {
      timestamp
      power
      efficiency
    }
    alerts(severity: HIGH) {
      id
      title
      createdAt
    }
    forecast(period: "24h") {
      timestamp
      predicted
      confidence
    }
  }
}

# Mutation: Update configuration
mutation {
  updateSourceConfig(
    id: "SOLAR-PV-001"
    config: {
      monitoring: { interval: 30 }
      alerts: { efficiencyThreshold: 85 }
    }
  ) {
    id
    config {
      monitoring {
        interval
      }
    }
  }
}

# Subscription: Real-time updates
subscription {
  productionUpdates(sourceId: "SOLAR-PV-001") {
    timestamp
    power
    efficiency
  }
}

7.10 Integration Best Practices

Follow these best practices to ensure robust, maintainable integrations.

Integration Checklist

CategoryBest PracticesImportance
Authentication Use OAuth 2.0, rotate credentials, store secrets securely Critical
Error Handling Implement retries, exponential backoff, circuit breakers High
Rate Limiting Respect rate limits, implement client-side throttling High
Monitoring Log all integration activity, track success/failure rates High
Versioning Use API versioning, plan for deprecation Medium
Documentation Document integration endpoints, data flows, dependencies Medium

Chapter 8 Preview

In Chapter 8, we'll explore the future roadmap for WIA-ENE-004, including upcoming features, emerging technologies, and the evolution of renewable energy standards.