YCZNWL KNX Gateway Automation Agent Skill
Connection
| Parameter | Default | Description |
|-----------|---------|-------------|
| Base URL | http://ycznwl.local/api/v1 | Default mDNS address — use as-is unless the user provides their own gateway address or IP |
| Auth | Authorization: Bearer ${KNX_TOKEN} | See token instructions below |
| Encoding | UTF-8 | The gateway accepts and emits UTF-8 only. Always send Content-Type: application/json; charset=utf-8 and decode responses as UTF-8. Names, descriptions, room names, action names, and any free-text fields may contain Chinese characters and must be transmitted/parsed as UTF-8. Do not URL-encode JSON payloads or wrap them in an extra encoding layer. |
Getting an API Token
- Open the KNX Gateway web UI
- Click your avatar (top-right) → Get API Token
- Copy the token
Safe token handling:
- Store the token in your platform's secret store or a local environment variable (
export KNX_TOKEN=...) — never paste it directly into a chat conversation, as conversation logs may be persisted - Reference it in requests via the environment variable, not inline
- Never hardcode the token in shared scripts or commit it to version control
This skill's only required credential is KNX_TOKEN. Optional workflow nodes that
send data outside the gateway or trusted LAN must be configured only after an
explicit user request and endpoint review. Do not introduce hardcoded secrets
into skill files or workflow examples.
Default safety policy: keep automations local to the gateway and trusted LAN. Only author or enable off-LAN HTTP, MQTT, webhook, or email integrations when the user explicitly asks for that integration and approves the exact endpoint.
Reference Documents
This skill is organized into progressive reference files. Read them in order when you need detailed information:
| File | Content |
|------|---------|
| ref/devices.md | Device types, subtypes, capabilities, actions, params |
| ref/scenes.md | Scene data model, actions structure, KNX binding, execution behavior |
| ref/triggers.md | Trigger types and their exact configuration (incl. sun_event with offset scheduling) |
| ref/nodes.md | Node types, subtypes (incl. scene_exec, schedule_match with sunrise/sunset boundaries), config structs, validation rules |
| ref/api.md | Complete REST API endpoint reference (devices, scenes, automation, system location/sun times) |
| ref/examples.md | Realistic, validated workflow examples (incl. scene-based) |
Quick Start — Agent Workflow
Creating a new scene
- Discover devices:
GET /devices→ noteuuid,name,type,capabilities, androom_id(resolve viaGET /rooms) - Build actions array: Each action targets a device:
{ "id": "a1", "device_uuid": "light-uuid", "device_name": "Living Room Light", "action": "turn_off", "params": {}, "delay": 0 }action+paramsmust match the device's capability (see ref/devices.md)delayis in milliseconds (0 = immediate, 500 = 0.5s delay before this action)idis a unique string per action (e.g."a1","a2")
Scene authoring best practices
- Brightness implies power on (dimmable lights only): For lights with brightness control
(
light_dimmer,light_tunable,light_rgb), sendingset_brightnesswithbrightness > 0automatically powers the light on at the firmware/handler level. Do not emit a separateturn_onaction beforeset_brightness— it adds latency and a redundant KNX telegram. Sendingset_brightnesswithbrightness: 0will likewise turn the light off. Use an explicitturn_on/turn_offonly when the device has no brightness capability. - Multi-room scenes — prefix
device_namewith the room name: When a scene spans multiple rooms, prepend the room name to the action's display name so the execution log and UI are readable. Example:"device_name": "客厅·主灯"instead of just"主灯". Single-room scenes may keep the bare device name. The room name comes fromGET /roomsjoined ondevice.room_id. This applies to both scene actions (actions[].device_name) and anynameyou set on automationdevice_control/scene_execaction nodes. - Color temperature range: Devices can be configured for any range within
1000–10000 Kwith a configurable step. The backend clamps & step-aligns values automatically — but pass reasonable values that the user has actually configured for the device.
- Create:
POST /sceneswithname,actions, optionalicon,color,description,enabled - Test:
POST /scenes/:uuid/execute→ verify execution result
Editing an existing scene
- Get current state:
GET /scenes/:uuid - Update:
PUT /scenes/:uuidwith partial fields:Only include fields you want to change. The{ "name": "Updated Scene Name", "actions": [ ... ], "enabled": true }actionsarray replaces the existing one entirely. - Test:
POST /scenes/:uuid/execute
Managing scenes
| Operation | Method | Endpoint |
|-----------|--------|----------|
| List all scenes | GET | /scenes (optional ?enabled=true) |
| Get scene | GET | /scenes/:uuid |
| Create | POST | /scenes |
| Update | PUT | /scenes/:uuid |
| Delete | DELETE | /scenes/:uuid |
| Execute | POST | /scenes/:uuid/execute |
| Toggle enabled | POST | /scenes/:uuid/toggle |
| Reorder | PUT | /scenes/sort |
| View logs | GET | /scenes/logs?scene_uuid=xxx |
See ref/api.md for full request/response details.
Using scenes in automations
Scenes can be triggered from automation workflows in two ways:
scene_execnode (recommended):{ "node_subtype": "scene_exec", "config": { "scene_uuid": "..." } }device_controlnode with virtual device:{ "config": { "device_uuid": "scene-<scene_uuid>", "action": "activate_scene" } }
See ref/examples.md Examples 7 & 8 for complete workflow payloads.
Creating a new automation
- Discover devices:
GET /devices→ noteuuid,type,sub_type,capabilities - Discover scenes (if needed):
GET /scenes→ note sceneuuidforscene_execnodes - Build import JSON using the format documented in ref/api.md section "Import"
- Import:
POST /automation/workflows/import→ returns new workflow with server-generated UUIDs - Validate:
POST /automation/workflows/:uuid/validate - Enable:
POST /automation/workflows/:uuid/enable
Manually executing an automation — REQUIRES a manual trigger
POST /automation/workflows/:uuid/execute can only fire enabled triggers of type
manual. If the workflow has no manual trigger (e.g. only device_event, cron,
sun_event, knx_group_event, or webhook triggers), the call returns
no enabled manual trigger found in workflow ... and nothing executes.
Rule: If the user wants the workflow to be runnable on demand from the UI or via the
API (e.g. a "test" button, a chatbot command, a script), include at least one
{ "trigger_type": "manual", "enabled": true } trigger in the import JSON. You may combine
it with other triggers — they remain independent.
{
"triggers": [
{ "uuid": "t-manual", "trigger_type": "manual", "enabled": true, "config": {} },
{ "uuid": "t-cron", "trigger_type": "cron", "enabled": true, "config": { "expression": "0 7 * * *" } }
]
}
A workflow without a manual trigger still runs automatically when its other triggers fire —
it just cannot be invoked through POST /workflows/:uuid/execute.
Editing an existing automation
- Get current state:
GET /automation/workflows/:uuid - Modify triggers/nodes/edges — keep existing UUIDs for unchanged elements, generate new UUIDs for additions
- Save:
PUT /automation/workflows/:uuid - Validate:
POST /automation/workflows/:uuid/validate
Security Notes
- Imported workflows: Always inspect imported workflow JSON before enabling. Look for unexpected off-LAN HTTP requests, MQTT brokers outside the trusted LAN, or webhook triggers exposed beyond the gateway network. Only import workflows from sources you trust.
- Network egress: Prefer gateway-local and LAN-local workflows. HTTP request, MQTT publish, webhook, and email integrations are advanced gateway features; use them only when the user explicitly asks and the destination is reviewed.
- Webhook triggers: Exposing a webhook URL can make the gateway reachable from outside its normal network. Use only when network exposure is deliberate and the token is kept secret.
- Base URL: Verify the gateway address resolves to your local network before running any control commands.
Critical Rules
-
Device actions are NOT generic "set" or "toggle". Each device type has specific actions. Always check ref/devices.md for the exact action name and required params for each device type/subtype combination.
-
UUIDs on import are placeholders. The server remaps ALL UUIDs. Use simple placeholder values like
"t1","n1","e1"— the server will replace them with real UUIDs. -
Imported workflows start in
draft+disabledstate. Always validate then enable after import. -
Node configs are strictly typed. A
device_controlnode with wrong params will fail at execution time even if import succeeds. Always match action + params to the device's capability. -
Edge handle names: Triggers use
source_handle: "output". Condition/logic nodes use"true"and"false"as source_handle. Action, delay, and transform nodes usesource_handle: "output". All target handles are"input". -
source_typein edges: Use"trigger"when source is a trigger UUID, use"node"when source is any node UUID.
Common Pitfalls (MUST READ)
Pitfall 1: node_subtype vs sub_type — DIFFERENT fields!
- Devices use
sub_type(e.g."sub_type": "light_dimmer") - Nodes use
node_subtype(e.g."node_subtype": "device_control") - If you use
sub_typein a node definition, it will be silently ignored. The node will have an empty subtype and validation will report "未知节点类型 action:" (unknown node type). Always usenode_subtypefor nodes.
Pitfall 2: Validate response — check errors array, NOT just valid
The /validate endpoint may return "valid": true even when errors is non-empty.
Node config errors (e.g. missing subtype, wrong params) appear in errors but do not
flip valid to false. Always check the errors array is null or empty.
✗ BAD: if response.data.valid == true → proceed
✓ GOOD: if response.data.valid == true AND response.data.errors is null/empty → proceed
Pitfall 3: After import, verify the response data
Always inspect the import response body. Confirm that:
node_subtypefields are non-empty for action nodessource_handle/target_handlehave the expected valuesconfigobjects contain the correct action/params
If any field is missing or empty, the import JSON had a wrong field name.
System Limits
| Limit | Value | |-------|-------| | Max workflows | 200 | | Max nodes per flow | 50 | | Max edges per flow | 200 | | Max triggers per workflow | 5 | | Timeout range | 5–3600 seconds | | Max parallel | 10 | | Max retry count | 5 | | Max name length | 128 chars | | Max description length | 1024 chars |
Retrieve current limits: GET /automation/limits
Scan to join WeChat group