Skip to main content

End-User Dashboard Integration

For end-users to understand the current status of software-based optimization, they must have access to a range of information about their account, devices, and optimization performance. The endpoints detailed below are used in the Whitelabel end-user dashboard Podero provides and can be used by Partners to build a comparable end-user experience.

Dashboard Overview Data

List All Devices

Retrieve all devices for a user to display on the dashboard:
curl -X GET \
  'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}/heat-pumps' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {auth_token}'
Returns a list of all heat pumps with complete data for each unit.

Example Response

[
  {
    "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
    "created_at": "2019-08-24T14:15:22Z",
    "updated_at": "2019-08-24T14:15:22Z",
    "building": "94964bf8-4ec9-4f3f-b10e-0fe21980279e",
    "is_authenticated": true,
    "is_smart_optimization_active": true,
    "device_model": {
      "manufacturer": "Nibe",
      "model": "S-Series"
    },
    "operational_mode": "heating",
    "current_power_consumption_w": 2500,
    "indoor_actual_temperature": 21.5,
    "outdoor_temperature": 5.3,
    "consumption_last_day_kwh": 45.3,
    "consumption_last_week_kwh": 287.6,
    "consumption_last_month_kwh": 1204.8
  }
]

Key Dashboard Metrics

Device Status Indicators

Field: is_authenticatedShows if the device is successfully connected to the manufacturer’s API.
def get_connection_status(device):
    return "Connected" if device['is_authenticated'] else "Disconnected"
Field: is_smart_optimization_activeIndicates whether Podero’s optimization algorithm is actively controlling the device.
def get_optimization_status(device):
    if not device['is_authenticated']:
        return "Not Available"
    return "Active" if device['is_smart_optimization_active'] else "Paused"
Field: operational_modeCurrent mode of operation (heating, cooling, standby, etc.).
mode_icons = {
    'heating': '🔥',
    'cooling': '❄️',
    'standby': '⏸️',
    'auto': '🔄'
}

Current Readings

Display real-time or near-real-time data:
def format_heat_pump_readings(device):
    return {
        'indoor_temp': f"{device['indoor_actual_temperature']}°C",
        'outdoor_temp': f"{device['outdoor_temperature']}°C",
        'current_power': f"{device['current_power_consumption_w']}W",
        'dhw_temp': f"{device['dhw_temperature']}°C"
    }

Consumption History

Show energy consumption over different time periods:
def format_consumption_data(device):
    return {
        'today': device['consumption_last_day_kwh'],
        'this_week': device['consumption_last_week_kwh'],
        'this_month': device['consumption_last_month_kwh'],
        'last_updated': device['consumption_last_updated_at']
    }

Single Device View

Get Specific Device Details

Retrieve detailed information for a single device:
curl -X GET \
  'https://app.podero.com/api/partners/v2.0/org/{org_id}/users/{user_id}/heat-pumps/{device_id}' \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer {auth_token}'

Dashboard UI Components

Status Card Example

function DeviceStatusCard({ device }) {
  return (
    <Card>
      <h3>{device.device_model.manufacturer} {device.device_model.model}</h3>

      <StatusIndicator
        connected={device.is_authenticated}
        optimizing={device.is_smart_optimization_active}
      />

      <MetricsGrid>
        <Metric
          label="Indoor Temp"
          value={`${device.indoor_actual_temperature}°C`}
        />
        <Metric
          label="Current Power"
          value={`${device.current_power_consumption_w}W`}
        />
        <Metric
          label="Today's Consumption"
          value={`${device.consumption_last_day_kwh} kWh`}
        />
      </MetricsGrid>
    </Card>
  );
}

Consumption Chart Example

import matplotlib.pyplot as plt

def create_consumption_chart(device):
    periods = ['Today', 'This Week', 'This Month']
    consumption = [
        device['consumption_last_day_kwh'],
        device['consumption_last_week_kwh'],
        device['consumption_last_month_kwh']
    ]

    plt.bar(periods, consumption)
    plt.ylabel('Energy Consumption (kWh)')
    plt.title('Device Consumption Overview')
    return plt

Real-Time Updates

State data refresh frequency depends on the manufacturer’s API limitations. Some values may update every 5-15 minutes.

Polling Strategy

Implement efficient polling for dashboard updates:
import time

def poll_device_status(device_id, interval=300):  # 5 minutes
    """
    Poll device status at regular intervals
    """
    while True:
        try:
            device = get_device_data(device_id)
            update_dashboard(device)

            # Check last update timestamp
            last_updated = device['current_state_last_updated_at']
            print(f"Last updated: {last_updated}")

        except Exception as e:
            print(f"Error polling device: {e}")

        time.sleep(interval)

Websocket Alternative

For real-time updates, consider implementing websockets on your backend to push updates to the dashboard when device state changes.

Building-Level Aggregation

Total Consumption by Building

Aggregate consumption across all devices in a building:
def get_building_consumption(user_id, building_id):
    """
    Calculate total building consumption
    """
    # Get all devices in building
    heat_pumps = get_heat_pumps(user_id)
    evs = get_electric_vehicles(user_id)

    # Filter by building
    building_devices = [
        d for d in (heat_pumps + evs)
        if d.get('building') == building_id
    ]

    # Sum consumption
    total_day = sum(d['consumption_last_day_kwh'] for d in building_devices)
    total_week = sum(d['consumption_last_week_kwh'] for d in building_devices)
    total_month = sum(d['consumption_last_month_kwh'] for d in building_devices)

    return {
        'day': total_day,
        'week': total_week,
        'month': total_month
    }

Savings Calculation

Display Optimization Savings

Calculate and display estimated savings from optimization:
def calculate_savings(device, energy_price_kwh=0.30):
    """
    Calculate estimated savings based on optimized consumption

    Note: This is a simplified example. Actual savings calculation
    should use historical data and baseline consumption.
    """
    # Estimated savings percentage with optimization
    savings_percentage = 0.15  # 15% typical savings

    consumption = device['consumption_last_month_kwh']
    optimized_cost = consumption * energy_price_kwh
    baseline_cost = consumption / (1 - savings_percentage) * energy_price_kwh

    savings = baseline_cost - optimized_cost

    return {
        'monthly_savings': round(savings, 2),
        'annual_projected': round(savings * 12, 2),
        'savings_percentage': savings_percentage * 100
    }

Error Handling

Display Connection Issues

def check_device_health(device):
    """
    Check device health and return user-friendly messages
    """
    if not device['is_authenticated']:
        return {
            'status': 'error',
            'message': 'Device disconnected. Please reconnect in settings.',
            'action': 'reconnect'
        }

    if device.get('authorization_url'):
        return {
            'status': 'warning',
            'message': 'Device requires re-authentication.',
            'action': 'reauthorize',
            'url': device['authorization_url']
        }

    # Check if data is stale
    last_update = datetime.fromisoformat(device['current_state_last_updated_at'])
    if (datetime.now() - last_update).total_seconds() > 3600:  # 1 hour
        return {
            'status': 'warning',
            'message': 'Device data may be outdated.',
            'last_update': last_update
        }

    return {'status': 'ok'}

Best Practices

  • Cache device data to reduce API calls
  • Implement efficient polling intervals (5-15 minutes)
  • Use pagination for users with many devices
  • Load critical data first, defer detailed metrics
  • Show loading states during data fetches
  • Display last update timestamps
  • Provide clear error messages with actions
  • Use visual indicators for status (colors, icons)
  • Round consumption values appropriately
  • Use consistent units throughout
  • Show trends with charts and graphs
  • Highlight important changes or alerts

Next Steps