This release is a pre-release and may not be stable for production use.
fw-nodes-homeassistant
Home Assistant nodes for Flowire workflow automation. Replaces Node-RED for HA automations with a visual workflow editor.
Installation
pip install fw-nodes-homeassistant
Enable in your backend .env:
INSTALLED_NODE_PACKAGES=fw-nodes-core,fw-nodes-homeassistant
Backend requirement: the HA State Changed filter fields (
entity_ids,to_state,from_state,for_seconds) are declared on the node via itsstream_filter_fieldsmetadata, and the Flowire backend's stream-subscription sync forwards them to the live WebSocket connection automatically. This requires a Flowire backend that honors a node'sstream_filter_fields(current versions do). On an older backend that ignores it, the trigger still fires but those filters have no effect (it watches all entities).
Credential Setup
All nodes use a shared Home Assistant credential with two fields:
| Field | Example | Description |
|---|---|---|
| Server URL | http://homeassistant.local:8123 |
Your HA instance URL |
| Access Token | eyJhbGciOi... |
Long-lived access token |
To create a long-lived access token:
- Open Home Assistant → click your profile (bottom-left)
- Open the Security tab → scroll to Long-Lived Access Tokens → Create Token
- Copy the token (it's only shown once)
Nodes
Triggers (Entry Points)
HA State Changed
Triggers when any entity's state changes. This is the most common trigger for home automation.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
entity_ids |
string[] | null (all) | Entity IDs to watch. Dynamic dropdown. |
to_state |
string | null (any) | Only fire when the entity changes to this state (e.g., on, home). |
from_state |
string | null (any) | Only fire when the entity changes from this state (e.g., off). |
for_seconds |
number | null | Only fire once the entity has held to_state continuously for this many seconds. Requires to_state. |
The to_state / from_state / for_seconds filters let you express common
automations directly in the trigger — no separate Condition or Delay node
needed.
- These filters fire on a real state transition (the state value actually
changes), not on attribute-only updates. So
to_state: onfires when a light turns on, not every time its brightness changes while already on. - With
for_seconds, the trigger fires once after the entity has heldto_statefor the duration. If it leavesto_statefirst, the countdown is cancelled (matching Home Assistant's ownfor:semantics).for_secondsrequiresto_state; without it the duration is ignored. - Reconnect caveat: a WebSocket reconnect (network blip, HA restart) clears
in-flight
for_secondscountdowns, so a long hold spanning a reconnect restarts from the next state change. Keep this in mind for very long durations.
Outputs:
| Field | Type | Description |
|---|---|---|
entity_id |
string | Entity that changed (e.g., light.kitchen) |
new_state |
string | New state value (on, off, 22.5, etc.) |
old_state |
string | Previous state value |
new_attributes |
dict | New entity attributes (brightness, temperature, etc.) |
old_attributes |
dict | Previous entity attributes |
last_changed |
string | ISO timestamp of state change |
last_updated |
string | ISO timestamp of last update |
context |
dict | Event context (user_id, parent_id) |
raw_event |
dict | Full raw event payload |
Example workflow: "Notify when front door opens"
- HA State Changed → entity_ids:
binary_sensor.front_door, to_state:on - HA Call Service →
notify.mobile_app_phonewith{"message": "Front door opened!"}
Example: "Garage left open for 10 minutes" (no Delay node needed)
- HA State Changed → entity_ids:
cover.garage_door, to_state:open, for_seconds:600 - HA Call Service →
notify.mobile_app_phonewith{"message": "Garage has been open 10 minutes!"}
HA Event Trigger
Triggers on any Home Assistant event type. More flexible than State Changed.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
events |
string[] | ["state_changed"] |
Event types to listen for |
Common event types:
state_changed— Entity state updatescall_service— When any service is calledautomation_triggered— When HA automations firescript_started— When scripts starttimer_finished/timer_started— Timer eventstag_scanned— NFC tag scanshomeassistant_start/homeassistant_stop— System lifecycledevice_registry_updated— Device changes
Outputs:
| Field | Type | Description |
|---|---|---|
event_type |
string | Event type name |
data |
dict | Event payload data |
origin |
string | LOCAL or REMOTE |
time_fired |
string | ISO timestamp |
context |
dict | Event context |
raw_event |
dict | Full raw event payload |
HA Webhook
Receives HTTP webhook callbacks from Home Assistant automations.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
webhook_id |
string | null | Optional webhook ID to validate |
Outputs:
| Field | Type | Description |
|---|---|---|
webhook_id |
string | Webhook ID from the request |
data |
dict | Webhook payload ({} when the request has no/empty body) |
headers |
dict | HTTP headers |
query |
dict | Query string parameters |
method |
string | HTTP method (POST, GET, etc.) |
An empty or bodyless request is accepted (useful for simple pings) and yields
data: {}. If webhook_id is set, it's validated against webhook_id in the
body when present.
Actions
HA Call Service
Call any Home Assistant service. This is the primary node for controlling devices.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
service |
string | required | Service in domain.action format. Dynamic dropdown. |
entity_id |
string | null | Target entity. Dynamic dropdown. |
area_id |
string | null | Target a whole area by ID (e.g., kitchen). |
device_id |
string | null | Target a device by ID (affects all its entities). |
label_id |
string | null | Target every entity carrying a label by ID. |
service_data |
dict | null | Additional parameters for the service |
return_response |
bool | false | Request response data from the service (HA 2023.7+). Required for services that return data. |
You can target a single entity_id or a whole group via area_id /
device_id / label_id (e.g. light.turn_off with area_id: kitchen turns
off every light in the kitchen). Combine multiple targets if needed.
Outputs:
| Field | Type | Description |
|---|---|---|
success |
bool | Whether the call succeeded |
service |
string | Service that was called |
changed_states |
list | Entity states that changed as a result |
response |
dict | Service response data (only when return_response is enabled) |
Service response data (return_response)
Some Home Assistant services return data instead of (or in addition to)
changing state. Enable return_response to call them and read the result from
the response output.
Get the weather forecast:
service: weather.get_forecasts
entity_id: weather.home
service_data: {"type": "daily"}
return_response: true
→ response contains {"weather.home": {"forecast": [...]}}
Get upcoming calendar events:
service: calendar.get_events
entity_id: calendar.family
service_data: {"start_date_time": "2025-01-01 00:00:00", "end_date_time": "2025-01-02 00:00:00"}
return_response: true
List to-do items:
service: todo.get_items
entity_id: todo.shopping_list
return_response: true
Services that return data require
return_response: trueand will error without it. Conversely, most action services reject it — leave it off for normal calls likelight.turn_on.
Target an area / device / label
Turn off all lights in an area:
service: light.turn_off
area_id: kitchen
Turn on everything tagged with a label:
service: homeassistant.turn_on
label_id: holiday_lights
Lights
Turn on a light:
service: light.turn_on
entity_id: light.kitchen
Turn on at 75% brightness:
service: light.turn_on
entity_id: light.kitchen
service_data: {"brightness_pct": 75}
Set RGB color (red) at full brightness:
service: light.turn_on
entity_id: light.led_strip
service_data: {"rgb_color": [255, 0, 0], "brightness": 255}
Set color by name:
service: light.turn_on
entity_id: light.bedroom
service_data: {"color_name": "blue", "brightness_pct": 50}
Set color temperature (warm white):
service: light.turn_on
entity_id: light.living_room
service_data: {"color_temp_kelvin": 2700}
Transition over 5 seconds:
service: light.turn_on
entity_id: light.bedroom
service_data: {"brightness_pct": 100, "transition": 5}
Turn off with transition:
service: light.turn_off
entity_id: light.bedroom
service_data: {"transition": 3}
Toggle a light:
service: light.toggle
entity_id: light.kitchen
Flash a light (short or long):
service: light.turn_on
entity_id: light.hallway
service_data: {"flash": "short"}
Light service_data reference:
| Parameter | Type | Description |
|---|---|---|
brightness |
int (0-255) | Absolute brightness |
brightness_pct |
int (0-100) | Brightness as percentage |
brightness_step |
int (-255 to 255) | Adjust relative to current |
brightness_step_pct |
int (-100 to 100) | Adjust relative (%) |
rgb_color |
[R, G, B] | RGB color (0-255 each) |
rgbw_color |
[R, G, B, W] | RGBW color |
rgbww_color |
[R, G, B, CW, WW] | RGBWW color |
hs_color |
[hue, sat] | Hue (0-360), Saturation (0-100) |
xy_color |
[x, y] | CIE xy color |
color_temp_kelvin |
int | Color temperature in Kelvin |
color_name |
string | CSS3 color name (red, blue, etc.) |
transition |
number | Transition time in seconds |
flash |
string | "short" or "long" |
effect |
string | Effect name (e.g., "colorloop") |
profile |
string | "relax", "energize", "concentrate", "reading" |
Only one color parameter is allowed per call. Don't combine
rgb_colorwithcolor_temp_kelvin, etc.
Switches
Turn on/off:
service: switch.turn_on
entity_id: switch.coffee_maker
Toggle:
service: switch.toggle
entity_id: switch.garage_door
Climate / Thermostats
Set temperature:
service: climate.set_temperature
entity_id: climate.thermostat
service_data: {"temperature": 22}
Set temperature with HVAC mode:
service: climate.set_temperature
entity_id: climate.thermostat
service_data: {"temperature": 22, "hvac_mode": "heat"}
Set heat/cool range:
service: climate.set_temperature
entity_id: climate.thermostat
service_data: {"target_temp_high": 24, "target_temp_low": 20}
Change HVAC mode:
service: climate.set_hvac_mode
entity_id: climate.thermostat
service_data: {"hvac_mode": "cool"}
HVAC modes: off, heat, cool, heat_cool, auto, dry, fan_only
Set fan mode:
service: climate.set_fan_mode
entity_id: climate.thermostat
service_data: {"fan_mode": "auto"}
Covers (Blinds, Garage Doors)
Open / Close / Stop:
service: cover.open_cover
entity_id: cover.garage_door
service: cover.close_cover
entity_id: cover.living_room_blinds
service: cover.stop_cover
entity_id: cover.living_room_blinds
Set position (0=closed, 100=open):
service: cover.set_cover_position
entity_id: cover.living_room_blinds
service_data: {"position": 50}
Media Players
Play/Pause/Stop:
service: media_player.media_play
entity_id: media_player.living_room_speaker
service: media_player.media_pause
entity_id: media_player.living_room_speaker
Set volume (0.0 to 1.0):
service: media_player.volume_set
entity_id: media_player.living_room_speaker
service_data: {"volume_level": 0.5}
Play media:
service: media_player.play_media
entity_id: media_player.living_room_speaker
service_data: {
"media_content_id": "https://example.com/song.mp3",
"media_content_type": "music"
}
Fans
Turn on with speed:
service: fan.turn_on
entity_id: fan.bedroom
service_data: {"percentage": 50}
Set preset mode:
service: fan.set_preset_mode
entity_id: fan.bedroom
service_data: {"preset_mode": "sleep"}
Notifications
Send mobile notification:
service: notify.mobile_app_phone
service_data: {
"message": "Motion detected in the backyard!",
"title": "Security Alert"
}
Notification with image:
service: notify.mobile_app_phone
service_data: {
"message": "Someone is at the door",
"title": "Doorbell",
"data": {
"image": "/api/camera_proxy/camera.front_door"
}
}
Scripts & Automations
Run a script:
service: script.turn_on
entity_id: script.good_morning
Trigger an automation:
service: automation.trigger
entity_id: automation.morning_routine
Enable/disable an automation:
service: automation.turn_off
entity_id: automation.motion_lights
Locks
Lock/Unlock:
service: lock.lock
entity_id: lock.front_door
service: lock.unlock
entity_id: lock.front_door
Scenes
Activate a scene:
service: scene.turn_on
entity_id: scene.movie_night
Input Helpers
Set an input boolean:
service: input_boolean.turn_on
entity_id: input_boolean.vacation_mode
Set an input number:
service: input_number.set_value
entity_id: input_number.target_temperature
service_data: {"value": 22}
Set an input select:
service: input_select.select_option
entity_id: input_select.house_mode
service_data: {"option": "away"}
System
Restart Home Assistant:
service: homeassistant.restart
(no entity_id needed)
Reload automations:
service: automation.reload
(no entity_id needed)
HA Get State
Get the current state and attributes of a specific entity.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
entity_id |
string | required | Entity to query. Dynamic dropdown. |
Outputs:
| Field | Type | Description |
|---|---|---|
entity_id |
string | Entity ID |
state |
string | Current state (on, off, 22.5, etc.) |
attributes |
dict | All entity attributes |
friendly_name |
string | Human-readable name |
last_changed |
string | When state last changed |
last_updated |
string | When state was last updated |
HA Get Entities
Get multiple entities with filtering. Useful for bulk queries.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
domain |
string | null | Filter by domain (light, switch, sensor, etc.) |
state |
string | null | Filter by state value (on, off, unavailable) |
area |
string | null | Name match: substring of the entity's friendly name or entity_id (kitchen, bedroom). Not a true HA Area — see note below. |
entity_ids |
string[] | null | Specific entity IDs (overrides other filters) |
Note: the
areafilter is a convenience name/ID substring match, not a lookup against Home Assistant's Area registry. It matches entities whose friendly name or entity_id contains the text. To act on a real HA Area, use HA Call Service witharea_id.
Outputs:
| Field | Type | Description |
|---|---|---|
entities |
list | List of matching entity states |
count |
int | Number of matches |
Example: "Get all lights that are on"
domain: light
state: on
Example: "Get all kitchen entities"
area: kitchen
HA Get History
Fetch historical state data for an entity.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
entity_id |
string | required | Entity to get history for. Dynamic dropdown. |
hours |
number | 24 | Hours of history to retrieve |
minimal_response |
bool | true | Return minimal data for better performance |
no_attributes |
bool | false | Exclude attributes for faster queries |
Outputs:
| Field | Type | Description |
|---|---|---|
entity_id |
string | Entity ID |
states |
list | Historical state entries |
count |
int | Number of entries |
start_time |
string | Start of period (ISO) |
end_time |
string | End of period (ISO) |
With
minimal_response: true(the default) HA returns reduced entries — onlystateandlast_changedfor most entries, withoutattributes. Setminimal_response: falseif you need full state objects (e.g. to readstates[i].attributes).
HA Fire Event
Fire a custom event on the Home Assistant event bus.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
event_type |
string | required | Event type to fire |
event_data |
dict | null | Data to include with the event |
Outputs:
| Field | Type | Description |
|---|---|---|
success |
bool | Whether the event was fired |
event_type |
string | Event type that was fired |
message |
string | HA response message |
Example: Trigger a HA automation from Flowire
event_type: flowire_alert
event_data: {"level": "warning", "room": "garage", "message": "Smoke detected"}
Then in HA, create an automation that triggers on flowire_alert events.
HA Render Template
Render a Jinja2 template server-side on Home Assistant.
Inputs:
| Field | Type | Default | Description |
|---|---|---|---|
credential_id |
string | required | HA credential |
template |
string | required | Jinja2 template using HA template syntax. Sent to HA verbatim. |
variables |
dict | null | Variables made available to the template. Values support Flowire {{...}} expressions. |
Important —
{{ }}is HA's, not Flowire's. Because Home Assistant templates use the same{{ }}braces as Flowire expressions, thetemplatefield is sent to Home Assistant exactly as written and is not processed by Flowire's expression engine. To pull data from an upstream node into a template, put it invariables(which is Flowire-parsed) and reference it by name:template: "Alert for {{ room }}: {{ states('sensor.' ~ room ~ '_temp') }}°C" variables: {"room": "{{SomeNode.room_name}}"}
Outputs:
| Field | Type | Description |
|---|---|---|
result |
string | Rendered template output |
Example templates:
Get a sensor value:
{{ states("sensor.temperature") }}
Check if entity is in a state:
{{ is_state("light.kitchen", "on") }}
Count lights that are on:
{{ states.light | selectattr("state", "eq", "on") | list | count }}
Format a message with multiple values:
Temperature: {{ states("sensor.temperature") }}°C, Humidity: {{ states("sensor.humidity") }}%
Calculate average of multiple sensors:
{% set temps = [
states("sensor.kitchen_temp") | float,
states("sensor.bedroom_temp") | float,
states("sensor.living_room_temp") | float
] %}
{{ (temps | sum / temps | count) | round(1) }}
Example Workflows
Motion-activated lights
- HA State Changed →
binary_sensor.motion_living_room, to_state:on - HA Call Service →
light.turn_on, entity:light.living_room, data:{"brightness_pct": 80, "color_temp_kelvin": 3000}
Thermostat schedule
- Cron Trigger →
0 7 * * 1-5(7 AM weekdays) - HA Call Service →
climate.set_temperature, entity:climate.thermostat, data:{"temperature": 22, "hvac_mode": "heat"}
Daily energy report
- Cron Trigger →
0 20 * * *(8 PM daily) - HA Render Template →
{{ states("sensor.daily_energy") }} kWh used today - HA Call Service →
notify.mobile_app_phone, data:{"message": "{{render-template.result}}", "title": "Energy Report"}Reference the Render Template node by its node id (
{{render-template.result}}), not its display name — pick it from the expression autocomplete in the editor.
Garage door left open alert
- HA State Changed →
cover.garage_door, to_state:open, for_seconds:600 - HA Call Service →
notify.mobile_app_phone, data:{"message": "Garage door has been open for 10 minutes!"}
Development
just install # Install dependencies
just test # Run tests
just lint # Run linter
just format # Format code
just check # Lint + format check
Metadata
Release files for fw-nodes-homeassistant 0.0.1a1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fw_nodes_homeassistant-0.0.1a1.tar.gz | 31.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fw_nodes_homeassistant-0.0.1a1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 64.9 kB
Release files / fw_nodes_homeassistant-0.0.1a1.tar.gz
| Download URL | fw_nodes_homeassistant-0.0.1a1.tar.gz |
|---|---|
| Size | 31.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7241f2454f241298d012fbfaeb09e38531b9e07111ca0ad5461ad04888d59fe5
|
|
BLAKE2b-256 checksum How to use checksums |
e954cb3edace45a531e83580ef5f37a52378f97446d8a4ae27752142c29ebddb
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / fw_nodes_homeassistant-0.0.1a1-py3-none-any.whl
| Download URL | fw_nodes_homeassistant-0.0.1a1-py3-none-any.whl |
|---|---|
| Size | 33.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c5c9b91a1a480f40a5c977dd2d0590928c7aa4780b1769479cb2701aa5306e9f
|
|
BLAKE2b-256 checksum How to use checksums |
60d09ec4c66e598f3748ce7352c5dcf562c642a990c4d5c25198960446a94d3c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.17 {"installer":{"name":"uv","version":"0.11.17","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"12","id":"bookworm","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|