Anyone who’s been in the Home Assistant universe for a while might still remember the early days with a slight shudder. Back then, creating automations was a pure text exercise in YAML YAMLData format (YAML Ain’t Markup Language). Used in Home Assistant for configurations, automations and scenes. Easy to read but error-prone with incorrect indentation files. And by that, I don’t mean relaxed configuration — I mean the daily battle against the invisible final boss: the space character.
Welcome to YAML Indentation Hell.
One space too few? Configuration error. One space too many? The system won’t boot. A tab instead of two spaces? Catastrophe! You often felt like a bomb disposal expert, trying with trembling hands to slide the entity_id exactly two spaces under the action block. You’d stare at the screen for hours, doubting your sanity, only to discover that line 42 was a millimeter too far left.
⚠ [affiliate] Keine Produkte mit Cache für home-assistant.
Bitte affiliate-sync --lang en ausführen.
Those who — like me — came from systems like IP-Symcon had it especially hard. I used to be an absolute “PHP guy.” So in the Symcon world, I could easily just program even the most complex automations because I spoke the language.
In Home Assistant, however, you initially felt lost in a text desert, painfully missing a real scripting language and needing Zen-Buddhist patience just to turn on the hallway light via a motion sensor in the dark. More extensive automations were only possible directly in YAML.
Fortunately, Home Assistant has evolved massively. The graphical automation editor has become powerful and takes this Sisyphean task off your hands. In parallel, Node-RED Node-REDVisual programming environment for flows. Often used as a Home Assistant add-on to create complex automations graphically via drag & dropRead more → has established itself as the quasi-standard for complex workflows, and for coders, there’s PyScript PyScriptEnables writing Home Assistant automations in Python instead of YAML. Provides more flexibility for complex logic with loops and conditionsRead more → — a powerful Python integration.

But when do you use which tool? I’ve looked at the three most common methods and compare their pros and cons.
The Scenario: Light On with Motion
To make the approaches comparable, we’ll use an absolutely classic example found in almost every household: A motion sensor in the hallway should turn on a lamp, but only when it’s dark enough (brightness < 20 lux). When no more motion is detected, the light should turn off again.
1. Native Home Assistant Automations
The built-in engine has matured enormously in recent years. What used to be tedious YAML hacking can now be almost entirely clicked together via the user interface ( UI UIUser Interface – the visible surface of software (windows, menus, buttons). In HA: the dashboard (Lovelace), settings and the add-on store ). Home Assistant still writes the YAML in the background, but you no longer have to look at it — and most importantly, you no longer have to manually indent it.
The flow is linear: Trigger TriggerTrigger of a Home Assistant automation – the event that starts the flow (e.g. sunset, sensor value, time). First building block of every automation (motion detected) -> Condition (only when dark) -> Action (light on) -> Trigger (motion) no motion detected -> Delay wait 5 minutes -> Action light off
Even though you mostly click today, it’s worth looking at the code that’s generated in the background to understand the structure:
|
|
That’s solid, readable, but even with this simple logic you can see why it can become confusing with more complex nesting — and we haven’t even defined the “off” automation after, say, 5 minutes that would also survive a Home Assistant reboot — so no simple delay.

A huge advantage of native automations is the trace function. You can visually and interactively track why an automation triggered — or why it didn’t. This is worth its weight in gold for troubleshooting and, in my opinion, is now better solved than debugging in many other tools.
Advantages:
- Deeply integrated: No additional software needed, Home Assistant updates cover everything.
- Performance: Since it runs directly in the core, latency is minimal.
- Debugging: The trace timeline is excellent for error analysis.
- Blueprints: You can use ready-made templates from the community without reinventing the wheel.
Disadvantages:
- Complexity with branching: As soon as you need nested “if-then” logic or loops, the UI quickly becomes confusing.
- YAML knowledge: For very specific things (templates), you end up back in the code editor — but at least usually only as one-liners.
2. Node-RED
For many, Node-RED is the holy grail of home automation. It’s a visual programming tool where you connect “nodes” with wires. It usually runs as an add-on alongside Home Assistant.
For visual types, this is a blessing. You can literally see the flow of data. Our example here would be a chain of: Event State Node (motion) -> Switch Node (brightness check) -> Call Service Node (light on).
Node-RED plays to its strengths when the logic becomes complex. When data needs to be fetched from an API APIApplication Programming Interface – defined interface through which programs communicate. Home Assistant offers a REST and a WebSocket API (e.g. for MCP) , reformatted, filtered, and then sent to three different services, Node-RED can often be clicked together in just a few minutes. In YAML, that would be a nightmare you’d wake up from drenched in sweat.

A perfect example of this is my project where I made our door camera smarter . When the doorbell rang, the TV had to be turned on, switched to the right HDMI input, and the camera image displayed. Such chains of different protocols (HDMI-CEC, MQTT MQTTLightweight publish/subscribe messaging protocol. Used in smart homes to exchange sensor data and control commands between devices , camera streams) are Node-RED’s specialty.
However, Node-RED introduces another layer of complexity. It’s a standalone system that needs to be maintained. If the add-on fails, the lights stay off even though Home Assistant is still running. It also tempts you to build huge “spaghetti monsters” — confusing cable-clutter flows that you yourself won’t understand after three months. Plus, you can get lost in the vast selection of custom nodes, and it’s often a challenge just to find the right node.
Advantages:
- Visual overview: Data flows are intuitively graspable.
- Powerful: Enormous library of “palettes” (extensions) for almost every use case.
- Flexibility: Ideal for complex logic and data manipulation.
Disadvantages:
- Additional maintenance: Another system that needs to be maintained.
- Overhead: For simple “light on/off” tasks, often like using a sledgehammer to crack a nut.
- Separation: The logic lives outside the actual Home Assistant configuration (mind your backup strategy!).
Here are a few node recommendations for NodeRed nonetheless. The first 3 make many complex tasks much easier:
- node-red-contrib-bigtimer — Powerful timer functions. Can handle sunrise/sunset (with offset), holidays, manual overrides, and even output MQTT text. Perfect for shutter and light control.
- node-red-contrib-cron-plus — Supports CRON syntax and dynamic creation of schedules at runtime.
- node-red-contrib-boolean-logic-ultimate — Saves you from huge “switch” cascades or complex if/else blocks in function nodes. Offers AND, OR, XOR gates. Example: “Light on only IF (motion detected) AND (it’s night) AND (NOT TV is on).” It also stores states persistently across restarts.
- node-red-contrib-looptimer-advanced — For making things blink or repeating notifications (“Garage is still open!”) until someone responds.
- node-red-contrib-influxdb — Write directly to InfluxDB.
- node-red-contrib-zigbee2mqtt — Access zigbee2mqtt.
- node-red-contrib-huemagic — Very powerful palette for Philips Hue. Offers more options (e.g., dynamic scenes, “Color Loop”) than the standard HA entities.
3. PyScript (Python) — The AppDaemon Killer?
For a long time, AppDaemon was the undisputed top dog for anyone who wanted more power than YAML could offer. Don’t get me wrong, AppDaemon is powerful and has its reason for existing (especially for complex dashboards) — but it’s also “its own beast.” It runs as a separate instance alongside Home Assistant, needs extra configuration, requires its own connection setup, and often feels unnecessarily complicated when you just want to “quickly” write an intelligent script.
Here comes PyScript, and for me, it’s the much leaner and more charming alternative. PyScript doesn’t run alongside but essentially inside Home Assistant. You save the overhead of a separate application. You have direct access to all entities as if they were native Python variables.
PyScript is installed via HACS HACSHome Assistant Community Store – unofficial marketplace for integrations, add-ons and custom dashboards from the community , and you store the scripts in the /config/pyscript/ folder.
Now, I’ve always worked in the realm of C-like programming languages — PHP, C, C++, JS, or C#. Here, structures are formed with curly braces, and indentation is useful for readability but doesn’t change functionality. My adjustment to Python was quite significant. However, Python rewards you with enforced, highly readable, and very elegant code that any tech-savvy and willing-to-learn Home Assistant fan can learn.
Let’s look at our light scenario in PyScript. Here’s what the same logic looks like when programmed:
Python
|
|
Or without comments:
|
|
This is extremely clean, short, and readable — provided you know Python. Thanks to the variables at the beginning, you can very easily reuse the code by simply swapping out the entities. PyScript becomes particularly exciting for two topics that are becoming increasingly important:
- AI and AI applications: Python is the lingua franca of artificial intelligence. If you want to call the OpenAI API, use LangChain, or feed data to a local LLM LLMLarge Language Model – AI model trained on vast amounts of text that can understand and generate natural language. Examples: GPT-4, Claude, Gemini, DeepSeek. Foundation for chatbots like ChatGPT and GitHub Copilot to control your heating truly intelligently, this is the place. In PyScript, you simply import the relevant libraries and you’re ready to go. In AppDaemon’s often isolated environment, integrating external libraries is often quite a hassle. PyScript sits right at the source.
- “Light” data persistence: Sometimes you want to store values that survive a restart. Normally, you clutter your Home Assistant instance with countless helper entities (input_text, input_number, input_boolean) for this. For every value you want to remember, a helper must be created. This unnecessarily bloats the entity list and makes the system sluggish. With PyScript, you save yourself this material battle. You simply use standard Python functions (open(), write()) to write data to a local text or JSON file in the config folder.
- Vibe Coding : Excellent coding support through AI tools. ChatGPT, Gemini, Claude ClaudeAI assistant by Anthropic (Sonnet, Opus, Haiku models). Uses MCP natively – Claude Desktop was one of the first MCP clients and can access your HA server directly , etc. “speak” Python best and can immediately deliver runnable suggestions or help with debugging. With YAML, the tools regularly fail as soon as automations become more complex. Plus, there’s a huge amount of Python libraries you can use.
Advantages:
- Simpler than AppDaemon: no separate instance, no connection overhead, no boilerplate code
- AI-Ready: Perfect environment for integrating modern AI libraries.
- No helper flood: Data is stored in files instead of having to create dozens of helper entities.
- Compact: Lots of logic in little space.
- VSCode: With the VSCode Editor as an addon , you get plenty of coding support (and proper indentation).
Disadvantages:
- Learning curve: Without Python knowledge, you’re facing a wall.
- Coding: Requires a “developer mindset.” Without any coding experience, it gets difficult.
- No UI: Code remains code — there’s nothing to click here.
- VSCode: … you should learn that too
The Comparison at a Glance
| Feature | Native Automation AutomationRule-based workflow in Home Assistant: triggers, conditions and actions automatically execute a flow (e.g. turn on lights at sunset) | Node-RED | PyScript |
|---|---|---|---|
| Entry Barrier | Low | Medium | High (Python knowledge) |
| Visualization | UI / Traces | Flow-Chart | None (Code) |
| Debugging | Excellent (Traces) | Good (Debug Node) | Log-Files |
| Maintenance Effort | Minimal | Medium ( Add-on Add-onAdditional software package for Home Assistant OS/Supervised, installed via the add-on store (renamed to ‘Apps’ in newer HA versions). Runs as its own container alongside core – e.g. the SSH add-on ) | Minimal (Text files) |
| Complexity | Quickly becomes confusing | Well structurable | Perfect for AI & complex logic |
| Architecture | Native Core | Separate Container | Integrated (simpler than AppDaemon) |
Reality Check: Where the Methods Hit Their Limits
Theory is good, practice is better. To understand why you should know (or at least understand) all three tools, let’s look at examples where the other approach fails or is simply no fun.
1. The Standard Case: Motion Sensor & Light
Winner: Native Automation
You could build this in Node-RED. You could write a Python script for it (see above). But why?
For a simple “motion on = light on” logic, PyScript is absolute overkill. You don’t bring out the big toolbox with programming language, file handling, and imports just to flip a switch. That’s using a sledgehammer to crack a nut.
Node-RED is also actually unnecessary here: If the Node-RED container hangs during an update, you’re standing in the dark. Native automations are more robust here, quicker to create, and require zero maintenance.
2. The “Webhook Parser”: Data from External Sources
Winner: Node-RED
Imagine a complex JSON object coming in via webhook from an external service (e.g., a non-integrated solar system or a DIY sensor). You need to break down this JSON, extract three values, check if value A is greater than value B, and then send the result via MQTT payload in separate topics.
- Native Automation: This ends in “Jinja2 template hell.” Anyone who’s ever tried to parse nested JSON in YAML templates knows what I’m talking about. It’s unreadable and error-prone.
- PyScript: Possible, but you first have to “catch” the webhook in Python.
- Node-RED: A dream. An
http-innode, afunctionnode (orchangenode), MQTT-send-node, and done. You can visually see where the data flows.
3. The “Mathematician”: Dynamic Heating Curves & Arrays
Winner: PyScript
The goal: Build a dynamic heating control that doesn’t just take the outside temperature, but goes through a list of the last 24 hours of values, calculates the average, removes outliers, factors in the sun’s position, and writes this value to a file to use as a reference tomorrow.
- Native Automation: Nearly impossible, or a construct of 20 helper entities and endless template sensors.
- Node-RED: You end up in a
functionnode where you… write JavaScript. So if you have to code anyway, why not do it in a proper environment? - PyScript: This is where Python plays to its strengths. Iterating lists, using statistical functions, writing files — that’s 10 lines of clean, readable code without helper chaos.
Conclusion and Recommendation
There is no “better” or “worse,” there’s only the right tool for the respective job.
I’ve personally evolved over the years. Initially, I outsourced a lot externally, simply to escape YAML hell. Nowadays, I follow the approach: As native as possible.
- Standard automations: I handle lights, heating, and simple notifications 90% with native Home Assistant automations. The UI is now so good and the traces so helpful that there’s no reason to fire up an external engine for this.
- Data processing & APIs: When JSON data needs to be parsed from a website or complex linkages are needed that are hard to represent in the UI, Node-RED is the tool of choice.
- AI, mathematics & storage: When calculations need to be made, data needs to be quickly written to a file (without helper chaos), or AI needs to be integrated into the smart home, PyScript is the royal road. It’s easier than AppDaemon and feels “closer” to the system.
My advice: Start with the built-in tools. Only when you hit hard limits there or notice that the automation is becoming unreadable should you look toward Node-RED. And if you know Python? You should check out PyScript — it could become a new love. And if you don’t know Python? The possibilities and elegance of PyScript might give you a compelling reason to dive into it.
What do you think? Leave a comment!
Share your thoughts, questions or experiences with the community.