Custom Service Calls
Make direct Home Assistant service calls for advanced use cases not covered by entity-specific hooks.
Overview
The useServiceCall hook provides access to Home Assistant's raw service call API, allowing you to call any service with custom parameters. This is useful when:
- You need to call services not covered by entity-specific hooks
- You want to control multiple entities with a single service call
- You're working with custom integrations or scripts
- You need fine-grained control over service parameters
Basic Usage
import { useServiceCall } from 'hass-react'
function CustomControl() {
const { callService } = useServiceCall()
const handleAction = async () => {
await callService('light', 'turn_on', {
entity_id: 'light.living_room',
brightness: 255,
rgb_color: [255, 0, 0]
})
}
return <button onClick={handleAction}>Red Light</button>
}
API Reference
useServiceCall()
Returns an object with service call methods:
callService(domain, service, data?)
Make a service call without expecting a response.
Parameters:
domain(string) - Service domain (e.g., 'light', 'switch', 'homeassistant')service(string) - Service name (e.g., 'turn_on', 'toggle', 'restart')data(object, optional) - Service data including entity_id and other parameters
Returns: Promise<void>
callServiceWithResponse<R>(domain, service, data?)
Make a service call and return the response.
Parameters:
domain(string) - Service domainservice(string) - Service namedata(object, optional) - Service data
Returns: Promise<R> - The service response
Examples
Control Multiple Entities
function RoomControl() {
const { callService } = useServiceCall()
const allLightsOn = async () => {
await callService('light', 'turn_on', {
entity_id: ['light.living_room', 'light.kitchen', 'light.bedroom'],
brightness: 200
})
}
const allLightsOff = async () => {
await callService('light', 'turn_off', {
entity_id: ['light.living_room', 'light.kitchen', 'light.bedroom']
})
}
return (
<div>
<button onClick={allLightsOn}>All Lights On</button>
<button onClick={allLightsOff}>All Lights Off</button>
</div>
)
}
Service with Response
function SystemInfo() {
const { callServiceWithResponse } = useServiceCall()
const [config, setConfig] = useState(null)
const getConfig = async () => {
const response = await callServiceWithResponse('homeassistant', 'check_config')
setConfig(response)
}
return (
<div>
<button onClick={getConfig}>Check Config</button>
{config && <pre>{JSON.stringify(config, null, 2)}</pre>}
</div>
)
}
Trigger Automation
function AutomationTrigger() {
const { callService } = useServiceCall()
const triggerAutomation = async () => {
await callService('automation', 'trigger', {
entity_id: 'automation.morning_routine',
skip_condition: true
})
}
return <button onClick={triggerAutomation}>Run Morning Routine</button>
}
Send Notification
function NotificationSender() {
const { callService } = useServiceCall()
const [message, setMessage] = useState('')
const sendNotification = async () => {
await callService('notify', 'mobile_app_my_phone', {
message: message,
title: 'Custom Notification',
data: {
push: {
sound: 'default'
}
}
})
setMessage('')
}
return (
<div>
<input
value={message}
onChange={(e) => setMessage(e.target.value)}
placeholder="Enter message"
/>
<button onClick={sendNotification}>Send</button>
</div>
)
}
Combine with Entity Hooks
You can mix useServiceCall with entity-specific hooks:
function HybridControl() {
const { callService } = useServiceCall()
const light = useLight('light.living_room')
// Use entity hook for state
const isOn = light.isOn
// Use custom service call for advanced control
const customEffect = async () => {
await callService('light', 'turn_on', {
entity_id: 'light.living_room',
effect: 'colorloop',
brightness: 150
})
}
return (
<div>
<p>Light is {isOn ? 'on' : 'off'}</p>
<button onClick={customEffect}>Color Loop</button>
</div>
)
}
Error Handling
Service calls include automatic retry logic with exponential backoff:
function RobustControl() {
const { callService } = useServiceCall()
const [error, setError] = useState(null)
const handleAction = async () => {
try {
setError(null)
await callService('light', 'turn_on', {
entity_id: 'light.living_room'
})
} catch (err) {
setError(err.message)
}
}
return (
<div>
<button onClick={handleAction}>Turn On</button>
{error && <p style={{ color: 'red' }}>{error}</p>}
</div>
)
}
Configuration
Retry behavior can be configured in the HAProvider:
<HAProvider
url="http://homeassistant.local:8123"
options={{
serviceRetry: {
maxAttempts: 5,
baseDelay: 500,
exponentialBackoff: true,
maxDelay: 10000
}
}}
>
<App />
</HAProvider>
When to Use
Use useServiceCall when:
- Calling services on multiple entities at once
- Working with custom integrations
- Triggering automations or scripts
- Sending notifications
- Calling services not covered by entity hooks
Use entity-specific hooks when:
- Working with a single entity
- You need reactive state updates
- The entity type has a dedicated hook
- You want type-safe methods and attributes
Notes
- Service calls are not entity-specific, so you must specify
entity_idin the data - The hook automatically includes retry logic for failed calls
- Errors are thrown as
ServiceCallErrororConnectionError - Service calls don't automatically update entity state - use entity hooks for reactive updates