I built a small setup where I can talk to a virtual assistant (“Jarvis”) via Telegram, and it can query Home Assistant entities and call services (turn on/off lights, open/close covers, adjust climate).
What it does (examples)
• “What lights are on in the dining room?”
→ It checks light.* entities + friendly names and replies with what’s currently ON.
• “Turn on by bed strip light”
→ Calls light.turn_on for the matching entity.
• “Set bedroom AC to 21°C”
→ Calls climate.set_temperature and confirms the new setpoint.
• Presence checks: “Are we home?”
→ Reads person.* / device_tracker.* states (e.g., person.sergio_sa: home).
Why this is useful
• Fast control from chat (especially on mobile / iPad).
• Natural language → entity/service calls.
• Works well when you have limited bandwidth (e.g., while traveling).
• I can also ask for explanations like: “Is the bedroom AC configured well given indoor vs outdoor temperature?” and then apply changes.
Safety / guardrails (important)
To avoid accidental actions, I added a couple of constraints:
• Domain allowlist: only allow control of light, cover, and climate.
• Entity exclusions: ability to exclude specific entities from control (e.g., one dining table channel I don’t want automated).
• Telegram group is mention-only, and command access is restricted to my user.
Technical overview (high level)
• Assistant runs on a small home server (NUC).
• It uses Home Assistant’s REST API: • Read: GET /api/states (and GET /api/states/<entity_id>)
• Control: POST /api/services// (e.g., light/turn_on, cover/close_cover, climate/set_temperature)
• Authentication uses a Long-Lived Access Token created in Home Assistant.
Notes / next steps
• I’m exploring a better scheduling approach: for “turn off lights if I fall asleep”, Home Assistant automations are more reliable than trying to schedule via the assistant itself.
• Next improvement would be an entity “room map” (areas/labels) so “dining room” doesn’t depend on naming conventions.
If anyone’s interested, I can share more details on the guardrails and matching logic (friendly name + entity_id search), and how I keep it safe in group chats.