ha-mcp-dev 7.6.0.dev610__tar.gz → 7.6.0.dev611__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.
- {ha_mcp_dev-7.6.0.dev610/src/ha_mcp_dev.egg-info → ha_mcp_dev-7.6.0.dev611}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/pyproject.toml +1 -1
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/best_practice_checker.py +45 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611/src/ha_mcp_dev.egg-info}/PKG-INFO +1 -1
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/MANIFEST.in +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/setup.cfg +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/__main__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/_pypi_marker +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/_version.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/auth/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/auth/consent_form.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/auth/provider.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/backup_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/client/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/client/rest_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/client/supervisor_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/client/websocket_client.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/client/websocket_listener.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/config.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/errors.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/approval_queue.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/evaluator.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/middleware.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/model.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/persistence.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/policy/value_sources.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/py.typed +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/.claude/settings.json +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/.claude-plugin/marketplace.json +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/.claude-plugin/plugin.json +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/.github/ISSUE_TEMPLATE/skill-rca.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/.github/pull_request_template.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/AGENTS.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/CLAUDE.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/CONTRIBUTING.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/LICENSE +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/README.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/SKILL.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/evals/evals.json +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/automation-patterns.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-cards.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/dashboard-guide.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/device-control.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/domain-docs.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/examples.yaml +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/helper-selection.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/safe-refactoring.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/template-guidelines.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/skills/home-assistant-best-practices/references/yaml-only-integrations.md +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/server.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/settings_ui.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/smoke_test.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/stdio_settings_sidecar.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/auto_backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/backup.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/device_control.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/enhanced.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/reference_validator.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/smart_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_addons.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_areas.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_blueprints.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_bug_report.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_calendar.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_camera.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_categories.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_code.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_automations.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_dashboards.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_entry_flow.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_scenes.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_scripts.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_energy.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_entities.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_filesystem.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_groups.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_hacs.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_history.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_integrations.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_labels.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_mcp_component.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_registry.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_resources.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_service.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_services.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_system.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_todo.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_traces.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_updates.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_utility.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_voice_assistant.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_yaml_config.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_zones.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/util_helpers.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/transforms/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/transforms/categorized_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/transforms/lite_docstrings.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/config_hash.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/data_paths.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/domain_handlers.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/fuzzy_search.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/kill_signal_diagnostics.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/operation_manager.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/python_sandbox.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/usage_logger.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/SOURCES.txt +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/dependency_links.txt +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/entry_points.txt +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/requires.txt +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/top_level.txt +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/tests/__init__.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/tests/test_constants.py +0 -0
- {ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/tests/test_env_manager.py +0 -0
|
@@ -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.
|
|
7
|
+
version = "7.6.0.dev611"
|
|
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"
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/best_practice_checker.py
RENAMED
|
@@ -77,6 +77,13 @@ _RE_SUN = re.compile(r"(?:is_state|state_attr|states)\s*\(\s*['\"]sun\.sun['\"]"
|
|
|
77
77
|
_RE_STATE_IN = re.compile(r"states\s*\([^)]+\)\s+in\s+[\[(]")
|
|
78
78
|
# Unsafe direct state access: states.sensor.x.state
|
|
79
79
|
_RE_DIRECT_STATE = re.compile(r"\bstates\.\w+\.\w+\.state\b")
|
|
80
|
+
# Duration/recency checks via last_changed or last_updated arithmetic.
|
|
81
|
+
# Both alternations require at least one dotted qualifier (e.g. ``states.sensor.x.``)
|
|
82
|
+
# so bare Jinja variables named ``last_changed`` are not falsely flagged.
|
|
83
|
+
_RE_DURATION_MATH = re.compile(
|
|
84
|
+
r"\bnow\(\)\s*-\s*(?:\w+\.)+last_(?:changed|updated)\b"
|
|
85
|
+
r"|\b(?:\w+\.)+last_(?:changed|updated)\s*<\s*now\(\)"
|
|
86
|
+
)
|
|
80
87
|
# Motion entity pattern
|
|
81
88
|
_RE_MOTION = re.compile(r"binary_sensor\.\w*motion", re.IGNORECASE)
|
|
82
89
|
# Any Jinja template marker — catch-all and target-field scan.
|
|
@@ -273,6 +280,16 @@ def _check_template_string(
|
|
|
273
280
|
"function instead (returns 'unknown' if missing rather than raising)."
|
|
274
281
|
+ _ref(skill_prefix, "template-guidelines.md#common-patterns")
|
|
275
282
|
)
|
|
283
|
+
if _RE_DURATION_MATH.search(template):
|
|
284
|
+
warnings.append(
|
|
285
|
+
f"{label} uses template for duration/recency check "
|
|
286
|
+
"(`now() - X.last_changed/last_updated`) — use the native `for:` field "
|
|
287
|
+
"on a `state` trigger or condition instead "
|
|
288
|
+
"(e.g., `platform: state, entity_id: binary_sensor.motion, to: 'off', "
|
|
289
|
+
"for: {minutes: 5}`). Native `for:` is event-driven and avoids repeated "
|
|
290
|
+
"template evaluation on every state change."
|
|
291
|
+
+ _ref(skill_prefix, "automation-patterns.md#native-conditions")
|
|
292
|
+
)
|
|
276
293
|
|
|
277
294
|
# Generic fallback: any Jinja in this logic position that didn't match
|
|
278
295
|
# a specific detector. Catches new anti-patterns (issue #1011) and
|
|
@@ -505,6 +522,19 @@ def _check_triggers(
|
|
|
505
522
|
"automation-patterns.md#trigger-types",
|
|
506
523
|
)
|
|
507
524
|
)
|
|
525
|
+
if _RE_DURATION_MATH.search(vt):
|
|
526
|
+
warnings.append(
|
|
527
|
+
"Trigger uses template for duration/recency check "
|
|
528
|
+
"(`now() - X.last_changed/last_updated`) — use the native "
|
|
529
|
+
"`for:` field on a `state` trigger instead "
|
|
530
|
+
"(e.g., `platform: state, entity_id: binary_sensor.motion, "
|
|
531
|
+
"to: 'off', for: {minutes: 5}`). Native `for:` is event-driven "
|
|
532
|
+
"and doesn't re-evaluate on every state change."
|
|
533
|
+
+ _ref(
|
|
534
|
+
skill_prefix,
|
|
535
|
+
"automation-patterns.md#trigger-types",
|
|
536
|
+
)
|
|
537
|
+
)
|
|
508
538
|
# Generic fallback for unmatched template triggers.
|
|
509
539
|
if len(warnings) == initial and _RE_ANY_TEMPLATE.search(vt):
|
|
510
540
|
warnings.append(
|
|
@@ -518,6 +548,21 @@ def _check_triggers(
|
|
|
518
548
|
)
|
|
519
549
|
)
|
|
520
550
|
|
|
551
|
+
# numeric_state trigger: value_template can also contain duration math
|
|
552
|
+
# (e.g. transforming last_changed into a seconds value for the threshold).
|
|
553
|
+
if platform == "numeric_state":
|
|
554
|
+
vt = trigger.get("value_template", "")
|
|
555
|
+
if isinstance(vt, str) and _RE_DURATION_MATH.search(vt):
|
|
556
|
+
warnings.append(
|
|
557
|
+
"`numeric_state` trigger uses `value_template` for duration/recency "
|
|
558
|
+
"check (`now() - X.last_changed/last_updated`) — use the native "
|
|
559
|
+
"`for:` field on a `state` trigger instead "
|
|
560
|
+
"(e.g., `platform: state, entity_id: binary_sensor.motion, "
|
|
561
|
+
"to: 'off', for: {minutes: 5}`). Native `for:` is event-driven "
|
|
562
|
+
"and doesn't re-evaluate on every state change."
|
|
563
|
+
+ _ref(skill_prefix, "automation-patterns.md#trigger-types")
|
|
564
|
+
)
|
|
565
|
+
|
|
521
566
|
|
|
522
567
|
# ---------------------------------------------------------------------------
|
|
523
568
|
# Mode + motion check
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/AGENTS.md
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/CLAUDE.md
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/LICENSE
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/resources/skills-vendor/README.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_automations.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_dashboards.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_entry_flow.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_helpers.py
RENAMED
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_config_scripts.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/tools/tools_voice_assistant.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/transforms/categorized_search.py
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/transforms/lite_docstrings.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp/utils/kill_signal_diagnostics.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{ha_mcp_dev-7.6.0.dev610 → ha_mcp_dev-7.6.0.dev611}/src/ha_mcp_dev.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|