Adding Device Support - delize/home-assistant-loggamera-integration GitHub Wiki
Adding Device Support (Developer Guide)
Technical guide for developers implementing support for new Loggamera devices.
🎯 When to Use This Guide
- You're implementing new device support
- Creating sensor mappings for unmapped devices
- Contributing device support to the integration
- Understanding the technical implementation process
For end users: See Device Help to request support instead.
🔍 Analysis Phase
Required Information from Users
When a user requests device support, gather:
-
Diagnostic output from these tools:
python tools/loggamera_diagnostic.py API_KEY --verbose python tools/organization_mapper.py API_KEY --format json python tools/validate_sensor_mappings.py
-
Device expectations - what sensors should be created
-
API response samples for the specific device
-
Device specifications if available
Extract Key Information
From diagnostic output, identify:
- Device Class from API (
PowerMeter
,CustomDevice
, etc.) - Available endpoints that respond for this device
- Sensor IDs from RawData endpoint responses
- Units and types (
UnitType
,ValueType
) - Clear names if provided by API
- Update frequency patterns
📊 API Response Analysis
Standard Endpoint Structure
{
"Data": {
"Values": [
{
"Name": "PowerInkW",
"Value": 2.5,
"UnitType": "kW",
"ValueType": "DECIMAL",
"ClearTextName": "Current Power"
}
],
"LogDateTimeUtc": "2025-01-19T10:30:00Z"
}
}
RawData Endpoint Structure
{
"Data": {
"Values": [
{
"Name": "544310",
"Value": 1234.5,
"UnitType": "kWh",
"ValueType": "DECIMAL",
"ClearTextName": "Total Energy"
}
]
}
}
Device Support Strategy
Scenario | Strategy | Implementation |
---|---|---|
Has dedicated endpoint | Standard mapping | Map endpoint response fields |
RawData only | RawData ID mapping | Map numeric sensor IDs |
Hybrid support | Combined mapping | Both standard + RawData |
No endpoint | Fallback only | Use GenericDevice/RawData |
🛠️ Implementation Steps
Step 1: Create Sensor Mappings
For Standard Endpoints
# Add to custom_components/loggamera/sensor.py
NEW_DEVICE_STANDARD_SENSORS = {
"ApiSensorName": {
"name": "internal_name",
"unit": "kWh",
"device_class": "energy",
"state_class": "total_increasing",
"clear_name": "User Display Name"
},
"AnotherSensor": {
"name": "another_sensor",
"unit": "°C",
"device_class": "temperature",
"state_class": "measurement",
"clear_name": "Temperature Sensor"
}
}
For RawData-Only Devices
# Add to sensor.py
NEW_DEVICE_RAWDATA_MAPPINGS = {
"544310": { # Numeric sensor ID
"name": "total_energy",
"unit": "kWh",
"device_class": "energy",
"state_class": "total_increasing",
"clear_name": "Total Energy"
},
"544311": {
"name": "flow_rate",
"unit": "m³/h",
"device_class": "volume_flow_rate",
"state_class": "measurement",
"clear_name": "Flow Rate"
}
}
Step 2: Add Device Recognition
Update Endpoint Selection
# In _get_primary_endpoint_for_device() method
def _get_primary_endpoint_for_device(self, device_id, device_type):
if device_type == "NewDeviceType":
primary_endpoint = API_ENDPOINT_NEW_DEVICE
elif device_type == "RawDataOnlyDevice":
# No dedicated endpoint - skip to fallbacks
primary_endpoint = None
# ... existing logic
Add to Sensor Creation
# Update sensor creation logic
def create_standard_sensors(self, device_data, device_id, device_name, device_type):
if device_type == "NewDeviceType":
mappings = NEW_DEVICE_STANDARD_SENSORS
# Create sensors using mappings
def create_rawdata_sensors(self, rawdata, device_id, device_name, device_type):
if device_type == "RawDataOnlyDevice":
mappings = NEW_DEVICE_RAWDATA_MAPPINGS
# Create sensors using mappings
Step 3: Handle Home Assistant Integration
Device Classes
DEVICE_CLASS_MAPPING = {
# Energy and Power
"energy": "energy", # kWh, Wh
"power": "power", # W, kW
"voltage": "voltage", # V
"current": "current", # A
# Environmental
"temperature": "temperature", # °C
"humidity": "humidity", # %
"pressure": "pressure", # Pa, bar
# Flow and Volume
"water": "water", # L, m³
"volume_flow_rate": "volume_flow_rate", # L/min, m³/h
# Other
"battery": "battery", # %
"signal_strength": "signal_strength" # dBm
}
State Classes
STATE_CLASS_MAPPING = {
"measurement": "measurement", # Instantaneous values
"total_increasing": "total_increasing", # Cumulative totals
"total": "total" # Totals that can decrease
}
Step 4: Error Handling
API Quirks
def fix_api_issues(clear_name, sensor_name):
"""Handle known API spelling/naming issues."""
corrections = {
"Voltate": "Voltage",
"Signal-Noice": "Signal-Noise",
# Add device-specific fixes
}
for wrong, correct in corrections.items():
clear_name = clear_name.replace(wrong, correct)
return clear_name
Missing Endpoints
def handle_missing_endpoint(device_type):
"""Handle devices without dedicated endpoints."""
no_endpoint_devices = ["HeatMeter", "ChargingStation"]
if device_type in no_endpoint_devices:
return None # Skip to fallbacks
return get_standard_endpoint(device_type)
🧪 Testing Implementation
Development Testing
Validate Mappings
# Test sensor coverage
python tools/validate_sensor_mappings.py
# Check device discovery
python tools/organization_mapper.py API_KEY --format json
# Test specific endpoints
python tools/loggamera_api_explorer.py API_KEY RawData --device-id DEVICE_ID
Integration Testing
# Full diagnostic
python tools/loggamera_diagnostic.py API_KEY --verbose
# Device-specific testing
python tools/comprehensive_sensor_discovery.py
User Testing Process
- Create development version with new support
- User installs and tests functionality
- User reports sensor accuracy and issues
- Iterate based on feedback
- Validate all sensors work correctly
Testing Checklist
- Device appears in Home Assistant
- All expected sensors created
- Sensor names are user-friendly
- Units and device classes correct
- Values update properly
- No "Unknown" sensors remain
- Integration with dashboards works
📝 Implementation Examples
Standard Device Example
# PowerMeter-style device with dedicated endpoint
SOLAR_INVERTER_STANDARD_SENSORS = {
"CurrentPowerOutput": {
"name": "current_power_output",
"unit": "kW",
"device_class": "power",
"state_class": "measurement",
"clear_name": "Current Power Output"
},
"TotalEnergyProduced": {
"name": "total_energy_produced",
"unit": "kWh",
"device_class": "energy",
"state_class": "total_increasing",
"clear_name": "Total Energy Produced"
}
}
RawData-Only Example
# HeatMeter-style device using only RawData
SMART_THERMOSTAT_RAWDATA_MAPPINGS = {
"545001": {
"name": "current_temperature",
"unit": "°C",
"device_class": "temperature",
"state_class": "measurement",
"clear_name": "Current Temperature"
},
"545002": {
"name": "target_temperature",
"unit": "°C",
"device_class": "temperature",
"state_class": "measurement",
"clear_name": "Target Temperature"
},
"545003": {
"name": "heating_active",
"unit": "",
"device_class": None,
"state_class": "measurement",
"clear_name": "Heating Active"
}
}
Complex Device Example
# Device using multiple endpoints
def create_complex_device_sensors(self, device_id, device_type):
sensors = []
# Standard endpoint sensors
standard_data = self.get_device_data(device_id, device_type)
sensors.extend(self.create_standard_sensors(standard_data))
# RawData detailed sensors
rawdata = self.get_raw_data(device_id)
sensors.extend(self.create_rawdata_sensors(rawdata))
# Custom processing for unique capabilities
if device_type == "ComplexDevice":
sensors.extend(self.create_special_sensors(device_id))
return sensors
📚 Documentation Updates
Update Device Support Guide
# Add to Supported-Devices.md
| **NewDevice** | ✅ Full | X sensors | Y sensors | ✅ Yes | Description |
Document Sensors
## NewDevice (Purpose)
**Integration**: Home Assistant compatibility notes
### Standard Sensors (Always Enabled)
| Sensor | Unit | Device Class | Purpose |
|--------|------|--------------|---------|
| **Sensor Name** | unit | device_class | Description |
### RawData Sensors (Enable Manually)
| Sensor | Unit | Device Class | Description |
Code Documentation
# Add clear comments explaining mapping decisions
NEW_DEVICE_MAPPINGS = {
# Energy sensor - maps to HA energy dashboard
"energy_sensor_id": {
"device_class": "energy", # Required for energy dashboard
"state_class": "total_increasing" # Cumulative energy
}
}
🔄 Quality Assurance
Code Review Checklist
- Follows existing code patterns
- Proper Home Assistant device classes
- Consistent naming conventions
- Error handling for edge cases
- Documentation updates included
- Diagnostic tools validate correctly
User Acceptance
- User confirms all expected sensors appear
- Sensor names are intuitive
- Values are accurate and update properly
- Integration with HA features works
- No regressions in existing functionality
🤝 Collaboration Guidelines
Working with Users
- Request specific diagnostic output
- Clarify expectations for sensor functionality
- Provide clear testing instructions
- Follow up to ensure satisfaction
- Document lessons learned for future devices
Contributing Changes
- Fork repository and create feature branch
- Implement device support following these patterns
- Test thoroughly with diagnostic tools
- Update documentation comprehensively
- Submit pull request with detailed description
This guide provides the technical foundation for robust device support implementation. Always coordinate with users requesting support to ensure the implementation meets their needs.
Related Guides:
- Device Help - For directing users to request support
- Supported Devices - Current device support reference
- Sensor Mappings and Architecture - Deep technical details