This document describes how we tested and validated the PGE API connection before receiving live data.
You need a registered PGE Share My Data account with:
| Credential | Description |
|---|---|
| Third Party ID | Your registration ID (e.g., 52144) |
| Client ID | OAuth client identifier |
| Client Secret | OAuth client secret |
| SSL Certificate | .crt and .key files for mTLS |
cd /path/to/PG-E-Data-Visualizer
source venv/bin/activate
pip install pgesmd-self-access pandasCreate auth/auth.json:
{
"third_party_id": "52144",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"cert_crt_path": "/path/to/certificate.crt",
"cert_key_path": "/path/to/private.key"
}from pgesmd_self_access.api import SelfAccessApi
print("Import successful")Common issues:
- Wrong import path: Use
pgesmd_self_access.api, notpgesmd_self_access - Class name:
SelfAccessApi(lowercase 'a' in 'Api')
from pgesmd_self_access.api import SelfAccessApi
auth_file = "auth/auth.json"
api = SelfAccessApi.auth(auth_file)
token = api.get_token()
print(f"Token: {token[:30]}...")Expected: A token string like a6db9ef7-a84c-4cad-990a-...
Common errors:
400: Invalid Certificate→ Certificate path wrong or cert doesn't match registrationMissing self.cert, RI violated→ Certificate paths not set in auth.json
status = api.get_service_status()
print(f"Service online: {status}")Expected: True
PGE requires completing a test before activating your registration:
from pgesmd_self_access.api import PgeRegister
# Create auth/auth.json first
reg = PgeRegister()
# This runs the full test sequence
result = reg.complete_testing()
print(f"Testing complete: {result}")This will:
- Get a test token
- Check service status
- Request sample data
- Verify everything works
from pgesmd_self_access.api import SelfAccessApi
api = SelfAccessApi.auth("auth/auth.json")
api.get_token()
# Request last 7 days of data
result = api.request_historical_data(days=7)
print(f"Request accepted: {result}")Expected: True with log message:
request successful, awaiting POST from server.
HTTP Response Codes:
202 Accepted→ Success! PGE will send data to your notification URI400 Bad Request→ Credentials or third_party_id mismatch401 Unauthorized→ Token expired or invalid403 Forbidden→ Certificate issue
#!/usr/bin/env python3
"""Test PGE API Connection"""
from pgesmd_self_access.api import SelfAccessApi
AUTH_FILE = "auth/auth.json"
def test_pge_api():
print("=" * 60)
print("PGE API Connection Test")
print("=" * 60)
# Initialize
print("\n1. Initializing API...")
api = SelfAccessApi.auth(AUTH_FILE)
print(" OK")
# Get token
print("\n2. Getting access token...")
token = api.get_token()
print(f" Token: {token[:30]}...")
# Check service
print("\n3. Checking service status...")
status = api.get_service_status()
print(f" Service online: {status}")
if not status:
print(" ERROR: Service offline")
return False
# Request data
print("\n4. Requesting historical data (7 days)...")
result = api.request_historical_data(days=7)
print(f" Request accepted: {result}")
if result:
print("\n" + "=" * 60)
print("SUCCESS! Data will be sent to your notification URI.")
print("Check Supabase pge_data table in ~60 seconds.")
print("=" * 60)
return result
if __name__ == "__main__":
test_pge_api()Save as scripts/automation/test_pge_api.py and run:
source venv/bin/activate
python scripts/automation/test_pge_api.py| Method | Description | Returns |
|---|---|---|
get_token() |
Get OAuth access token | Token string |
need_token() |
Check if token expired | Boolean |
get_service_status() |
Check if PGE API is online | Boolean |
request_latest_data() |
Request most recent data | Boolean |
request_historical_data(days=N) |
Request last N days | Boolean |
request_date_data(date) |
Request specific date | Boolean |
All request_* methods are async - they trigger PGE to send data to your notification URI.
PGE's API does NOT return data directly. Instead:
You PGE Your Server
| | |
|-- request_historical_data | |
| | |
|<-------- 202 Accepted ----| |
| | |
| |-- (processes request) -------|
| | |
| |-- POST ESPI XML data ------->|
| | |
| | (store data)
This is why we need Supabase - to receive and store the callback.
pip install pgesmd-self-access- Check certificate paths in auth.json are absolute paths
- Verify certificate matches what you registered with PGE
- Check certificate hasn't expired:
openssl x509 -in certificate.crt -noout -dates
- Verify
third_party_idin auth.json matches PGE registration - Check
client_idandclient_secretare correct - Ensure you've completed the API testing phase with PGE
- Check your notification URI is correct in PGE registration
- Verify Supabase Edge Function is deployed and working
- Check Edge Function logs for errors
- PGE may take 1-2 minutes to send data
Our certificate:
- CN: sumedhsankhe.github.io
- Expires: March 28, 2026
Check certificate:
openssl x509 -in /path/to/certificate.crt -noout -subject -dates| Field | Value |
|---|---|
| Third Party ID | 52144 |
| User Type | Self Access |
| Commodity Type | Gas, Electric |
| Data Elements | Basic, Billing, Account, Usage |
| Historical Data | 24 months |
| Notification URI | https://dhwdtuuppvlbzjccotdk.supabase.co/functions/v1/pge-notify |
Last updated: January 2026