The Client component provides a WebSocket-based API for communicating with Home Assistant. It handles authentication, connection management, entity subscriptions, and service calls.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/korapp/plasma-homeassistant/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Client is a QML component that wrapsQtWebSockets.WebSocket and implements the Home Assistant WebSocket API protocol.
Location: package/contents/ui/Client.qml
Type: BaseObject (extends QtObject)
Properties
The base URL of the Home Assistant server (e.g.,
http://homeassistant.local:8123)Automatically converted to WebSocket URL by replacing http with ws and appending /api/websocketHome Assistant long-lived access token for authenticationTypically retrieved from KDE Wallet via ClientFactory
Indicates whether the client is connected and authenticatedBecomes
true after successful authentication, false on disconnect or before authIndicates whether the client has both URL and token configuredAutomatically activates WebSocket connection when true
Contains the last error message, or empty string if no errorAutomatically cleared when connection becomes ready
Public Methods
subscribeEntities
Subscribes to state updates for specific entities.Array of entity IDs to subscribe to (e.g.,
["light.living_room", "sensor.temperature"])Function called when entity states changeReceives a single
event parameter containing:a: Initial entity states (object mapping entity_id to state data)c: Changed entity states (object with entity_id keys and change data)
Returns an unsubscribe function that cancels the subscription when called
callService
Calls a Home Assistant service with optional data.Service domain (e.g.,
"light", "switch", "climate")Service name (e.g.,
"turn_on", "turn_off", "set_temperature")Service target specificationCommon formats:
{entity_id: "light.bedroom"}- Single entity{entity_id: ["light.bedroom", "light.kitchen"]}- Multiple entities{area_id: "living_room"}- All entities in area
Additional service data (parameters)Examples:
{brightness: 255}for light.turn_on{temperature: 22}for climate.set_temperature
Promise that resolves when the service call succeeds, or rejects with error object
getStates
Retrieves current states for all or specific entities.Optional array of entity IDs to filterIf omitted, returns all entity states
Promise that resolves to array of entity state objectsEach object contains:
entity_id: Entity identifierstate: Current state valueattributes: Object with entity attributeslast_changed: ISO timestamplast_updated: ISO timestamp
getServices
Retrieves all available services and their metadata.Promise that resolves to object mapping domain → service → metadataStructure:
Connection Lifecycle
Authentication Flow
- WebSocket connects to
baseUrl/api/websocket - Server sends
{type: "auth_required"} - Client sends
{type: "auth", access_token: token} - Server responds with
{type: "auth_ok"}or{type: "auth_invalid"} readyproperty becomestrueon successerrorsignal emitted on auth failure
Client.qml:57-66):
Keepalive Mechanism
The client uses a ping/pong system to maintain the connection:- Interval: 30 seconds (30000ms)
- Behavior:
- Sends ping command
- Waits for any message response
- If no response after 30s, reconnects
- Reset: Timer resets on any message received
Client.qml:26-44):
Reconnection
The client automatically reconnects when:- Ping/pong timeout occurs (no response in 30s)
- WebSocket connection is lost
reconnect()is called manually
Error Handling
Error Signal
The client emits anerror signal when issues occur:
- Authentication failures (
auth_invalidmessage) - WebSocket connection errors (
errorStringchanged) - Service call failures (promise rejection)
Error String Property
TheerrorString property contains the last error message:
- Set when
errorsignal is emitted - Automatically cleared when connection becomes ready
- Displayed in UI via StatusIndicator
Client.qml:20-24):
Internal Implementation Details
Message Counter
Each command is assigned a unique ID from an incrementing counter:Promise Management
Async commands store promise resolvers in a Map:Subscription Management
Subscriptions are tracked in a Map with callbacks:Usage with ClientFactory
The recommended way to use the Client is via ClientFactory:Best Practices
- Always check
ready: Wait forready === truebefore making API calls - Use ClientFactory: Don’t instantiate Client directly
- Handle errors: Connect to
errorsignal or use promise.catch() - Clean up subscriptions: Call returned unsubscribe function when done
- Monitor
errorString: Display to users for connection issues - Let keepalive work: Don’t manually manage ping/pong unless necessary
Related Components
- ClientFactory - Singleton for client instance management
- Entity Model - Data structures for entity state
- Main Plasmoid - Example client usage
