Skip to main content

HASSL: Home Assistant Simple Scripting Language

Project description

HASSL

Home Assistant Simple Scripting Language

Version

HASSL is a human-friendly domain-specific language (DSL) for building loop-safe, deterministic, and composable automations for Home Assistant.

It compiles lightweight .hassl scripts into fully functional YAML packages that plug directly into Home Assistant, replacing complex automations with a clean, readable syntax.


🚀 Features

  • Readable DSL → write logic like natural language (if motion && lux < 50 then light = on)
  • Sync devices → keep switches, dimmers, and fans perfectly in sync
  • Schedules → declare time-based gates (enable from 08:00 until 19:00)
  • Weekday/weekend/holiday schedules → full support for Home Assistant’s Workday integration (v0.3.1)
  • Loop-safe → context ID tracking prevents feedback loops
  • Per-rule enable gatesdisable rule or enable rule dynamically
  • Inline waitswait (!motion for 10m) works like native HA triggers
  • Color temperature in Kelvinlight.kelvin = 2700
  • Modular packages/imports → split automations across files with public/private exports
  • Auto-reload resilience → schedules re-evaluate automatically on HA restart

🧰 Example

Basic standalone script

alias light  = light.wesley_lamp
alias motion = binary_sensor.wesley_motion_motion
alias lux    = sensor.wesley_motion_illuminance

schedule wake_hours:
  enable from 08:00 until 19:00;

rule wesley_motion_light:
  schedule use wake_hours;
  if (motion && lux < 50)
  then light = on;
  wait (!motion for 10m) light = off

rule landing_manual_off:
  if (light == off) not_by any_hassl
  then disable rule wesley_motion_light for 3m

Produces a complete Home Assistant package with:

  • Helpers (input_boolean, input_text, input_number)
  • Context-aware writer scripts
  • Sync automations for linked devices
  • Rule-based automations with schedules and not_by guards

Using imports across packages

# packages/std/shared.hassl
package std.shared

alias light  = light.wesley_lamp
alias motion = binary_sensor.wesley_motion_motion
alias lux    = sensor.wesley_motion_illuminance

schedule wake_hours:
  enable from 08:00 until 19:00;
# packages/home/landing.hassl
package home.landing
import std.shared.*

rule wesley_motion_light:
  schedule use wake_hours;
  if (motion && lux < 50)
  then light = on;
  wait (!motion for 10m) light = off

rule landing_manual_off:
  if (light == off) not_by any_hassl
  then disable rule wesley_motion_light for 3m

This setup produces:

  • One shared package defining reusable aliases and schedules
  • A landing package importing and reusing those exports

Together, they generate:

  • ✅ Shared schedule sensor (binary_sensor.hassl_schedule_std_shared_wake_hours_active)
  • ✅ Cross-package rule automations gated by that schedule
  • ✅ Context-safe helpers and syncs for both packages

🏗 Installation

git clone https://github.com/adanowitz/hassl.git
cd hassl
pip install -e .

Verify:

hasslc --help

⚙️ Usage

  1. Create a .hassl script (e.g., living_room.hassl).
  2. Compile it into a Home Assistant package:
    hasslc living_room.hassl -o ./packages/living_room/
    
  3. Copy the package into /config/packages/ and reload automations.

Each .hassl file compiles into an isolated package — no naming collisions, no shared helpers.


📦 Output Files

File Description
helpers_<pkg>.yaml Defines all helpers (booleans, text, numbers)
scripts_<pkg>.yaml Writer scripts with context stamping
sync_<pkg>_*.yaml Sync automations for each property
rules_bundled_<pkg>.yaml Rule logic automations + schedules
schedules_<pkg>.yaml Time/sun-based schedule sensors (v0.3.1)

🧠 Concepts

Concept Description
Alias Maps short names to HA entities (alias light = light.kitchen)
Sync Keeps multiple devices aligned across on/off, brightness, etc.
Rule Defines reactive logic with guards, waits, and control flow.
Schedule Defines active time windows, reusable across rules.
Tag Lightweight metadata stored in input_text helpers.

🔒 Loop Safety & Context Tracking

HASSL automatically writes the parent context ID into helper entities before performing actions.
This ensures not_by any_hassl and not_by rule("name") guards work flawlessly, preventing infinite feedback.


🕒 Schedules That Survive Restarts

All schedules are restart-safe:

  • binary_sensor.hassl_schedule_<package>_<name>_active automatically re-evaluates on startup.
  • Clock and sun-based windows update continuously through HA’s template engine.
  • Missed events (like mid-day restarts) are recovered automatically.

🗓️ Holiday & Workday Integration (v0.3.1)

HASSL now supports holidays <id>: schedules tied to Home Assistant’s Workday integration.

To enable holiday and weekday/weekend-aware schedules:

1️⃣ Create two Workday sensors in Home Assistant

You must create two Workday integrations through the Home Assistant UI.

Sensor 1 — binary_sensor.hassl_<id>_workday

  • Workdays: Mon–Fri
  • Excludes: holiday
  • Meaning: ON only on real workdays (Mon–Fri that are not holidays).

Sensor 2 — binary_sensor.hassl_<id>_not_holiday

  • Workdays: Mon–Sun
  • Excludes: holiday
  • Meaning: ON every day except official holidays (including weekends).

In both, set your Country and optional Province/Region as needed for your locale (e.g., US, CA, GB, etc.).
After setup, rename the entity IDs to exactly match:

  • binary_sensor.hassl_<id>_workday
  • binary_sensor.hassl_<id>_not_holiday
    where <id> matches the identifier used in your .hassl file (e.g., us_ca).

HASSL derives:

  • binary_sensor.hassl_holiday_<id> → ON on holidays (even when they fall on weekends).

Truth table

Day type hassl_<id>_workday hassl_<id>_not_holiday hassl_holiday_<id> (derived)
Tue (normal) on on off
Sat (normal weekend) off on off
Mon that’s an official holiday off off on
Sat that’s an official holiday off off on

This distinction lets you build precise schedules like:

holidays us_ca:
    country="US", province="CA"

schedule master_wake:
  on weekdays 06:00–22:00 except holidays us_ca;
  on weekends 08:00–22:00;
  on holidays us_ca 09:00–22:00;

🧩 Note:
Both sensors must be created manually in the Home Assistant UI — integrations can’t be defined in YAML.
Once created, HASSL automatically references them in generated automations.


⚗️ Experimental: Date & Month Range Schedules

HASSL v0.3.1 includes early support for:

on months Jun–Aug 07:00–22:00;
on dates 12-24..01-02 06:00–20:00;

These may compile successfully but are not yet validated in production.
They’re marked experimental and will be verified after template automation support (v0.4 milestone).


📚 Documentation


🧩 Contributing

Contributions, tests, and ideas welcome!
To run tests locally:

pytest tests/

Please open pull requests for grammar improvements, new device domains, or scheduling logic.


📄 License

MIT License © 2025
Created and maintained by @adanowitz


HASSL — simple, reliable, human-readable automations for Home Assistant.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hassl-0.3.1.tar.gz (50.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hassl-0.3.1-py3-none-any.whl (46.9 kB view details)

Uploaded Python 3

File details

Details for the file hassl-0.3.1.tar.gz.

File metadata

  • Download URL: hassl-0.3.1.tar.gz
  • Upload date:
  • Size: 50.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for hassl-0.3.1.tar.gz
Algorithm Hash digest
SHA256 d93491297d61f7bbdd6eb12b41fa9cd2878f1aff913f38f540418ace92eadcaf
MD5 8183387650d9b3a8b8e75723058b7098
BLAKE2b-256 d87e946eb14cb4b0f82f6312328d8a299e3ca584bb39f4879915b75490f9dde1

See more details on using hashes here.

File details

Details for the file hassl-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: hassl-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 46.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for hassl-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3c5a3c1e9b80dc0a0d8610c4ea1e703d866cd83ccacce7ac7717732d6f93087a
MD5 331e350aed257280b0c356372de6dc16
BLAKE2b-256 998ae98a3c5d54ab5ed1e1fd9e262f2814c53f6febcd4600a6b8fdce9725d5b4

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page