API Issues and Workarounds - delize/home-assistant-loggamera-integration GitHub Wiki

API Issues and Workarounds

API Version: Loggamera Platform API v2
Last Updated: 2025-01-18
Integration Version: 0.7.3+

This document catalogs known issues, inconsistencies, and undocumented behaviors in the Loggamera Platform API v2, along with the workarounds implemented in the Home Assistant integration.

📋 Quick Reference

Issue Category Impact Workaround Status
Spelling Errors Display names ✅ Fixed in integration
Missing Endpoints HeatMeter support ✅ Fallback implemented
Response Format Error handling ✅ Normalized in integration
Authentication Non-standard auth ✅ Implemented correctly
Endpoint Availability Device support ✅ Fallback mechanisms
Data Types Type conversion ✅ Auto-conversion
SSL/TLS Issues Connectivity ✅ Certificate management
Update Frequency Data freshness ⚠️ Documented limitation
Data Pull Issues Missing/empty data 🔍 Under investigation
Organization Access Complex hierarchy ✅ State management
Error Handling Inconsistent errors ✅ Error normalization

🔤 Spelling and Naming Errors

"Voltate" Instead of "Voltage"

Issue: API consistently returns misspelled "Voltate" in sensor names.

Affected: ChargingStation devices via RawData endpoint Sensor IDs: 544426, 544427, 544428

API Response:

{
  "ClearTextName": "Voltate (Phase 1)",
  "Name": "544426"
}

Expected: "Voltage (Phase 1)"

✅ Integration Fix: Automatic spelling correction in sensor display names

# Sensor name correction in sensor.py
if "Voltate" in clear_name:
    clear_name = clear_name.replace("Voltate", "Voltage")

"Signal-Noice" Instead of "Signal-Noise"

Issue: API returns "Signal-Noice relation (Snr)" instead of proper "Signal-Noise ratio (SNR)".

Affected: RoomSensor devices via RawData endpoint Sensor ID: 543837

✅ Integration Fix: Terminology correction for technical accuracy

if "Signal-Noice" in clear_name:
    clear_name = clear_name.replace("Signal-Noice", "Signal-Noise")

🚫 Missing API Endpoints

HeatMeter Endpoint Does Not Exist

Issue: Despite HeatMeter being a supported device type, there is no dedicated /HeatMeter endpoint.

Expected: POST /api/v2/HeatMeter endpoint (similar to PowerMeter, WaterMeter) Actual: Returns "invalid endpoint" error

Impact: HeatMeter devices cannot use optimized device-specific endpoints

✅ Integration Solution:

  • Primary: Use /RawData endpoint for all HeatMeter data
  • Fallback: Use /GenericDevice for alarm information
  • Special mapping: Dedicated sensor mappings for HeatMeter RawData IDs (544310-544324)
# HeatMeter handling in api.py
if device_type == "HeatMeter":
    # HeatMeter has no dedicated endpoint - use RawData directly
    primary_endpoint = None

📊 Response Format Inconsistencies

Empty Response Bodies

Issue: Some endpoints return HTTP 200 with completely empty response bodies instead of proper JSON error responses.

Affected: Various device-specific endpoints when device type is unsupported

Expected: JSON error response or HTTP error status Actual: Empty string response body

✅ Integration Fix: Pre-parse empty response detection

# Handle endpoints that return no response body
if not response.text.strip():
    result = {"Data": None, "Error": None}
else:
    result = response.json()

Inconsistent Error Message Structure

Issue: Error messages returned in different formats across endpoints.

Format 1 (Most endpoints):

{
  "Error": "error message string"
}

Format 2 (Some endpoints):

{
  "Error": {
    "Message": "error message string"
  }
}

✅ Integration Fix: Unified error parsing

# Handle both error format types
if "Error" in result and result["Error"] is not None:
    if isinstance(result["Error"], dict) and "Message" in result["Error"]:
        error_message = result["Error"]["Message"]
    else:
        error_message = str(result["Error"])

Null ValueType Fields

Issue: ValueType field is often null in RawData responses rather than meaningful values.

Impact: Cannot determine sensor data type directly from API metadata

✅ Integration Fix: Intelligent type inference

# Infer sensor types from UnitType and Value content
def _infer_sensor_type(self, value_data):
    unit_type = value_data.get("UnitType", "").lower()
    if unit_type in ["°c", "celsius"]:
        return "temperature"
    elif unit_type in ["%", "percent"]:
        return "humidity" if "humidity" in name.lower() else "generic"
    # ... additional inference logic

🔐 Authentication Issues

API Key in Request Body (Non-Standard)

Issue: API requires API key in JSON request body rather than standard HTTP Authorization header.

Standard Practice: Authorization: Bearer <api_key> header Loggamera API: "ApiKey": "<api_key>" in request body

✅ Integration Implementation: Correct non-standard authentication

# Always include the API key in request body
if "ApiKey" not in data:
    data["ApiKey"] = self.api_key

🌐 Endpoint Availability Problems

Inconsistent Endpoint Support by Device Type

Issue: Not all endpoints work with all device types, but this is undocumented.

Examples:

  • PowerMeter devices: PowerMeter endpoint works
  • HeatMeter devices: No dedicated endpoint, must use RawData
  • Some devices: Capabilities endpoint not available

✅ Integration Solution: Endpoint cascading with caching

# Intelligent endpoint fallback system
def _get_primary_endpoint_for_device(self, device_id, device_type):
    # 1. Try device-specific endpoint
    if primary_endpoint and not self._endpoint_cache.get(primary_endpoint, False):
        try:
            return self._make_request(primary_endpoint, {"DeviceId": device_id})
        except LoggameraAPIError:
            self._endpoint_cache[primary_endpoint] = False
    
    # 2. Fallback to generic endpoints
    for endpoint in [API_ENDPOINT_RAW_DATA, API_ENDPOINT_GENERIC_DEVICE]:
        # Try each fallback endpoint...

"Invalid Endpoint" vs "Access Denied" Confusion

Issue: API returns "invalid endpoint" for both unsupported endpoints and permission issues.

Impact: Cannot distinguish between true unavailability and permissions

✅ Integration Solution: Endpoint availability caching

# Cache invalid endpoints to avoid repeated failures
if error_message == "invalid endpoint":
    self._endpoint_cache[endpoint] = False
    raise LoggameraAPIError(f"API error: {error_message}")

🔧 Data Type and Value Inconsistencies

Inconsistent Unit Case Sensitivity

Issue: API returns both lowercase and uppercase variants for the same unit type.

Examples:

  • "ConsumedTotalInm3" (lowercase m3)
  • "ConsumedTotalInM3" (uppercase M3)

✅ Integration Fix: Case-insensitive unit mapping

# Handle both case variants
if any(unit in sensor_name.lower() for unit in ["inkwh", "kwh"]):
    return "energy"
elif any(unit in sensor_name.lower() for unit in ["inm3", "m3", "m³"]):
    return "water"

String vs Numeric Value Types

Issue: Numeric values sometimes returned as strings, sometimes as numbers.

✅ Integration Fix: Automatic type conversion

def _convert_value(self, value):
    """Convert string numbers to appropriate numeric types."""
    if isinstance(value, str):
        try:
            if '.' in value:
                return float(value)
            else:
                return int(value)
        except ValueError:
            return value
    return value

🔒 SSL/TLS Certificate Issues

Certificate Verification Failures

Issue: SSL certificate verification frequently fails in various environments, especially Docker.

Common Errors:

  • CERTIFICATE_VERIFY_FAILED
  • WRONG_VERSION_NUMBER
  • Missing CA certificates

✅ Integration Solution: Explicit certificate management

# Explicit certificate path using certifi
self.session.verify = certifi.where()

Additional Tools: tools/diagnose_tls.sh for automatic certificate diagnosis and fixes

⏱️ Update Frequency Limitations

PowerMeter Data Update Intervals

Issue: PowerMeter endpoint data only updates approximately every 30 minutes regardless of polling frequency.

Impact: More frequent polling doesn't yield more current data

⚠️ Documented Limitation: This is an API behavior, not an integration issue

Integration Response:

  • Default scan interval set to 20 minutes (1200 seconds)
  • Documentation explains the limitation
  • Monitoring tools available to analyze actual update patterns
# Default optimized for PowerMeter update frequency
DEFAULT_SCAN_INTERVAL = 1200  # 20 minutes

📊 Data Pull Inconsistencies

Intermittent Missing or Empty Data

Issue: Periodic instances where API endpoints return no data or empty responses despite devices being active and accessible.

Symptoms:

  • API returns empty "Data" arrays when data should be present
  • Intermittent data gaps in otherwise functional device feeds
  • Affects different environments inconsistently (e.g., test vs production)
  • Timing patterns suggest potential server-side processing issues

Observed Patterns:

  • Time-based: Often occurs during specific time windows (e.g., 4 AM processing cycles)
  • Environment-specific: May affect test environments while production remains stable
  • Device-agnostic: Can affect multiple device types simultaneously
  • Temporary: Usually resolves within normal update cycles (15-30 minutes)

Example Scenarios:

  • Organization endpoint returns empty device lists when devices exist
  • Device endpoints return {"Data": {"Values": []}} despite recent activity
  • RawData endpoints intermittently unavailable for active devices

🔍 Current Investigation Status:

  • Root cause analysis: Ongoing investigation into API backend processing patterns
  • Monitoring implementation: Adding timestamp logging to identify specific failure windows
  • Environment correlation: Comparing test vs production environment behaviors
  • Retry strategy evaluation: Assessing optimal retry intervals for these scenarios

⚠️ Temporary Workarounds:

  • Retry logic with exponential backoff already implemented
  • Circuit breaker prevents excessive retry attempts
  • Integration gracefully handles empty responses without crashing
  • Error logging captures instances for pattern analysis

Integration Response:

# Enhanced logging for data pull issue analysis
if not data_values or len(data_values) == 0:
    self._logger.warning(
        "Empty data response for device %s at %s - investigating timing patterns",
        device_id, 
        datetime.now().isoformat()
    )

📈 Investigation Areas:

  1. API Server Processing: Backend data aggregation timing and caching
  2. Load Balancing: Request routing consistency across API instances
  3. Database Sync: Data consistency between API backend databases
  4. Time Zone Handling: UTC vs local time processing in API responses
  5. Caching Layers: API response caching invalidation patterns

Next Steps:

  • Continued monitoring and data collection
    • Have added extensive data logging for this issue
  • Correlation analysis with API vendor
  • Enhanced diagnostic tools for real-time detection
  • Potential API polling strategy adjustments based on findings

🏢 Organization Access Patterns

Complex Child Organization Access

Issue: Accessing devices in child organizations requires temporarily switching organization context.

Required Process:

  1. Store original organization ID
  2. Switch to child organization ID
  3. Make device request
  4. Restore original organization ID

✅ Integration Solution: Careful state management

# Temporary organization context switching
original_org_id = self.api.organization_id
try:
    self.api.organization_id = child_org_id
    child_devices = await self.hass.async_add_executor_job(self.api.get_devices)
    # Process child organization devices
finally:
    self.api.organization_id = original_org_id

⚠️ Error Handling Inconsistencies

Capabilities Endpoint Error Behavior

Issue: Capabilities endpoint may not be available for all devices but returns "invalid endpoint" instead of empty capabilities.

Expected: Empty capabilities response Actual: "invalid endpoint" error

✅ Integration Solution: Graceful degradation

try:
    return self._make_request(API_ENDPOINT_CAPABILITIES, {"DeviceId": device_id})
except LoggameraAPIError as e:
    if "invalid endpoint" in str(e):
        return {
            "Data": {"ReadCapabilities": [], "WriteCapabilities": []},
            "Error": None,
        }
    else:
        raise

Scenarios Endpoint Availability

Issue: Scenarios endpoint may not be available for all organizations.

Expected: Empty scenarios list when none exist Actual: "invalid endpoint" error for organizations without scenario support

✅ Integration Solution: Empty list fallback

try:
    return self._make_request(API_ENDPOINT_SCENARIOS, {"OrganizationId": self.organization_id})
except LoggameraAPIError as e:
    if "invalid endpoint" in str(e):
        return {"Data": {"Scenarios": []}, "Error": None}
    else:
        raise

🛠️ Integration Workarounds Summary

The Home Assistant integration implements comprehensive workarounds for these API issues:

Fallback Mechanisms

  • Endpoint cascading: Try primary → RawData → GenericDevice
  • Endpoint caching: Remember invalid endpoints to avoid repeated failures
  • Error normalization: Handle multiple error response formats
  • Graceful degradation: Return empty responses instead of errors when appropriate

Data Normalization

  • Spelling correction: Fix API typos in display names
  • Type conversion: Convert string numbers to appropriate numeric types
  • Unit standardization: Handle case variations in unit names
  • Value sanitization: Clean and validate sensor values

Reliability Improvements

  • SSL handling: Explicit certificate management with diagnostic tools
  • Timeout handling: Reasonable timeouts with exponential backoff retry logic
  • State management: Careful organization context switching
  • Circuit breaker: Prevent repeated calls to failing endpoints

Retry Logic and Fault Tolerance

  • Exponential backoff: 15s → 30s → 60s retry delays
  • Circuit breaker: Opens after 6 failures, 5-minute timeout
  • Error classification: Different retry strategies for different error types
  • Network resilience: Handle connectivity and timeout issues

📈 Recommendations for API Improvements

  1. Standardize Error Responses: Use consistent error message format across all endpoints
  2. Fix Spelling Errors: Correct "Voltate" → "Voltage" and "Signal-Noice" → "Signal-Noise"
  3. Add HeatMeter Endpoint: Implement dedicated /HeatMeter endpoint
  4. Document Endpoint Support: Clearly specify which endpoints work with which device types
  5. Improve Authentication: Support standard Authorization headers
  6. Consistent Data Types: Return numeric values as numbers, not strings
  7. Update Frequency Documentation: Document actual update intervals for each endpoint
  8. Graceful Degradation: Return empty arrays instead of "invalid endpoint" errors
  9. SSL Certificate Improvements: Ensure certificate chain compatibility across environments
  10. Organization Hierarchy: Support accessing child organization devices in single requests

🔍 Testing and Validation

The integration includes comprehensive diagnostic tools to test these workarounds:


Note: This documentation reflects integration development experience and testing. API behavior may change in future versions. Always consult official Loggamera API documentation for authoritative information.

⚠️ **GitHub.com Fallback** ⚠️