Thank you for your interest in contributing to WashData! 🎉 This document provides guidelines and instructions for contributing to the project.
Before contributing, please review our Code of Conduct. By participating, you agree to uphold these standards.
- Getting Started
- Development Setup
- Types of Contributions
- Pull Request Process
- Coding Standards
- Testing
- Git Commit Messages
- Localization & Translations
- Questions & Support
- Python 3.11+
- Home Assistant development environment knowledge (helpful but not required)
- Git and GitHub account
- Fork the repository on GitHub
- Clone your fork locally:
git clone https://github.com/YOUR_USERNAME/ha_washdata.git cd ha_washdata - Add upstream remote to stay in sync:
git remote add upstream https://github.com/3dg1luk43/ha_washdata.git
- Initialize translator submodule (required for translation tooling):
This populates
git submodule update --init --recursive
scripts/ha_integration_translator.
git checkout -b feature/your-feature-name
# or for bug fixes:
git checkout -b fix/brief-descriptionUse descriptive branch names (e.g., feature/cycle-detection-improvement, fix/timezone-bug).
python3 -m venv .venv
source .venv/bin/activate # On Windows: .venv\Scripts\activateOn Windows, if VS Code does not auto-detect the interpreter from .venv, set local
workspace overrides to .venv\\Scripts\\python.exe (and use that interpreter for pytest).
pip install -r requirements-dev.txtVerify your Python code before committing:
python3 -m compileall custom_components/ha_washdata tests/ --quiet./run_tests.sh
# or manually:
pytest tests/ -vTo simulate a washing machine with power readings:
python3 devtools/mqtt_mock_socket.py --default LONG --variability 0.15For full mock testing guide, see TESTING.md.
Found a bug? Open an issue using our bug report template. Include:
- Clear description of the issue
- Steps to reproduce
- Your WashData version and Home Assistant version
- Relevant logs or error messages
Have an idea? Open an issue using our feature request template. Describe:
- What the feature should do
- Why it would be useful
- How it should work (with examples if possible)
IMPORTANT: Submit translations via Pull Request, not as issues.
See Localization & Translations section below.
Improve READMEs, guides, or docstrings:
- Edit the relevant
.mdor.pyfile - Submit a PR with clear changes
- Documentation improvements are always welcome!
Review open PRs and provide constructive feedback. Even experienced contributors value a second set of eyes.
-
Sync with upstream: Ensure your branch is up-to-date with
maingit fetch upstream git rebase upstream/main
-
Check for existing work: Search issues and PRs to avoid duplicate efforts
-
For large changes: Open an issue first to discuss with maintainers
-
Write clean, focused code:
- One feature/fix per PR (don't mix unrelated changes)
- Follow the project's coding standards (see below)
- Include comments for complex logic
-
Test your changes:
./run_tests.sh python3 -m compileall custom_components/ha_washdata tests/ --quiet
-
Update documentation:
- Docstrings for functions/classes
- README if adding UI components
- CHANGELOG if it's a user-facing change
-
Push to your fork:
git push origin feature/your-feature-name
-
Open a Pull Request on GitHub with:
- Clear title describing the change
- Detailed description (use our PR template)
- Reference any related issues:
Closes #123 - Screenshots for UI changes
-
Respond to reviews:
- Be open to feedback
- Make requested changes promptly
- If you disagree, explain your reasoning
- Re-request review after making changes
[FEATURE]- New features[FIX]- Bug fixes[REFACTOR]- Code reorganization (no behavior change)[DOCS]- Documentation only[TEST]- Test improvements[PERF]- Performance improvements
Example: [FIX] Handle timezone-aware datetime in cycle detection
- PEP 8 compliance (with Black formatter preferences)
- Type hints for better IDE support
- Docstrings for all public functions/classes (Google style)
- No hardcoded UI strings - use
strings.jsonandtranslations/for all user-facing text
Example:
async def async_method(self, device_id: str, config: dict[str, Any]) -> None:
"""
Perform an async operation.
Args:
device_id: The device identifier
config: Configuration dictionary
Returns:
None
"""
# Implementation- ONLY NumPy for calculations (no SciPy or ML libraries)
- No external API calls - all processing must be local
- Timezone-aware datetimes - ALWAYS use
dt_util.now() - No inline UI strings - use translation keys instead
- Respect 32KB event data limit - exclude large data from fired events
See copilot-instructions.md for full technical details.
- New feature files go in
custom_components/ha_washdata/ - Tests go in
tests/mirroring the module structure - Documentation additions go in
doc/folder - Do NOT modify core architecture files without discussion
# All tests
pytest tests/ -v
# Specific test file
pytest tests/test_cycle_detector.py -v
# With coverage
pytest tests/ --cov=custom_components.ha_washdata- Use
pytestframework - Mock external dependencies (Home Assistant services, etc.)
- Aim for >80% code coverage on new code
- Test both happy-path and edge cases
Example test structure:
import pytest
from unittest.mock import Mock, AsyncMock
@pytest.fixture
def mock_manager():
"""Fixture providing a mock WashDataManager."""
return Mock()
@pytest.mark.asyncio
async def test_cycle_detection(mock_manager):
"""Test that cycles are detected correctly."""
mock_manager.some_method.return_value = "expected_value"
assert mock_manager.some_method() == "expected_value"Write clear, descriptive commit messages:
type: brief summary (50 chars max)
Longer explanation of what changed and why. Wrap at 72 characters.
Explain the problem you're solving, not just the code changes.
- Bullet point for major changes
- Another detail
Fixes #123
Types:
feat:New featurefix:Bug fixrefactor:Code reorganizationdocs:Documentationtest:Test additions/improvementsperf:Performance improvementschore:Build, config, dependencies
Examples:
feat: Add predictive end-time calculationfix: Handle null power readings gracefullydocs: Update TESTING.md with mock socket guide
Do NOT open an issue to report bad translations. Instead:
-
Edit the translation file for your language
- Location:
custom_components/ha_washdata/translations/[language-code].json - Example:
translations/ru.json,translations/es.json
- Location:
-
Submit a Pull Request with your corrections
- Include a brief description of what was corrected
-
Use translation script (for Home Assistant translations):
source .venv_translation/bin/activate python3 scripts/ha_integration_translator/translate.py custom_components/ha_washdata/translations --all -
Protect manually curated keys from auto-overwrite (recommended):
- Add key paths to
custom_components/ha_washdata/translations/.translation-locks.json - Exact key lock example:
options.step.manage_profiles.title - Prefix lock example:
options.common_text.* - On next automated translation run, locked existing keys are preserved.
- Add key paths to
- Copy
translations/en.jsontotranslations/[new-language-code].json - Translate all values (keep keys unchanged)
- Include in strings.json if needed
- Submit PR with translations
Note: Translations are validated automatically. Ensure JSON is valid before submitting.
- Question about contributing? → Open a Discussion on GitHub
- Found a bug? → Open an Issue with the bug report template
- Have a feature idea? → Open an Issue with the feature request template
- Need development help? → Reach out to maintainers via discussion
- Be respectful and assume good intentions
- Search first - your question may already be answered
- Provide context - share relevant code/logs
- Be patient - maintainers are volunteers
Contributors to WashData are recognized in:
- CHANGELOG.md for significant contributions
- GitHub's contributor graph
- Project README acknowledgments (major contributors)
Thank you for making WashData better! 🌟
Last Updated: 2026-03-11