ha-mcp-dev 7.6.0.dev668__tar.gz → 7.6.0.dev670__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. {ha_mcp_dev-7.6.0.dev668/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev670}/PKG-INFO +1 -1
  2. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/pyproject.toml +1 -1
  3. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_energy.py +57 -26
  4. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
  5. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/LICENSE +0 -0
  6. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/MANIFEST.in +0 -0
  7. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/README.md +0 -0
  8. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/setup.cfg +0 -0
  9. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/__init__.py +0 -0
  10. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/__main__.py +0 -0
  11. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/_pypi_marker +0 -0
  12. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/_version.py +0 -0
  13. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/auth/__init__.py +0 -0
  14. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/auth/consent_form.py +0 -0
  15. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/auth/provider.py +0 -0
  16. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/backup_manager.py +0 -0
  17. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/client/__init__.py +0 -0
  18. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/client/rest_client.py +0 -0
  19. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/client/supervisor_client.py +0 -0
  20. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/client/websocket_client.py +0 -0
  21. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/client/websocket_listener.py +0 -0
  22. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/config.py +0 -0
  23. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/dashboard_screenshot/__init__.py +0 -0
  24. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/dashboard_screenshot/capture.py +0 -0
  25. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/dashboard_screenshot/provision.py +0 -0
  26. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/errors.py +0 -0
  27. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/__init__.py +0 -0
  28. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/approval_queue.py +0 -0
  29. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/evaluator.py +0 -0
  30. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/handlers.py +0 -0
  31. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/middleware.py +0 -0
  32. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/model.py +0 -0
  33. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/persistence.py +0 -0
  34. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/policy/value_sources.py +0 -0
  35. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/py.typed +0 -0
  36. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
  37. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
  38. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
  39. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
  40. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
  41. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
  42. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
  43. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
  44. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
  45. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
  46. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
  47. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
  48. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
  49. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
  50. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
  51. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
  52. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
  53. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
  54. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
  55. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
  56. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
  57. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
  58. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/server.py +0 -0
  59. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/settings.css +0 -0
  60. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/settings.js +0 -0
  61. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/settings_ui.py +0 -0
  62. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/smoke_test.py +0 -0
  63. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
  64. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/__init__.py +0 -0
  65. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/auto_backup.py +0 -0
  66. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/backup.py +0 -0
  67. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/best_practice_checker.py +0 -0
  68. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/device_control.py +0 -0
  69. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/enhanced.py +0 -0
  70. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/helpers.py +0 -0
  71. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/reference_validator.py +0 -0
  72. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/registry.py +0 -0
  73. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/__init__.py +0 -0
  74. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_base.py +0 -0
  75. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_config.py +0 -0
  76. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_deep.py +0 -0
  77. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_entities.py +0 -0
  78. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_fetch.py +0 -0
  79. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_overview.py +0 -0
  80. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_scenes.py +0 -0
  81. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/smart_search/_scoring.py +0 -0
  82. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_addons.py +0 -0
  83. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_areas.py +0 -0
  84. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_blueprints.py +0 -0
  85. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_bug_report.py +0 -0
  86. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_calendar.py +0 -0
  87. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_camera.py +0 -0
  88. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_categories.py +0 -0
  89. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_code.py +0 -0
  90. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_config_automations.py +0 -0
  91. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
  92. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
  93. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
  94. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
  95. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
  96. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_dashboard_screenshot.py +0 -0
  97. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_entities.py +0 -0
  98. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_filesystem.py +0 -0
  99. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_groups.py +0 -0
  100. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_hacs.py +0 -0
  101. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_history.py +0 -0
  102. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_integrations.py +0 -0
  103. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_labels.py +0 -0
  104. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
  105. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_registry.py +0 -0
  106. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_resources.py +0 -0
  107. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_search.py +0 -0
  108. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_service.py +0 -0
  109. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_services.py +0 -0
  110. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_system.py +0 -0
  111. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_todo.py +0 -0
  112. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_traces.py +0 -0
  113. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_updates.py +0 -0
  114. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_utility.py +0 -0
  115. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
  116. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
  117. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/tools_zones.py +0 -0
  118. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/util_helpers.py +0 -0
  119. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/tools/validation_middleware.py +0 -0
  120. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/transforms/__init__.py +0 -0
  121. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/transforms/categorized_search.py +0 -0
  122. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
  123. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/__init__.py +0 -0
  124. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/config_hash.py +0 -0
  125. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/data_paths.py +0 -0
  126. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/domain_handlers.py +0 -0
  127. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/fuzzy_search.py +0 -0
  128. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
  129. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/operation_manager.py +0 -0
  130. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/python_sandbox.py +0 -0
  131. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/skill_loader.py +0 -0
  132. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp/utils/usage_logger.py +0 -0
  133. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
  134. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
  135. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
  136. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
  137. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
  138. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/tests/__init__.py +0 -0
  139. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/tests/test_constants.py +0 -0
  140. {ha_mcp_dev-7.6.0.dev668 → ha_mcp_dev-7.6.0.dev670}/tests/test_env_manager.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.6.0.dev668
3
+ Version: 7.6.0.dev670
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ha-mcp-dev"
7
- version = "7.6.0.dev668"
7
+ version = "7.6.0.dev670"
8
8
  description = "Home Assistant MCP Server - Complete control of Home Assistant through MCP"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.13,<3.14"
@@ -59,6 +59,33 @@ _PREFS_TOP_LEVEL_KEYS: tuple[_PrefsKey, ...] = (
59
59
  "device_consumption_water",
60
60
  )
61
61
 
62
+ # Energy source ``type`` values accepted by HA Core's ``SourceType`` union
63
+ # (homeassistant/components/energy/data.py). ``_EnergySourceType`` names the
64
+ # domain (mirroring the ``_PrefsKey`` pattern above) and ``_ENERGY_SOURCE_TYPES``
65
+ # is its ordered realization — the single source of truth for the local shape
66
+ # check. A type missing here is spuriously rejected even though
67
+ # ``energy/save_prefs`` would accept it; when HA Core adds a source type, add it
68
+ # in both places. Ordered (not a ``set``) to match the upstream union and to
69
+ # keep error messages deterministic. See issue #1530.
70
+ _EnergySourceType = Literal["grid", "solar", "battery", "gas", "water"]
71
+ _ENERGY_SOURCE_TYPES: tuple[_EnergySourceType, ...] = (
72
+ "grid",
73
+ "solar",
74
+ "battery",
75
+ "gas",
76
+ "water",
77
+ )
78
+
79
+ # Non-grid source types. Each requires a ``stat_energy_from`` consumption
80
+ # statistic and is de-duplicated by this tool on ``(type, stat_energy_from)``
81
+ # (used for both the shape check's required-field rule and
82
+ # ``_append_unique_source`` de-duplication). ``grid`` is excluded: its
83
+ # ``stat_energy_from`` is optional and a hub can legitimately carry multiple grid
84
+ # variants, so it has no single uniqueness key.
85
+ _STAT_FROM_SOURCE_TYPES: frozenset[str] = frozenset(
86
+ t for t in _ENERGY_SOURCE_TYPES if t != "grid"
87
+ )
88
+
62
89
 
63
90
  def _default_prefs() -> dict[str, Any]:
64
91
  """Return the default empty prefs structure used by HA Core.
@@ -196,25 +223,25 @@ def _shape_check(
196
223
  )
197
224
  continue
198
225
  if key == "energy_sources":
199
- valid_types = {"grid", "solar", "battery", "gas"}
200
- requires_stat_from = {"solar", "battery", "gas"}
226
+ valid_types = "|".join(_ENERGY_SOURCE_TYPES)
201
227
  entry_type = entry.get("type")
202
228
  if entry_type is None:
203
229
  errors.append(
204
230
  {
205
231
  "path": f"{key}[{idx}]",
206
- "message": "energy_sources entries require 'type' (grid|solar|battery|gas)",
232
+ "message": f"energy_sources entries require 'type' ({valid_types})",
207
233
  }
208
234
  )
209
- elif entry_type not in valid_types:
235
+ elif entry_type not in _ENERGY_SOURCE_TYPES:
210
236
  errors.append(
211
237
  {
212
238
  "path": f"{key}[{idx}].type",
213
- "message": f"invalid type '{entry_type}' (must be one of grid|solar|battery|gas)",
239
+ "message": f"invalid type '{entry_type}' (must be one of {valid_types})",
214
240
  }
215
241
  )
216
242
  elif (
217
- entry_type in requires_stat_from and "stat_energy_from" not in entry
243
+ entry_type in _STAT_FROM_SOURCE_TYPES
244
+ and "stat_energy_from" not in entry
218
245
  ):
219
246
  errors.append(
220
247
  {
@@ -354,7 +381,7 @@ class EnergyTools:
354
381
  "the mutation against a fresh read and reports what would "
355
382
  "change without writing — but still raises "
356
383
  "RESOURCE_ALREADY_EXISTS (duplicate add_device, or duplicate "
357
- "add_source for solar/battery/gas), RESOURCE_NOT_FOUND "
384
+ "add_source for solar/battery/gas/water), RESOURCE_NOT_FOUND "
358
385
  "(missing remove_device), or VALIDATION_FAILED (post-mutator "
359
386
  "shape error) when the proposed mutation is not applicable. "
360
387
  "Default False."
@@ -414,11 +441,14 @@ class EnergyTools:
414
441
  Field(
415
442
  description=(
416
443
  "Single energy_sources entry for mode='add_source'. Must "
417
- "contain 'type' (one of grid|solar|battery|gas) and the "
418
- "type-specific required fields (e.g. solar/battery/gas "
419
- "require 'stat_energy_from'). Note: HA Core's voluptuous "
420
- "schema for grid sources requires the full field set "
421
- "(cost_adjustment_day, stat_energy_to, stat_cost, "
444
+ "contain 'type' (one of grid|solar|battery|gas|water) and "
445
+ "the type-specific required fields (e.g. "
446
+ "solar/battery/gas/water require 'stat_energy_from'). Every "
447
+ "source type also accepts an optional 'name' (display label "
448
+ "in the energy graphs); battery additionally accepts "
449
+ "'stat_soc' (state-of-charge statistic). Note: HA Core's "
450
+ "voluptuous schema for grid sources requires the full field "
451
+ "set (cost_adjustment_day, stat_energy_to, stat_cost, "
422
452
  "entity_energy_price, number_energy_price, "
423
453
  "entity_energy_price_export, number_energy_price_export, "
424
454
  "stat_compensation) — the local shape check is narrower, "
@@ -434,11 +464,11 @@ class EnergyTools:
434
464
  """
435
465
  Manage the Home Assistant Energy Dashboard preferences.
436
466
 
437
- The Energy Dashboard configuration (grid/solar/battery/gas sources,
438
- individual device consumption sensors, cost tariffs, water) is stored
439
- in ``.storage/energy`` and not otherwise reachable via REST, services,
440
- or helper flows — this tool is the only way for agents to inspect or
441
- modify it.
467
+ The Energy Dashboard configuration (grid/solar/battery/gas/water energy
468
+ sources, individual device consumption sensors for electricity and
469
+ water, cost tariffs) is stored in ``.storage/energy`` and not otherwise
470
+ reachable via REST, services, or helper flows — this tool is the only
471
+ way for agents to inspect or modify it.
442
472
 
443
473
  WHEN TO USE:
444
474
  - mode='get' / 'set': inspect or replace the full Energy Dashboard
@@ -449,7 +479,8 @@ class EnergyTools:
449
479
  internally; the caller does NOT manage config_hash. Use ``water=True``
450
480
  to target the water meter list instead of electricity.
451
481
  - mode='add_source': append a single entry to ``energy_sources`` (grid,
452
- solar, battery, or gas). Same atomic read-modify-write semantics.
482
+ solar, battery, gas, or water). Same atomic read-modify-write
483
+ semantics.
453
484
 
454
485
  WHEN NOT TO USE:
455
486
  - To create the underlying statistics themselves — they must already
@@ -491,7 +522,7 @@ class EnergyTools:
491
522
  - Convenience modes are NOT idempotent: 'add_device' on an existing
492
523
  ``stat_consumption`` returns RESOURCE_ALREADY_EXISTS; 'remove_device'
493
524
  on a missing entry returns RESOURCE_NOT_FOUND. 'add_source' rejects
494
- duplicates by ``(type, stat_energy_from)`` for solar/battery/gas
525
+ duplicates by ``(type, stat_energy_from)`` for solar/battery/gas/water
495
526
  (RESOURCE_ALREADY_EXISTS); grid entries are appended without a
496
527
  duplicate check (multiple grid variants are legitimate, and grid
497
528
  has no single canonical uniqueness key) — the caller is responsible
@@ -1094,15 +1125,15 @@ class EnergyTools:
1094
1125
 
1095
1126
  The ``source`` dict is wrapped into a synthetic single-entry config
1096
1127
  for ``_shape_check`` reuse, which validates the type-specific
1097
- required fields (e.g. ``stat_energy_from`` for solar/battery/gas).
1128
+ required fields (e.g. ``stat_energy_from`` for solar/battery/gas/water).
1098
1129
 
1099
1130
  Duplicate semantics are asymmetric to ``_add_device`` because
1100
1131
  ``energy_sources`` does not expose a single uniqueness key across
1101
- types: solar/battery/gas are keyed on ``stat_energy_from``, but
1132
+ types: solar/battery/gas/water are keyed on ``stat_energy_from``, but
1102
1133
  ``grid`` entries can legitimately have multiple variants
1103
1134
  (different tariffs, multiple meters) where ``stat_energy_from``
1104
1135
  alone does not identify duplicates. We therefore reject duplicates
1105
- by ``(type, stat_energy_from)`` for solar/battery/gas only and
1136
+ by ``(type, stat_energy_from)`` for solar/battery/gas/water only and
1106
1137
  leave grid de-duplication to the caller.
1107
1138
  """
1108
1139
  if source is None:
@@ -1112,7 +1143,7 @@ class EnergyTools:
1112
1143
  "'source' is required when mode='add_source'",
1113
1144
  context={"mode": "add_source"},
1114
1145
  suggestions=[
1115
- "Pass source={'type': 'grid'|'solar'|'battery'|'gas', ...}",
1146
+ "Pass source={'type': 'grid'|'solar'|'battery'|'gas'|'water', ...}",
1116
1147
  ],
1117
1148
  )
1118
1149
  )
@@ -1132,7 +1163,7 @@ class EnergyTools:
1132
1163
  },
1133
1164
  suggestions=[
1134
1165
  "Fix the listed errors and retry",
1135
- "solar/battery/gas need 'stat_energy_from'; grid needs "
1166
+ "solar/battery/gas/water need 'stat_energy_from'; grid needs "
1136
1167
  + "only 'type' for the local check, but HA Core's voluptuous "
1137
1168
  + "schema requires the full grid field set "
1138
1169
  + "(cost_adjustment_day, stat_energy_to, stat_cost, "
@@ -1189,7 +1220,7 @@ class EnergyTools:
1189
1220
  """Append ``new_source`` to ``existing`` with type-aware duplicate
1190
1221
  detection.
1191
1222
 
1192
- Solar/battery/gas entries are keyed on
1223
+ Solar/battery/gas/water entries are keyed on
1193
1224
  ``(type, stat_energy_from)`` — duplicates raise
1194
1225
  ``RESOURCE_ALREADY_EXISTS``. Grid entries are appended without a
1195
1226
  duplicate check (multiple grid variants are legitimate, and grid
@@ -1199,7 +1230,7 @@ class EnergyTools:
1199
1230
  backstop for whatever HA Core flags.
1200
1231
  """
1201
1232
  source_type = new_source.get("type")
1202
- if source_type in {"solar", "battery", "gas"}:
1233
+ if source_type in _STAT_FROM_SOURCE_TYPES:
1203
1234
  stat = new_source.get("stat_energy_from")
1204
1235
  for entry in existing:
1205
1236
  if (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ha-mcp-dev
3
- Version: 7.6.0.dev668
3
+ Version: 7.6.0.dev670
4
4
  Summary: Home Assistant MCP Server - Complete control of Home Assistant through MCP
5
5
  Author-email: Julien <github@qc-h.net>
6
6
  License: MIT