This document provides guidance for developers working on the RoboVac integration.
custom_components/robovac/
├── __init__.py # Integration initialization
├── config_flow.py # Configuration flow for setup
├── robovac.py # Core RoboVac class with command logic
├── vacuum.py # Home Assistant vacuum entity
├── sensor.py # Sensor entities
├── tuyalocalapi.py # Tuya device communication
├── tuyalocaldiscovery.py # Device discovery
├── vacuums/
│ ├── base.py # Base classes and enums
│ ├── T2250.py through T2262.py # Model-specific command mappings
│ └── ... (other models)
└── strings.json # Localization strings
tests/
├── test_vacuum/
│ ├── test_t2251_command_mappings.py # Model-specific tests
│ ├── test_get_robovac_human_readable_value.py
│ ├── test_get_robovac_command_value.py
│ └── ... (other tests)
└── conftest.py # Pytest configuration and fixtures
Each vacuum model defines command mappings in vacuums/T*.py files. These mappings translate between:
- Device codes: Numeric DPS codes used by the Tuya protocol
- Command names: Enum values like
RobovacCommand.MODE,RobovacCommand.FAN_SPEED - Command values: User-friendly strings like
"auto","turbo","Standard"
Example structure:
RobovacCommand.MODE: {
"code": 5, # DPS code for this command
"values": {
"auto": "Auto", # Key: input value, Value: output value
"small_room": "SmallRoom",
"spot": "Spot",
},
},- Keys (input values): Lowercase snake_case (e.g.,
"auto","small_room") - Values (output values): PascalCase (e.g.,
"Auto","SmallRoom") - Case-insensitive matching: Device responses are matched case-insensitively
Device responses are matched case-insensitively, so "AUTO", "auto", and "Auto" all map to the same value. This eliminates the need for duplicate bidirectional mappings and simplifies the command mapping definitions.
- Clone the repository
- Install dependencies:
pip install -r requirements.txt - Install development dependencies:
pip install -r requirements-dev.txt - Run tests to verify setup:
task test
# Run all tests
task test
# Run specific test file
pytest tests/test_vacuum/test_t2251_command_mappings.py -v
# Run with coverage
task test # Already includes coverage report
# Run tests matching a pattern
pytest tests/test_vacuum/ -k "mode" -v# Check code style and formatting
task lint
# Verify type hints
task type-check
# Both lint and type-check
task lint && task type-check# Check markdown formatting
task markdownlint
# Fix markdown issues
task markdownlint --fixCreate custom_components/robovac/vacuums/TXXX.py:
"""Model name (TXXX)"""
from homeassistant.components.vacuum import VacuumEntityFeature
from .base import RoboVacEntityFeature, RobovacCommand, RobovacModelDetails
class TXXX(RobovacModelDetails):
homeassistant_features = (
VacuumEntityFeature.BATTERY
| VacuumEntityFeature.START
| VacuumEntityFeature.STOP
| VacuumEntityFeature.PAUSE
| VacuumEntityFeature.RETURN_HOME
| VacuumEntityFeature.FAN_SPEED
| VacuumEntityFeature.LOCATE
)
robovac_features = (
RoboVacEntityFeature.CLEANING_TIME
| RoboVacEntityFeature.CLEANING_AREA
)
commands = {
RobovacCommand.START_PAUSE: {
"code": 2,
},
RobovacCommand.MODE: {
"code": 5,
"values": {
"auto": "Auto",
"small_room": "SmallRoom",
},
},
# ... other commands
}Add to custom_components/robovac/vacuums/__init__.py:
from .TXXX import TXXX
ROBOVAC_MODELS = {
# ... existing models
"TXXX": TXXX,
}Create tests/test_vacuum/test_txxx_command_mappings.py:
"""Tests for TXXX command mappings."""
import pytest
from unittest.mock import patch
from custom_components.robovac.robovac import RoboVac
from custom_components.robovac.vacuums.base import RobovacCommand
@pytest.fixture
def mock_txxx_robovac():
"""Create a mock TXXX RoboVac instance for testing."""
with patch("custom_components.robovac.robovac.TuyaDevice.__init__", return_value=None):
robovac = RoboVac(
model_code="TXXX",
device_id="test_id",
host="192.168.1.100",
local_key="test_key",
)
return robovac
def test_txxx_model_has_required_commands(mock_txxx_robovac):
"""Test that TXXX model has required commands defined."""
commands = mock_txxx_robovac.model_details.commands
assert RobovacCommand.MODE in commands
assert RobovacCommand.FAN_SPEED in commands
# ... other assertions- DEBUG: Diagnostic information for troubleshooting (e.g., value lookups, state changes)
- INFO: General informational messages (e.g., "Data points now available")
- WARNING: Actual problems that need attention (e.g., initialization failures, update failures)
- ERROR: Serious errors (e.g., vacuum not initialized for critical operations)
# DEBUG: Diagnostic information
_LOGGER.debug("Successfully updated vacuum %s", self._attr_name)
# WARNING: Actual problem
_LOGGER.warning("Cannot update vacuum %s: IP address not set", self._attr_name)
# ERROR: Serious issue
_LOGGER.error("Cannot locate vacuum: vacuum not initialized")Follow the pattern from test_t2251_command_mappings.py:
- Create a fixture for the mock RoboVac instance
- Test command value mappings
- Test case-insensitive matching
- Test model structure (commands present)
- Aim for 100% coverage of modified code
- Test both success and failure paths
- Use mocking to isolate units under test
- Follow TDD: write tests before implementation
- Run
task testto verify coverage
# View coverage report
task test
# Generate HTML coverage report
pytest --cov=custom_components.robovac --cov-report=htmlFollow Conventional Commits:
feat:New featurefix:Bug fixrefactor:Code refactoring without behavior changetest:Adding or updating testsdocs:Documentation updateschore:Maintenance tasks
Examples:
feat: add T2250 command mappings
fix: handle "No error" status correctly
test: add T2251 command mapping tests
refactor: improve value lookup logic
docs: update development guide
# Run with verbose output
pytest tests/test_vacuum/test_t2251_command_mappings.py -v -s
# Run with pdb debugger
pytest tests/test_vacuum/test_t2251_command_mappings.py --pdb
# Run specific test
pytest tests/test_vacuum/test_t2251_command_mappings.py::test_t2251_mode_has_values -v# Run type checker
task type-check
# Check specific file
mypy custom_components/robovac/robovac.py# Run linter
task lint
# Auto-fix formatting issues
black custom_components/robovac/- Home Assistant Developer Documentation
- Tuya Local API Documentation
- Pytest Documentation
- Python Type Hints
- Check existing issues and PRs
- Review the troubleshooting guide
- Enable debug logging to diagnose issues
- Create detailed issue reports with logs
Last Updated: October 2025 Maintained By: RoboVac Integration Team