Monitoring Power Events#

Overview#

This use case demonstrates how to receive real-time notifications of power events using webhooks. Grid integrators can register webhooks to receive notifications when power ramp up/down events start and complete, enabling real-time tracking of datacenter power changes.

Goal#

Receive real-time notifications when datacenter power changes occur, enabling grid solutions to track target achievement, report status to utilities, and coordinate with other grid services.

Persona: Grid Integration Engineer#

Role: Developer integrating commercial grid solutions with DPS for datacenter power management.

Objective: Implement webhook receivers to track power events and maintain real-time awareness of datacenter power state.

Use Case Workflow#

Scenario: Grid solution needs to track when power constraints are applied and report status to utility

Workflow Steps:

  1. Implement Webhook Receiver - Create HTTP endpoint to receive power event notifications

  2. Register Webhook - Subscribe to power events via NvGrid API

  3. Process Events - Parse webhook payloads and extract power event data

  4. Unregister Webhook - Clean up webhook subscription when no longer needed


Theory of Operation#

Power Events#

DPS NvGrid sends webhook notifications for four power events:

  • START_RAMP_UP: Power constraint is relaxing (increasing power limit)

  • END_RAMP_UP: Power ramp up complete, new higher limit reached

  • START_RAMP_DOWN: Power constraint is tightening (decreasing power limit)

  • END_RAMP_DOWN: Power ramp down complete, new lower limit reached

Webhook Lifecycle#

sequenceDiagram participant GS as Grid Solution participant NvGrid as NvGrid API participant DPS as DPS Scheduler participant Webhook as Webhook Endpoint GS->>NvGrid: RegisterWebhook(url, events) NvGrid-->>GS: Success Note over GS,DPS: Time passes, load target scheduled DPS->>DPS: Load target start time reached DPS->>Webhook: POST /webhook (START_RAMP_DOWN) Webhook-->>DPS: 200 OK Note over DPS: Power reduction in progress DPS->>Webhook: POST /webhook (END_RAMP_DOWN) Webhook-->>DPS: 200 OK Note over GS: When done monitoring GS->>NvGrid: UnregisterWebhook(url) NvGrid-->>GS: Success

Event Payload#

Webhooks receive HTTP POST requests with JSON payloads:

{
  "event": "start_ramp_down",
  "feed_tag": "main_power_feed",
  "start_time": "2025-10-24T17:00:00Z",
  "end_time": "2025-10-24T18:00:00Z",
  "strategy": "best_effort",
  "target_load": {
    "value": 6.5,
    "unit": "mw"
  },
  "prev_target_load": {
    "value": 10.0,
    "unit": "mw"
  },
  "calculated_load": {
    "value": 9.2,
    "unit": "mw"
  },
  "compliant": false,
  "correlation_id": "curtailment-20251024-170000"
}

Webhook Integration Guide#

Step 1: Implement Webhook Receiver#

Create an HTTP endpoint that accepts POST requests from DPS. Your endpoint must:

  • Accept HTTP POST requests with JSON payload

  • Return 200 OK response for successful receipt

  • Parse and process the event payload (structure shown in the preceding example)

Minimal Example:

# Minimal webhook endpoint example (Flask)
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/nvgrid/webhook', methods=['POST'])
def receive_power_event():
    """Receive power event from DPS NvGrid"""
    event_data = request.get_json()

    # Extract key fields
    event_type = event_data.get('event')
    correlation_id = event_data.get('correlation_id')
    target_load = event_data.get('target_load', {})
    calculated_load = event_data.get('calculated_load', {})

    # Your processing logic here
    print(f"Received {event_type}: {target_load.get('value')} {target_load.get('unit')}")

    return jsonify({'status': 'success'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=8080)

Implementation is grid integrator’s responsibility. Process events according to your grid integration requirements.

Step 2: Register Webhook#

Subscribe to power events by registering the webhook URL.

Python Example#

Note: Complete Python setup (installation, CA cert, authentication) is documented in Managing Power Constraints - Python Client Setup.

#!/usr/bin/env python3
"""
Register webhook for NvGrid power events
"""
from dpsapi.v1 import nvgrid_pb2
from nvgrid_client import get_auth_token, create_nvgrid_client, create_auth_metadata

def register_webhook(stub, metadata, webhook_url, events=None):
    """Register webhook for power event notifications

    Args:
        stub: NvGrid client stub
        metadata: Auth metadata
        webhook_url: URL to receive webhooks
        events: List of event names to subscribe to (None = all)

    Returns:
        True if successful
    """
    request = nvgrid_pb2.RegisterWebhookRequest(url=webhook_url)

    # Map event names to proto enums
    event_map = {
        'start_ramp_up': nvgrid_pb2.RegisterWebhookRequest.POWER_EVENT_START_RAMP_UP,
        'end_ramp_up': nvgrid_pb2.RegisterWebhookRequest.POWER_EVENT_END_RAMP_UP,
        'start_ramp_down': nvgrid_pb2.RegisterWebhookRequest.POWER_EVENT_START_RAMP_DOWN,
        'end_ramp_down': nvgrid_pb2.RegisterWebhookRequest.POWER_EVENT_END_RAMP_DOWN,
    }

    if events:
        request.for_events.extend([event_map[e] for e in events])
        print(f"Subscribing to: {', '.join(events)}")
    else:
        print("Subscribing to all power events")

    response = stub.RegisterWebhook(request, metadata=metadata)

    if response.code == nvgrid_pb2.LoadTargetResponse.STATUS_CODE_SUCCESS:
        print(f"✅ Webhook registered: {webhook_url}")
        return True
    else:
        print(f"❌ Failed: {response.diag_msg}")
        return False

# Usage
token = get_auth_token('admin', 'password', host='api.dps')
channel, stub = create_nvgrid_client(token, host='api.dps')
metadata = create_auth_metadata(token)

# Register for all events
register_webhook(stub, metadata, 'http://grid-solution:8080/nvgrid/webhook')

# Or register for specific events
register_webhook(stub, metadata, 'http://grid-solution:8080/nvgrid/webhook',
                events=['start_ramp_down', 'end_ramp_down'])

channel.close()

Step 3: Process Webhook Events#

Your webhook receiver should process the JSON payload to extract relevant information for your grid integration needs. Key fields available in the payload:

  • event: Event type (start_ramp_down, end_ramp_down, start_ramp_up, end_ramp_up)

  • correlation_id: Tracking ID linking related events

  • target_load: Target power level (value, unit)

  • calculated_load: Actual power consumption (value, unit)

  • prev_target_load: Previous target before this change

  • compliant: Whether calculated load meets target (boolean)

  • start_time, end_time: Schedule times

  • strategy: Load targeting strategy (e.g., best_effort)

Process these fields according to your utility reporting and compliance requirements.


Step 4: Unregister Webhook#

Clean up webhook subscription when no longer needed.

Python Example#

Note: Refer to Managing Power Constraints - Python Client Setup for installation and authentication setup.

#!/usr/bin/env python3
"""
Unregister webhook from NvGrid
"""
from dpsapi.v1 import nvgrid_pb2
from nvgrid_client import get_auth_token, create_nvgrid_client, create_auth_metadata

def unregister_webhook(stub, metadata, webhook_url):
    """Unregister webhook

    Args:
        stub: NvGrid client stub
        metadata: Auth metadata
        webhook_url: URL to unregister

    Returns:
        True if successful
    """
    request = nvgrid_pb2.UnregisterWebhookRequest(url=webhook_url)
    response = stub.UnregisterWebhook(request, metadata=metadata)

    if response.code == nvgrid_pb2.LoadTargetResponse.STATUS_CODE_SUCCESS:
        print(f"✅ Webhook unregistered: {webhook_url}")
        return True
    else:
        print(f"❌ Failed: {response.diag_msg}")
        return False

# Usage
token = get_auth_token('admin', 'password', host='api.dps')
channel, stub = create_nvgrid_client(token, host='api.dps')
metadata = create_auth_metadata(token)

unregister_webhook(stub, metadata, 'http://grid-solution:8080/nvgrid/webhook')

channel.close()

Testing Webhooks#

You can test webhook delivery using curl:

# Send test webhook payload to your endpoint
curl -X POST http://localhost:8080/nvgrid/webhook \
  -H "Content-Type: application/json" \
  -d '{
    "event": "start_ramp_down",
    "start_time": "2025-10-24T17:00:00Z",
    "end_time": "2025-10-24T18:00:00Z",
    "strategy": "best_effort",
    "target_load": {"value": 6.5, "unit": "mw"},
    "prev_target_load": {"value": 10.0, "unit": "mw"},
    "calculated_load": {"value": 9.8, "unit": "mw"},
    "compliant": false,
    "correlation_id": "test-001"
  }'

This webhook integration enables real-time awareness of datacenter power changes, allowing grid solutions to track compliance and report status to utilities effectively.