# Home Assistant Link Binding
The Home Assistant Link binding (hasslink) connects to a Home Assistant instance via its native WebSocket API, exposing Home Assistant devices and entities as native openHAB Things, Channels, and Items with real-time, bi-directional synchronization.
While openHAB offers robust scripting, flexible rule engines, and tailored UIs, Home Assistant's massive contributor base rapidly adds support for new smart home hardware and niche integrations. This binding bridges that gap—allowing you to use Home Assistant as an integration backend for hard-to-integrate devices while keeping openHAB as your primary home automation platform.
# Features
- Vast Ecosystem Expansion: Instantly extends openHAB compatibility to thousands of Home Assistant-supported integrations and hardware.
- Native WebSocket Communication: Connects directly to Home Assistant's built-in
/api/websocket—no extra integrations, add-ons, or Home Assistant-side modifications required. - Automatic Unit Conversion: Maps Home Assistant units of measurement (
°C,°F,W,kWh,hPa, etc.) directly to openHABQuantityTypeitems (Number:Temperature,Number:Power, etc.). - Dynamic Channel Generation: Dynamically creates channels based on entity state attributes upon discovery or configuration.
- Unified Channel Naming: Predictable channel structure using
domain-entity_namefor primary channels anddomain-entity_name#attributefor secondary attributes. - Bi-directional Control: Full command mapping for switches, dimmers, colors, climate controls, covers, fans, media players, and more.
- Rule Engine Actions: Execute Home Assistant service calls, trigger buttons, run scripts, and activate scenes directly from openHAB automation rules.
# Prerequisites & Setup
# 1. Home Assistant Instance
You need a running Home Assistant instance on your local network. If you do not already have one, it can be run as a lightweight container alongside openHAB.
For full installation options, see the official Home Assistant Installation Guide (opens new window).
# Minimal Docker Compose Example
If running in Docker, a basic setup requires network_mode: host to allow mDNS discovery and local API connectivity:
version: '3.8'
services:
homeassistant:
container_name: homeassistant
image: ghcr.io/home-assistant/home-assistant:stable
volumes:
- /opt/homeassistant/config:/config
- /etc/localtime:/etc/localtime:ro
restart: unless-stopped
network_mode: host
# 2. Generate a Long-Lived Access Token
openHAB authenticates with Home Assistant using a token:
- Open your Home Assistant UI in a web browser.
- Click your user profile icon (bottom-left corner).
- Select the Security tab at the top of the profile page.
- Scroll down to the Long-Lived Access Tokens section.
- Select Create Token, enter a name (e.g.,
openHAB Link), and copy the generated token string. - Store this token securely. You will provide it when configuring the
hasslink:serverThing in openHAB.
# Discovery
The binding supports automatic discovery for both the Home Assistant server itself and its connected entities.
# Server Bridge Discovery (mDNS)
If Home Assistant is running on your local network with mDNS enabled, openHAB will automatically discover the Home Assistant server instance:
- Go to Settings → Things → Inbox in openHAB.
- Choose the discovered Home Assistant server from the Inbox.
- Enter your Long-Lived Access Token in the Bridge configuration and save.
# Entity & Device Discovery
Once the server Bridge is online, device discovery runs automatically:
- The binding queries the Home Assistant WebSocket API and device/entity registries.
- Discovered physical and logical hardware devices appear in your openHAB Inbox as Things (e.g.,
hasslink:device:XXXXX:XXXXX). - Adding a Thing from the Inbox automatically generates its primary channel and any mapped attribute channels.
- Real-Time Additions: Devices added to Home Assistant while openHAB is running are automatically detected and added to the Inbox without requiring a restart.
Filtered Discovery & Manual Scans:
To prevent cluttering your openHAB Inbox with hundreds of virtual helpers, automations, scripts, persons, and system domains that are typically of lower direct interest, auto-discovery focuses exclusively on physical and logical devices by default. Skipped entities and independent items can still be added manually or configured via discovery filter options on the Bridge.
If you add or rename entities in Home Assistant and want to refresh the Inbox immediately, go to Settings → Things → + (Add), select Home Assistant Link Binding, and trigger a manual scan.
# Thing Configuration
# Bridge (server)
The server Bridge manages the persistent WebSocket connection to Home Assistant Core and controls global Inbox discovery filters. Standard wildcard glob patterns (*, ?) are supported across area, domain, and label filters.
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
host | Text | N/A | Yes | Hostname or IP address of Home Assistant |
port | Integer | 8123 | No | WebSocket/HTTP port |
token | Text | N/A | Yes | Home Assistant Long-Lived Access Token |
secure | Boolean | false | No | Use TLS/SSL (wss://) |
ignoreIndependentEntities | Boolean | true | No | Exclude entities without a parent device (helpers, automations, person tracking) from Inbox discovery |
includedAreas | Text (Multiple) | [] | No | Whitelist of Home Assistant Area IDs to discover (supports glob patterns, e.g., *bedroom*) |
excludedAreas | Text (Multiple) | [] | No | Blacklist of Home Assistant Area IDs to exclude from discovery (supports glob patterns) |
includedDomains | Text (Multiple) | [] | No | Whitelist of Home Assistant domains to discover (supports glob patterns, e.g., light*) |
excludedDomains | Text (Multiple) | See below | No | Blacklist of Home Assistant domains to exclude from discovery (supports glob patterns) |
includedLabels | Text (Multiple) | [] | No | Whitelist of Home Assistant Labels/Tags to discover (supports glob patterns, e.g., openhab*) |
excludedLabels | Text (Multiple) | [] | No | Blacklist of Home Assistant Labels/Tags to ignore during discovery (supports glob patterns) |
Default Excluded Domains:
automation,conversation,counter,media_source,persistent_notification,stt,sun,timer,tts,zone
# Device / Entity Container (device)
The device Thing maps one or more Home Assistant entities to openHAB channels and provides per-Thing channel creation filters. Standard wildcard glob patterns (*, ?) are supported across all filter fields.
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
deviceId | Text | N/A | No | Home Assistant device registry identifier |
entityIds | Text (Multiple) | [] | No | Explicitly defined entity IDs or glob patterns; bypasses all device exclusions and filter rules |
channelIdPrefixToStrip | Text | "" | No | Fixed prefix of entity object IDs to remove from generated channel IDs (e.g., kitchen_). Blank keeps the full object ID. |
includedDomains | Text (Multiple) | [] | No | Whitelist of Home Assistant domains to restrict channels to (supports glob patterns, e.g., sensor*) |
excludedDomains | Text (Multiple) | [] | No | Blacklist of Home Assistant domains to exclude from creating channels (supports glob patterns, e.g., update*) |
includedLabels | Text (Multiple) | [] | No | Whitelist of Home Assistant Labels/Tags for child entities (supports glob patterns) |
excludedLabels | Text (Multiple) | [] | No | Blacklist of Home Assistant Labels/Tags for child entities (supports glob patterns) |
includedEntities | Text (Multiple) | [] | No | Specific Entity IDs or glob patterns (e.g., sensor.*bed*, *_temperature) to explicitly allow as channels |
excludedEntities | Text (Multiple) | [] | No | Specific Entity IDs or glob patterns (e.g., *battery*, *_rssi) to exclude from channel creation |
Note: At least one of
deviceIdorentityIdsmust be defined.
For full evaluation semantics and details on composite filtering, see filtering.
TIP
The device ID can be obtained from Settings → Devices & Services → Devices. Click on the device you want to use.
The device ID is the final segment of the URL. For example:
https://homeassistant.local/config/devices/device/5a471c1a7211f02d76869838fe451d68
The device ID is:
5a471c1a7211f02d76869838fe451d68
# Supported Entity Domains
The binding includes dedicated mapping logic for over 35 Home Assistant entity domains:
- Lighting & Power:
light,switch,button,scene,script - Sensors:
sensor,binary_sensor,device_tracker,geolocation,event - Climate & Environment:
climate,humidifier,water_heater,weather,fan - Covers & Locks:
cover,lock,valve - Media & Remotes:
media_player,remote,camera,image - Controls & Inputs:
number,select,text,date,time,datetime - Robotics & Vacuum:
vacuum,lawn_mower,siren - System & Infrastructure:
update,alarm_control_panel,infrared,radio_frequency
# Channel Types & Event Handling
The binding utilizes standard openHAB channel types mapped dynamically across entities:
- Standard State Channels:
color,contact,datetime,dimmer,image,location,number,player,rollershutter,string,switch - Event Channel (
event): Used exclusively for the Home Assistantevententity domain.
# Event Channel Behavior (event Domain)
For Home Assistant event entities, event acts purely as an openHAB Trigger channel:
- Rule Triggers: Incoming Home Assistant events fire openHAB channel trigger events directly (e.g.,
channel "hasslink:..." triggered). - Item Linking: If you wish to post commands or update Item states from incoming events, link the channel to an Item using standard openHAB Profiles or rules.
# Channel Naming Conventions
Channels are generated dynamically using the following structure.
By default, the full Home Assistant entity object ID is used, so sensor.living_room_temperature generates sensor-living_room_temperature.
Configure channelIdPrefixToStrip on the device Thing to remove a fixed prefix from entity object IDs (for example, living_room_ produces sensor-temperature).
The prefix is not inferred from the current entity set, so adding or removing entities does not change existing channel IDs.
Primary Channel:
domain-entity_name(e.g.,light-living_room_light,sensor-living_room_temperature) Exposes the primary state of the entity (e.g.,ON/OFF, numeric values, or string states).Domain Attribute Channel:
domain-entity_name#attribute_name(e.g.,light-living_room_light#color_temp,climate-hallway#target_temperature) Exposes first-class, strongly typed mapped attributes explicitly handled by specific entity implementations.Generic Attribute Channel (Sensor Entities):
sensor-entity_name#attribute_name(e.g.,sensor-weather_station#pressure_trend) Auto-discovered fallback attributes generated exclusively for sensor entities from the Home Assistant state payload when not mapped as primary channels. List and map attributes are provided as JSON strings.Raw JSON Attributes Channel:
domain-entity_name#json_attributesExposes the entire Home Assistant entity attributes payload as a serialized JSON string.Note: This channel is not created automatically. To opt in, you must manually create a custom channel with the following configuration parameters:
entityId: <entity_id>attribute: json_attributes
Once defined, payload serialization is evaluated lazily and only executes when an Item is actively linked to the channel.
# Supported Entity Domains & Mapping Logic
The binding provides out-of-the-box support for over 35 Home Assistant entity domains. While standard scalar entities (such as simple sensors, switches, or selects) map symmetrically between Home Assistant states and openHAB items, more complex domains require specialized handling for state inversions, dynamic command generation, or parameterized action service calls.
For full details on domain-specific channel structures, command syntax (e.g., alarm PIN codes, vacuum segment cleaning), percentage inversions (e.g., covers), and attribute channel generation, see the Home Assistant Entity Mapping Guide.
# Rule Actions
The binding exposes actions scoped to the server Bridge (hasslink:server).
Actions can be retrieved in openHAB automation rules using the action identifier "hasslink" and the bridge UID.
# Action Summary
| Method | Description |
|---|---|
callService(String domain, String service, String entityId, Map<String, Object> payload) | Invokes any native Home Assistant service via the WebSocket connection. |
pressButton(String entityId) | Triggers a Home Assistant button entity (button or input_button). |
runScript(String scriptId, Map<String, Object> variables) | Executes a Home Assistant script directly by service name. |
activateScene(String sceneId) | Activates a Home Assistant scene using the generic scene.turn_on service. |
# Action Details
# callService
callService(String domain, String service, String entityId, Map<String, Object> payload)
Invokes any native Home Assistant service via the WebSocket connection.
domain(String, required): The target Home Assistant service domain (e.g."light","notify","climate").service(String, required): The target service action (e.g."turn_on","persistent_notification","set_temperature").entityId(String, optional): Fully qualified entity ID ("domain.object_id") ornullif the service does not target a specific entity.payload(Map<String, Object>, optional): Key-value parameters passed to the service payload ornull.
# pressButton
Syntax: pressButton(String entityId)
Triggers a Home Assistant button entity (button or input_button).
entityId(String, required): The target entity ID. Accepts a fully qualified entity ID (e.g.,"button.reboot","input_button.reset") or a shorthand object ID (e.g.,"reboot"), which automatically defaults to thebuttondomain ("button.reboot").
# runScript
Syntax: runScript(String scriptId, Map<String, Object> variables)
Executes a Home Assistant script directly by service name.
scriptId(String, required): Fully qualified script ID (e.g.,"script.welcome_home") or simple script name (e.g.,"welcome_home").variables(Map<String, Object>, optional): Execution variables passed to the script payload ornull.
# activateScene
Syntax: activateScene(String sceneId)
Activates a Home Assistant scene using the generic scene.turn_on service.
sceneId(String, required): Fully qualified scene ID (e.g.,"scene.movie_night") or simple scene name (e.g.,"movie_night").
# Rule Examples
:::
# Textual Configuration Examples
# things/homeassistant.things
Bridge hasslink:server:homeassistant "Home Assistant Core" [
host="192.168.1.100",
port=8123,
token="eyJhbGciOiJIUzI1NiIsInR...",
secure=false,
ignoreIndependentEntities=true,
includedLabels="openhab*"
] {
// Single entity mapping
Thing device desk_light "Desk Lamp" [
entityIds="light.desk_lamp"
]
// Physical device mapping via Home Assistant Device ID with wildcard exclusions for static noise
Thing device lawn_mower "Lawn Mower" [
deviceId="3a4b5c6d7e8f90123456789abcdef012",
excludedEntities="*_version", "*_mac", "*_fw_*"
]
// Grouping multiple standalone entities into one Thing
Thing device office_environment "Office Environment" [
entityIds=
"sensor.office_temperature",
"sensor.office_humidity",
"switch.office_fan"
]
}
# items/homeassistant.items
// Light Controls
Switch DeskLamp_Power "Desk Lamp Power" <light> { channel="hasslink:device:homeassistant:desk_light:light-desk_lamp" }
Dimmer DeskLamp_Brightness "Desk Lamp Brightness" <light> { channel="hasslink:device:homeassistant:desk_light:light-desk_lamp#brightness" }
// Environment Sensors (Automated QuantityType)
Number:Temperature Office_Temp "Office Temperature [%.1f %unit%]" <temperature> { channel="hasslink:device:homeassistant:office_environment:sensor-office_temperature" }
Number:Dimensionless Office_Humidity "Office Humidity [%.0f %%]" <humidity> { channel="hasslink:device:homeassistant:office_environment:sensor-office_humidity" }
// Climate Controls
String AC_Mode "AC Mode" <climate> { channel="hasslink:device:homeassistant:living_room_ac:climate-living_room_ac" }
Number:Temperature AC_TargetTemp "Target Temperature [%.1f %unit%]" <temperature> { channel="hasslink:device:homeassistant:living_room_ac:climate-living_room_ac#target_temperature" }