A HACS integration that enables programming Home Assistant automations in Structured Text (IEC 61131-3) - the language used in industrial PLCs like TwinCAT and Siemens controllers.
ST for Home Assistant transpiles Structured Text code into native Home Assistant automations, bringing industrial control logic patterns to home automation without any runtime overhead.
- Industrial PLC Language: Write automations using Structured Text (IEC 61131-3)
- Native HA Automations: Code is transpiled to standard HA automations (no interpreter)
- Event-Driven: Automatic trigger generation from entity dependencies
- State Persistence: Smart helper management for stateful variables
- Built-in Safety: Loop guards and defensive Jinja generation
- Timer Support: TON, TOF, TP function blocks using HA timer entities
- Live Editor: CodeMirror 6-based editor with syntax highlighting and autocomplete
- Complete Parser: Full Chevrotain-based parser supporting all IEC 61131-3 ST features
- Online Mode: Real-time entity value display in the editor
- Transactional Deploy: Atomic deployment with backup and rollback support
Current Version: 2.0.0
Status: Stable, Ready for Production Use
| Component | Tests | Status |
|---|---|---|
| Parser | 25 | ✅ Passing |
| Dependency Analyzer | 16 | ✅ Passing |
| Storage Analyzer | 23 | ✅ Passing |
| Transpiler | 24 | ✅ Passing |
| Deploy/Helper Manager | 5 | ✅ Passing |
| Restore/Migration | 20 | ✅ Passing |
| Online Mode | 10 | ✅ Passing |
| Error Mapping | 10 | ✅ Passing |
| Source Maps | 11 | ✅ Passing |
| Total | 194 | ✅ 100% Passing |
- TypeScript: ✅ Passing (strict mode)
- ESLint: ✅ Passing (0 errors)
- Bundle Size: 214 KB (gzipped, initial load) with code splitting
- Open HACS in your Home Assistant instance
- Click on "Integrations"
- Click the three dots in the top right corner
- Select "Custom repositories"
- Add this repository URL:
https://github.com/Auda29/ST_HA_Automation - Select "Integration" as the category
- Click "Install" on the ST for Home Assistant card
- Restart Home Assistant
- Download the latest release from the releases page
- Copy the
custom_components/st_hassfolder to your Home Assistantcustom_componentsdirectory - Restart Home Assistant
After installation, a new "ST Editor" panel will appear in your Home Assistant sidebar.
{mode: restart}
{throttle: T#1s}
PROGRAM Kitchen_Light
VAR
{trigger}
motion AT %I* : BOOL := 'binary_sensor.kitchen_motion';
light AT %Q* : BOOL := 'light.kitchen';
{persistent}
activationCount : INT := 0;
END_VAR
IF motion THEN
light := TRUE;
activationCount := activationCount + 1;
ELSE
light := FALSE;
END_IF;
END_PROGRAM
This creates an automation that:
- Triggers on motion sensor state changes (max once per second)
- Controls the kitchen light based on motion
- Counts activations persistently using an HA helper
BOOL- Boolean values (mapped to entity on/off states)INT,DINT,LINT,SINT- Integer values with various bit widthsREAL,LREAL- Floating point valuesSTRING,WSTRING- Text valuesTIME,DATE,TIME_OF_DAY,DATE_AND_TIME- Time-related types
IF/ELSIF/ELSE/END_IF- Conditional branchingCASE...OF/END_CASE- Multi-way branching with rangesFOR...TO...BY...DO/END_FOR- Counted loopsWHILE...DO/END_WHILE- Pre-condition loopsREPEAT...UNTIL/END_REPEAT- Post-condition loopsEXIT,RETURN- Loop/function control
VAR- Local variablesVAR_INPUT- Input variables (entity reads)VAR_OUTPUT- Output variables (entity writes)VAR_IN_OUT- Bidirectional variablesVAR_GLOBAL- Global variables (shared across programs)
AT %I*- Input entity binding (sensors, binary sensors)AT %Q*- Output entity binding (lights, switches, services)AT %M*- Memory/helper binding
| Pragma | Description |
|---|---|
{trigger} |
Entity change triggers automation |
{no_trigger} |
Entity is read but doesn't trigger |
{persistent} |
Value stored in HA helper |
{transient} |
Value only during run (default) |
{reset_on_restart} |
Always use initial value after HA restart |
{require_restore} |
Error if no stored value exists |
{mode: restart|single|queued|parallel} |
Script execution mode |
{throttle: T#duration} |
Rate limiting |
{debounce: T#duration} |
Debouncing |
R_TRIG- Rising edge detectionF_TRIG- Falling edge detectionSR/RS- Set-Reset flip-flopsTON- On-delay timerTOF- Off-delay timerTP- Pulse timer
- Selection:
SEL,MUX - Limits:
LIMIT,MIN,MAX - Math:
ABS,SQRT,TRUNC,ROUND - Conversion:
TO_INT,TO_DINT,TO_REAL,TO_LREAL,TO_STRING,TO_BOOL
- Arithmetic:
+,-,*,/,MOD - Comparison:
=,<>,<,<=,>,>= - Logical:
AND,OR,XOR,NOT
Detailed documentation is available in the docs folder:
- Project Overview - Architecture, design decisions, MUST-DO's and MUST-NOT-DO's
- Product Requirements Document - Comprehensive specifications and implementation details
- Agents Documentation - Agent-based development workflow
- Agent Tasks - Task list and status tracking
- Repository Setup - Initial project structure
- CodeMirror Integration - Editor implementation
- Parser Implementation - Chevrotain parser
- Dependency Analyzer - Trigger generation
- Storage Analyzer - Persistence detection
- And more in the archive folder
ST for Home Assistant uses a compile-time transpilation approach:
┌─────────────────────────────────────────────────────────────────────────┐
│ ST for Home Assistant Pipeline │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ST Code Editor Parser Analyzers Transpiler │
│ (CodeMirror 6) (Chevrotain) (Dependency) (AST → YAML) │
│ (Storage) │
│ ↓ ↓ ↓ ↓ │
│ Editor UI AST Nodes Analysis HA Automation │
│ Results + Script Config │
│ + Helpers │
│ ↓────────────────────────────────┘ │
│ ↓ │
│ Deploy Manager │
│ (Backup/Restore/Rollback) │
│ ↓ │
│ Home Assistant │
│ (WebSocket API) │
└─────────────────────────────────────────────────────────────────────────┘
| Component | Description |
|---|---|
| Lexer/Parser | Chevrotain-based parser with full IEC 61131-3 ST support |
| Dependency Analyzer | Extracts entity dependencies and generates triggers |
| Storage Analyzer | Determines which variables need persistent helpers |
| Transpiler | Converts ST logic to Home Assistant YAML/Jinja2 |
| Timer Transpiler | Handles TON/TOF/TP using HA timer entities |
| Deploy Manager | Transactional deployment with backup and rollback |
| Helper Manager | Synchronizes helpers with code requirements |
| Source Mapper | Maps YAML paths back to ST source lines |
| Error Mapper | Translates HA errors to ST context |
| Online Mode | Real-time entity state display in editor |
- Node.js 20+
- npm 10+
- Python 3.12+
- Home Assistant development environment (optional)
# Clone repository
git clone https://github.com/Auda29/ST_HA_Automation.git
cd ST_HA_Automation
# Install frontend dependencies
cd frontend
npm install
# Build frontend
npm run build
# Watch mode for development
npm run build:watchcd frontend
# Type checking
npm run typecheck
# Linting
npm run lint
npm run lint:fix # Auto-fix issues
# Unit tests
npm test # Watch mode
npm run test:run # Single runST_HA_Automation/
├── custom_components/st_hass/ # Python backend
│ ├── __init__.py # Integration setup
│ ├── config_flow.py # Configuration UI
│ ├── const.py # Constants
│ └── frontend/ # Built frontend files
├── frontend/ # TypeScript frontend
│ ├── src/
│ │ ├── editor/ # CodeMirror editor
│ │ ├── parser/ # Chevrotain parser
│ │ ├── analyzer/ # Dependency & storage analysis
│ │ ├── transpiler/ # ST → HA YAML conversion
│ │ ├── deploy/ # Deployment & helper management
│ │ ├── online/ # Live value updates
│ │ ├── restore/ # Migration & restore
│ │ ├── error-mapping/ # Error translation
│ │ ├── sourcemap/ # Source map generation
│ │ └── panel/ # Main UI panel
│ ├── package.json
│ ├── tsconfig.json
│ └── vite.config.ts
├── docs/ # Documentation
└── tests/ # Integration tests
Contributions are welcome! Please:
- Read the Project Overview to understand design decisions
- Review the PRD for detailed specifications
- Check archived documentation for implementation details
- Follow the existing code style (TypeScript + Lit)
- Add tests for new features
- Update documentation as needed
The codebase, tests, UI strings, and README are maintained in English. See docs/language_policy.md for details.
This project uses an agent-based development workflow with specialized roles:
- Taskmaster: Plans tasks, assigns work, monitors progress
- Dev1 (Core): Implements core business logic
- Dev2 (Integration): Builds APIs, UI, integrations
- Testing: Writes and executes tests
- Review: Reviews code quality
- DevOps: Handles merges and deployment
See Agents Documentation for details.
The project follows strict guidelines documented in 00_Project_Overview.md:
- Cycle → Event transformation via dependency analysis
- State persistence with tiered storage strategy
- Defensive Jinja generation for null-safety
- Loop safety guards with iteration limits
- Script mode: restart as default
- Transactional deploy with rollback
- Source maps for debugging
- Timer as entity + event pattern
- Deploy via HA APIs only (no file manipulation)
- Throttle helper initialization with fallback
- No polling/cycle-time patterns
- No helper explosion
- No mode: single for logic scripts
- No naive Jinja without null checks
- No infinite loops without safety
- No hardcoded entity IDs
- No deploy without backup
- No direct HA API without abstraction
- No direct YAML file manipulation
- No unchecked throttle templates
MIT License - See LICENSE file for details
- Inspired by industrial PLC programming (TwinCAT, Siemens, etc.)
- Parser built with Chevrotain
- Editor powered by CodeMirror 6
- UI components using Lit
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: docs folder