Overview
One client-mode connector, HomeAssistant, for the Home Assistant REST API. Home Assistant is an open-source automation platform that runs on site and connects thousands of device integrations: building HVAC, lighting, energy meters, smart plugs, Zigbee and Z-Wave sensors. Everything it knows about is an entity with a state (for examplesensor.office_temperature = 21.4), and you act on devices by calling services (for example switch.turn_off).
Use the connector to bridge Home Assistant and the UNS: mirror plant values into Home Assistant dashboards, switch a compressor or the shop-floor lighting from a broker rule, pull building temperature history into a report, or start a Home Assistant automation from an MQTT alarm.
Replies arrive on
<topic>/response. The WebSocket API (live event subscriptions) is not covered by this template.
Authentication
Every event exceptTriggerWebhook sends Authorization: {authorization}, so pass the whole header value: "Bearer <long-lived access token>". Create the token in Home Assistant under your user Profile > Security > Long-lived access tokens; it is shown only once and is valid for 10 years unless you delete it. Use a dedicated Home Assistant user for the broker so you can revoke it on its own; non-admin users cannot read the error log or check the configuration.
Keep the header value in a broker secret (suggested HOME_ASSISTANT_AUTHORIZATION) and map it in with GET SECRET. A missing or wrong token returns 401.
TriggerWebhook needs no token: the webhook id is the secret, so pick a long random one. Webhook triggers only accept requests from the local network unless the trigger sets local_only: false, so run the broker on the same network as Home Assistant or change that option.
Basic Syntax
SetBASE_ADDRESS to your Home Assistant URL, with no trailing slash: http://homeassistant.local:8123 or http://<ip>:8123 with USE_SSL "false", or an HTTPS reverse proxy or Home Assistant Cloud remote URL with USE_SSL "true". The REST API is part of default_config; on a minimal configuration add api: to configuration.yaml.
MQTT examples
Request bodies go underbody, so control fields like authorization and entity_id are not sent to Home Assistant. Events with a query field need it; send the pre-encoded query string.
Mirror a plant value into Home Assistant: publish to cloud-iot/home-assistant/state/set:
201 the first time and 200 afterwards. The state only exists in Home Assistant’s state machine (it is not a device and does not survive a restart), which is fine for dashboards and automations fed from the broker.
Switch a device: publish to cloud-iot/home-assistant/service/call:
400. Any service works the same way: light/turn_on with {"entity_id": "light.hall_b", "brightness_pct": 60}, climate/set_temperature with {"entity_id": "climate.office", "temperature": 21}, script/turn_on, automation/trigger, notify/<target>.
Read the next maintenance windows: publish to cloud-iot/home-assistant/service/call-with-response:
service_response with the events. Use this event only for services that return data; others answer 400.
Read one entity: publish {"authorization": "...", "entity_id": "sensor.office_temperature"} to cloud-iot/home-assistant/state/get.
Pull the history of a sensor: publish to cloud-iot/home-assistant/history/get-since:
cloud-iot/home-assistant/history/get with the same query (without start_time) for the past day.
Start a Home Assistant automation: add a webhook trigger to an automation (Settings > Automations > Trigger > Webhook) and publish to cloud-iot/home-assistant/webhook/trigger:
trigger.json, for example {{ trigger.json.machine }}. Home Assistant answers 200 with an empty body even when no automation uses the id, so check the automation trace when testing.
Render a template: publish {"authorization": "...", "body": {"template": "{{ states('sensor.office_temperature') }} °C"}} to cloud-iot/home-assistant/template/render; the reply is the rendered text.
Helper actions
Mirror a line temperature into Home Assistant and switch off a compressor when the broker raises an alarm:cloud-iot/home-assistant/# with a rule: its payloads carry the token and can switch real equipment.
Notes
- Errors come back on the response topic:
400for bad JSON, an unknown domain or service, a missingfilter_entity_idor areturn_responsemismatch,401for a missing or wrong token,404for an unknown entity or calendar, and405for a wrong method. SetStatechanges Home Assistant’s view of an entity, not the device. To act on a device, call a service withCallService.queryandend_timevalues must be URL-encoded (:as%3A,+as%2B).start_timein the path can stay as plain ISO 8601, for example2026-10-05T00:00:00+01:00.- History and logbook need the
historyandlogbookintegrations (part ofdefault_config), and only cover what the recorder keeps (10 days by default). - For a live stream of every state change, use Home Assistant’s MQTT integration or its WebSocket API instead of polling
ListStates.

