|
385 | 385 | { |
386 | 386 | "name": "ha_config_set_automation", |
387 | 387 | "title": "Create or Update Automation", |
388 | | - "description": "Create or update a Home Assistant automation. MUST call ha_get_skill_guide first.\n\nPREFER NATIVE SOLUTIONS OVER TEMPLATES (read this before writing any `{{ ... }}`):\nNative triggers/conditions/actions are validated at config load, fail loudly, and\ndo not bypass HA's schema. Templates fail silently at runtime and obscure intent.\n- `condition: numeric_state` instead of `{{ states('x') | float > N }}`\n- `condition: state` (with `state:` list) instead of `{{ is_state(...) }}` /\n `{{ states(x) in [...] }}`\n- `condition: time` instead of `{{ now().hour ... }}` or `{{ now().weekday() ... }}`\n- `condition: sun` instead of `{{ is_state('sun.sun', ...) }}`\n- Native `for:` field on `state`/`numeric_state` triggers and `state`\n conditions over `{{ now() - X.last_changed > timedelta(...) }}` duration math.\n- `wait_for_trigger` instead of `wait_template`\n- `choose` action instead of template-based service names\n- For one-shot date firing, use a `time` trigger plus `automation.turn_off` on a\n hardcoded entity_id — not `{{ now().date() ... }}`.\n- Hardcode `target.entity_id` literals — never `{{ this.entity_id }}`.\nTemplates are appropriate ONLY in `data.*` fields, notification message/title,\n`event_data`, and `variables`. The reactive best-practice checker on this tool\nwill surface anything in a logic position that should be native; consult the\n`best_practice_warnings` field on the response and fix before re-submitting.\nThe relevant skill section is auto-embedded under `skill_content` on warnings,\nand the full `automation-patterns.md` + `template-guidelines.md` references\nship under `skill_content` proactively by default. For comprehensive\nguidance beyond that, call `ha_get_skill_guide`.\n\nThe returned `automation_id` is the resolved entity_id (canonical\nform, e.g. `automation.morning_routine`) when entity registration\nsucceeds, falling back to the input `identifier` (update path) or\nthe generated `unique_id` from the upsert response (fresh create\nwhen no identifier was passed).\n\nBefore reaching for ``ha_config_set_automation``, consider whether a\ndedicated tool fits the use case better:\n\n- State snapshot of one or more entities (capture-then-replay,\n no trigger needed) -> ha_config_set_scene\n- State-derived value that recomputes when its inputs change\n (template sensor / binary sensor / number / select)\n -> ha_config_set_helper(helper_type='template')\n- Stateful counter / timer / schedule / boolean / etc.\n -> ha_config_set_helper(helper_type='counter' | 'timer' | ...)\n\nSupports two modes: full config replacement OR Python transformation.\n\nWHEN TO USE WHICH MODE:\n- python_transform: RECOMMENDED for edits to existing automations. Surgical updates.\n- config: Use for creating new automations or full restructures.\n\nIMPORTANT: python_transform requires 'identifier' and 'config_hash' from ha_config_get_automation().\n\nPYTHON TRANSFORM EXAMPLES:\n- Update action: python_transform=\"config['action'][0]['data']['brightness'] = 255\"\n- Add trigger: python_transform=\"config['trigger'].append({'platform': 'state', 'entity_id': 'binary_sensor.motion', 'to': 'on'})\"\n- Remove last action: python_transform=\"config['action'].pop()\"\n\nCreates a new automation (if identifier omitted) or updates existing automation with provided configuration.\n\nAUTOMATION TYPES:\n\n1. Regular Automations - Define triggers and actions directly\n2. Blueprint Automations - Use pre-built templates with customizable inputs\n\nREQUIRED FIELDS (Regular Automations):\n- alias: Human-readable automation name\n- trigger: List of trigger conditions (time, state, event, etc.)\n- action: List of actions to execute\n\nREQUIRED FIELDS (Blueprint Automations):\n- alias: Human-readable automation name\n- use_blueprint: Blueprint configuration\n - path: Blueprint file path (e.g., \"motion_light.yaml\")\n - input: Dictionary of input values for the blueprint\n\nOPTIONAL CONFIG FIELDS (Regular Automations):\n- description: Detailed description of the user's intent (RECOMMENDED: helps safely modify implementation later)\n- category: Category ID for organization (use ha_config_get_category to list, ha_config_set_category to create)\n- condition: Additional conditions that must be met\n- mode: 'single' (default), 'restart', 'queued', 'parallel'\n- max: Maximum concurrent executions (for queued/parallel modes)\n- initial_state: Whether automation starts enabled (true/false)\n- variables: Variables for use in automation\n\nBASIC EXAMPLES:\n\nSimple time-based automation:\nha_config_set_automation(config={\n \"alias\": \"Morning Lights\",\n \"description\": \"Turn on bedroom lights at 7 AM to help wake up\",\n \"trigger\": [{\"platform\": \"time\", \"at\": \"07:00:00\"}],\n \"action\": [{\"action\": \"light.turn_on\", \"target\": {\"area_id\": \"bedroom\"}}]\n})\n\nMotion-activated lighting — `for:` on the off-transition replaces action-delay:\nha_config_set_automation(config={\n \"alias\": \"Motion Light\",\n \"trigger\": [\n {\"platform\": \"state\", \"entity_id\": \"binary_sensor.motion\", \"to\": \"on\", \"id\": \"motion_on\"},\n {\"platform\": \"state\", \"entity_id\": \"binary_sensor.motion\", \"to\": \"off\",\n \"for\": {\"minutes\": 5}, \"id\": \"motion_off\"}\n ],\n \"action\": [\n {\"choose\": [\n {\"conditions\": [\n {\"condition\": \"trigger\", \"id\": \"motion_on\"},\n {\"condition\": \"sun\", \"after\": \"sunset\"}\n ],\n \"sequence\": [{\"action\": \"light.turn_on\", \"target\": {\"entity_id\": \"light.hallway\"}}]},\n {\"conditions\": [{\"condition\": \"trigger\", \"id\": \"motion_off\"}],\n \"sequence\": [{\"action\": \"light.turn_off\", \"target\": {\"entity_id\": \"light.hallway\"}}]}\n ]}\n ]\n})\n\nUpdate existing automation:\nha_config_set_automation(\n identifier=\"automation.morning_routine\",\n config={\n \"alias\": \"Updated Morning Routine\",\n \"trigger\": [{\"platform\": \"time\", \"at\": \"06:30:00\"}],\n \"action\": [\n {\"action\": \"light.turn_on\", \"target\": {\"area_id\": \"bedroom\"}},\n {\"action\": \"climate.set_temperature\", \"target\": {\"entity_id\": \"climate.bedroom\"}, \"data\": {\"temperature\": 22}}\n ]\n }\n)\n\nBLUEPRINT AUTOMATION EXAMPLES:\n\nCreate automation from blueprint:\nha_config_set_automation(config={\n \"alias\": \"Motion Light Kitchen\",\n \"use_blueprint\": {\n \"path\": \"homeassistant/motion_light.yaml\",\n \"input\": {\n \"motion_entity\": \"binary_sensor.kitchen_motion\",\n \"light_target\": {\"entity_id\": \"light.kitchen\"},\n \"no_motion_wait\": 120\n }\n }\n})\n\nUpdate blueprint automation inputs:\nha_config_set_automation(\n identifier=\"automation.motion_light_kitchen\",\n config={\n \"alias\": \"Motion Light Kitchen\",\n \"use_blueprint\": {\n \"path\": \"homeassistant/motion_light.yaml\",\n \"input\": {\n \"motion_entity\": \"binary_sensor.kitchen_motion\",\n \"light_target\": {\"entity_id\": \"light.kitchen\"},\n \"no_motion_wait\": 300\n }\n }\n }\n)\n\nTRIGGER TYPES: time, time_pattern, sun, state, numeric_state, event, device, zone, template, and more\nCONDITION TYPES: state, numeric_state, time, sun, template, device, zone, and more\nACTION TYPES: action calls, delays, wait_for_trigger, wait_template, if/then/else, choose, repeat, parallel\n\nFor comprehensive automation documentation with all trigger/condition/action types and advanced examples:\n- Use: ha_get_skill_guide\n- Or visit: https://www.home-assistant.io/docs/automation/\n\nTROUBLESHOOTING:\n- Use ha_get_state() to verify entity_ids exist\n- Use ha_search() to find correct entity_ids\n- IF you must use Jinja2 and have no native alternative, test it first with\n ha_eval_template() before embedding it in the automation config — catches\n syntax errors and unresolved entity_ids before they fail silently at runtime\n- Use ha_search(domain_filter='automation') to find existing automations", |
| 388 | + "description": "Create or update a Home Assistant automation. MUST call ha_get_skill_guide first.\n\nPREFER NATIVE SOLUTIONS OVER TEMPLATES (read this before writing any `{{ ... }}`):\nNative triggers/conditions/actions are validated at config load, fail loudly, and\ndo not bypass HA's schema. Templates fail silently at runtime and obscure intent.\n- `condition: numeric_state` instead of `{{ states('x') | float > N }}`\n- `condition: state` (with `state:` list) instead of `{{ is_state(...) }}` /\n `{{ states(x) in [...] }}`\n- `condition: time` instead of `{{ now().hour ... }}` or `{{ now().weekday() ... }}`\n- `condition: sun` instead of `{{ is_state('sun.sun', ...) }}`\n- Native `for:` field on `state`/`numeric_state` triggers and `state`\n conditions over `{{ now() - X.last_changed > timedelta(...) }}` duration math.\n- `wait_for_trigger` instead of `wait_template`\n- `choose` action instead of template-based service names\n- For one-shot date firing, use a `time` trigger plus `automation.turn_off` on a\n hardcoded entity_id — not `{{ now().date() ... }}`.\n- Hardcode `target.entity_id` literals — never `{{ this.entity_id }}`.\nTemplates are appropriate ONLY in `data.*` fields, notification message/title,\n`event_data`, and `variables`. The reactive best-practice checker on this tool\nwill surface anything in a logic position that should be native; consult the\n`best_practice_warnings` field on the response and fix before re-submitting.\nThe relevant skill section is auto-embedded under `skill_content` on warnings,\nand the full `automation-patterns.md` + `template-guidelines.md` references\nship under `skill_content` proactively by default. For comprehensive\nguidance beyond that, call `ha_get_skill_guide`.\n\nThe returned `automation_id` is the resolved entity_id (canonical\nform, e.g. `automation.morning_routine`) when entity registration\nsucceeds, falling back to the input `identifier` (update path) or\nthe generated `unique_id` from the upsert response (fresh create\nwhen no identifier was passed).\n\nBefore reaching for ``ha_config_set_automation``, consider whether a\ndedicated tool fits the use case better:\n\n- State snapshot of one or more entities (capture-then-replay,\n no trigger needed) -> ha_config_set_scene\n- State-derived value that recomputes when its inputs change\n (template sensor / binary sensor / number / select)\n -> ha_config_set_helper(helper_type='template')\n- Stateful counter / timer / schedule / boolean / etc.\n -> ha_config_set_helper(helper_type='counter' | 'timer' | ...)\n\nSupports two modes: full config replacement OR Python transformation.\n\nWHEN TO USE WHICH MODE:\n- python_transform: RECOMMENDED for edits to existing automations. Surgical updates.\n- config: Use for creating new automations or full restructures.\n\nIMPORTANT: python_transform requires 'identifier' and 'config_hash' from ha_config_get_automation().\n\nPYTHON TRANSFORM EXAMPLES (operate on the fetched config, which uses HA's\ncanonical plural root keys 'triggers'/'actions'/'conditions'):\n- Update action: python_transform=\"config['actions'][0]['data']['brightness'] = 255\"\n- Add trigger: python_transform=\"config['triggers'].append({'trigger': 'state', 'entity_id': 'binary_sensor.motion', 'to': 'on'})\"\n- Remove last action: python_transform=\"config['actions'].pop()\"\n\nCreates a new automation (if identifier omitted) or updates existing automation with provided configuration.\n\nAUTOMATION TYPES:\n\n1. Regular Automations - Define triggers and actions directly\n2. Blueprint Automations - Use pre-built templates with customizable inputs\n\nREQUIRED FIELDS (Regular Automations):\n- alias: Human-readable automation name\n- triggers: List of triggers (time, state, event, etc.)\n- actions: List of actions to execute\n\nREQUIRED FIELDS (Blueprint Automations):\n- alias: Human-readable automation name\n- use_blueprint: Blueprint configuration\n - path: Blueprint file path (e.g., \"motion_light.yaml\")\n - input: Dictionary of input values for the blueprint\n\nOPTIONAL CONFIG FIELDS (Regular Automations):\n- description: Detailed description of the user's intent (RECOMMENDED: helps safely modify implementation later)\n- category: Category ID for organization (use ha_config_get_category to list, ha_config_set_category to create)\n- conditions: Additional conditions that must be met\n- mode: 'single' (default), 'restart', 'queued', 'parallel'\n- max: Maximum concurrent executions (for queued/parallel modes)\n- initial_state: Whether automation starts enabled (true/false)\n- variables: Variables for use in automation\n\nBASIC EXAMPLES:\n\nSimple time-based automation:\nha_config_set_automation(config={\n \"alias\": \"Morning Lights\",\n \"description\": \"Turn on bedroom lights at 7 AM to help wake up\",\n \"triggers\": [{\"trigger\": \"time\", \"at\": \"07:00:00\"}],\n \"actions\": [{\"action\": \"light.turn_on\", \"target\": {\"area_id\": \"bedroom\"}}]\n})\n\nMotion-activated lighting — `for:` on the off-transition replaces action-delay:\nha_config_set_automation(config={\n \"alias\": \"Motion Light\",\n \"triggers\": [\n {\"trigger\": \"state\", \"entity_id\": \"binary_sensor.motion\", \"to\": \"on\", \"id\": \"motion_on\"},\n {\"trigger\": \"state\", \"entity_id\": \"binary_sensor.motion\", \"to\": \"off\",\n \"for\": {\"minutes\": 5}, \"id\": \"motion_off\"}\n ],\n \"actions\": [\n {\"choose\": [\n {\"conditions\": [\n {\"condition\": \"trigger\", \"id\": \"motion_on\"},\n {\"condition\": \"sun\", \"after\": \"sunset\"}\n ],\n \"sequence\": [{\"action\": \"light.turn_on\", \"target\": {\"entity_id\": \"light.hallway\"}}]},\n {\"conditions\": [{\"condition\": \"trigger\", \"id\": \"motion_off\"}],\n \"sequence\": [{\"action\": \"light.turn_off\", \"target\": {\"entity_id\": \"light.hallway\"}}]}\n ]}\n ]\n})\n\nUpdate existing automation:\nha_config_set_automation(\n identifier=\"automation.morning_routine\",\n config={\n \"alias\": \"Updated Morning Routine\",\n \"triggers\": [{\"trigger\": \"time\", \"at\": \"06:30:00\"}],\n \"actions\": [\n {\"action\": \"light.turn_on\", \"target\": {\"area_id\": \"bedroom\"}},\n {\"action\": \"climate.set_temperature\", \"target\": {\"entity_id\": \"climate.bedroom\"}, \"data\": {\"temperature\": 22}}\n ]\n }\n)\n\nBLUEPRINT AUTOMATION EXAMPLES:\n\nCreate automation from blueprint:\nha_config_set_automation(config={\n \"alias\": \"Motion Light Kitchen\",\n \"use_blueprint\": {\n \"path\": \"homeassistant/motion_light.yaml\",\n \"input\": {\n \"motion_entity\": \"binary_sensor.kitchen_motion\",\n \"light_target\": {\"entity_id\": \"light.kitchen\"},\n \"no_motion_wait\": 120\n }\n }\n})\n\nUpdate blueprint automation inputs:\nha_config_set_automation(\n identifier=\"automation.motion_light_kitchen\",\n config={\n \"alias\": \"Motion Light Kitchen\",\n \"use_blueprint\": {\n \"path\": \"homeassistant/motion_light.yaml\",\n \"input\": {\n \"motion_entity\": \"binary_sensor.kitchen_motion\",\n \"light_target\": {\"entity_id\": \"light.kitchen\"},\n \"no_motion_wait\": 300\n }\n }\n }\n)\n\nTRIGGER TYPES: time, time_pattern, sun, state, numeric_state, event, device, zone, template, and more\nCONDITION TYPES: state, numeric_state, time, sun, template, device, zone, and more\nACTION TYPES: action calls, delays, wait_for_trigger, wait_template, if/then/else, choose, repeat, parallel\n\nFor comprehensive automation documentation with all trigger/condition/action types and advanced examples:\n- Use: ha_get_skill_guide\n- Or visit: https://www.home-assistant.io/docs/automation/\n\nTROUBLESHOOTING:\n- Use ha_get_state() to verify entity_ids exist\n- Use ha_search() to find correct entity_ids\n- IF you must use Jinja2 and have no native alternative, test it first with\n ha_eval_template() before embedding it in the automation config — catches\n syntax errors and unresolved entity_ids before they fail silently at runtime\n- Use ha_search(domain_filter='automation') to find existing automations", |
389 | 389 | "inputSchema": { |
390 | 390 | "properties": { |
391 | 391 | "config": { |
392 | | - "type": "Annotated[dict[str, Any] | None, Field(description=\"Complete automation configuration with required fields: 'alias', 'trigger', 'action'. Optional: 'description', 'condition', 'mode', 'max', 'initial_state', 'variables'. Mutually exclusive with python_transform.\", default=None)]", |
| 392 | + "type": "Annotated[dict[str, Any] | None, Field(description=\"Complete automation configuration with required fields: 'alias', 'triggers', 'actions'. Optional: 'description', 'conditions', 'mode', 'max', 'initial_state', 'variables'. Mutually exclusive with python_transform.\", default=None)]", |
393 | 393 | "default": null |
394 | 394 | }, |
395 | 395 | "identifier": { |
396 | 396 | "type": "Annotated[str | None, Field(description='Automation entity_id or unique_id for updates. Required for python_transform. Omit to create new automation with generated unique_id.', default=None)]", |
397 | 397 | "default": null |
398 | 398 | }, |
399 | 399 | "python_transform": { |
400 | | - "type": "Annotated[str | None, Field(description='Python expression to transform existing automation config. Mutually exclusive with config. Requires identifier and config_hash for validation. WARNING: Expressions with infinite loops will hang the server. Examples: Simple: python_transform=\"config[\\'action\\'][0][\\'data\\'][\\'brightness\\'] = 255\" Pattern: python_transform=\"for a in config[\\'action\\']: if a.get(\\'alias\\') == \\'My Step\\': a[\\'data\\'][\\'value\\'] = 100\" \\n\\n' + get_security_documentation())]", |
| 400 | + "type": "Annotated[str | None, Field(description='Python expression to transform existing automation config. Mutually exclusive with config. Requires identifier and config_hash for validation. WARNING: Expressions with infinite loops will hang the server. Examples: Simple: python_transform=\"config[\\'actions\\'][0][\\'data\\'][\\'brightness\\'] = 255\" Pattern: python_transform=\"for a in config[\\'actions\\']: if a.get(\\'alias\\') == \\'My Step\\': a[\\'data\\'][\\'value\\'] = 100\" \\n\\n' + get_security_documentation())]", |
401 | 401 | "default": null |
402 | 402 | }, |
403 | 403 | "config_hash": { |
|
2514 | 2514 | "default": null |
2515 | 2515 | }, |
2516 | 2516 | "attribute_keys": { |
2517 | | - "type": "Annotated[str | list[str] | None, Field(default=None, description='Return only the specified keys from each entity\\'s attributes dict (e.g. [\"brightness\", \"color_temp\"] for lights). None = full attributes (default). Unknown keys are silently dropped. Requires \"attributes\" to be present in fields= (or fields=None).')]", |
| 2517 | + "type": "Annotated[str | list[str] | None, Field(default=None, description='Return only the specified keys from each entity\\'s attributes dict (e.g. [\"brightness\", \"color_temp_kelvin\"] for lights). None = full attributes (default). Unknown keys are silently dropped. Requires \"attributes\" to be present in fields= (or fields=None).')]", |
2518 | 2518 | "default": null |
2519 | 2519 | } |
2520 | 2520 | }, |
|
0 commit comments