Skip to main content
Glama
homeassistant.ts4.6 kB
import https from 'https'; import http from 'http'; import { Config, HomeAssistantStatus, HomeAssistantEntity } from '../types.js'; let config: Config; export function initHomeAssistant(cfg: Config): void { config = cfg; } async function homeAssistantRequest(endpoint: string, method: string = 'GET', body?: any): Promise<any> { if (!config.homeAssistantHost || !config.homeAssistantToken) { throw new Error('Home Assistant is not configured'); } const protocol = config.homeAssistantUseHttps ? 'https' : 'http'; const url = `${protocol}://${config.homeAssistantHost}:${config.homeAssistantPort}/api${endpoint}`; const httpModule = config.homeAssistantUseHttps ? https : http; return new Promise((resolve, reject) => { const options: any = { method, headers: { 'Authorization': `Bearer ${config.homeAssistantToken}`, 'Content-Type': 'application/json', }, }; // Allow self-signed certificates for HTTPS if (config.homeAssistantUseHttps) { options.rejectUnauthorized = false; } const req = httpModule.request(url, options, (res) => { let data = ''; res.on('data', (chunk) => { data += chunk; }); res.on('end', () => { if (res.statusCode && res.statusCode >= 200 && res.statusCode < 300) { try { resolve(JSON.parse(data)); } catch { resolve(data); } } else { reject(new Error(`Home Assistant API error: ${res.statusCode} - ${data}`)); } }); }); req.on('error', (error) => { reject(error); }); if (body) { req.write(JSON.stringify(body)); } req.end(); }); } // Level 1 - Monitor export async function getHomeAssistantStatus(): Promise<HomeAssistantStatus> { try { // Get configuration const configData = await homeAssistantRequest('/config'); // Get all entity states const states = await homeAssistantRequest('/states'); // Count automations (entities that start with 'automation.') const automations = states.filter((entity: any) => entity.entity_id.startsWith('automation.') ); // Get unique domains const domains: string[] = [...new Set(states.map((entity: any) => entity.entity_id.split('.')[0] ))].sort() as string[]; return { version: configData.version || 'unknown', location: configData.location_name || 'Home', entities_count: states.length, automations_count: automations.length, domains, }; } catch (error) { throw new Error(`Failed to get Home Assistant status: ${(error as Error).message}`); } } export async function listHomeAssistantEntities(domain?: string): Promise<{ entities: HomeAssistantEntity[] }> { try { const states = await homeAssistantRequest('/states'); let filteredStates = states; if (domain) { filteredStates = states.filter((entity: any) => entity.entity_id.startsWith(`${domain}.`) ); } const entities = filteredStates.map((entity: any) => ({ entity_id: entity.entity_id, state: entity.state, friendly_name: entity.attributes?.friendly_name || entity.entity_id, last_updated: entity.last_updated, attributes: entity.attributes || {}, })); return { entities }; } catch (error) { throw new Error(`Failed to list Home Assistant entities: ${(error as Error).message}`); } } export async function getHomeAssistantEntity(entity_id: string): Promise<HomeAssistantEntity> { try { const entity = await homeAssistantRequest(`/states/${encodeURIComponent(entity_id)}`); return { entity_id: entity.entity_id, state: entity.state, friendly_name: entity.attributes?.friendly_name || entity.entity_id, last_updated: entity.last_updated, attributes: entity.attributes || {}, }; } catch (error) { throw new Error(`Failed to get entity ${entity_id}: ${(error as Error).message}`); } } // Level 3 - Configure export async function getHomeAssistantConfig(): Promise<Record<string, any>> { try { const configData = await homeAssistantRequest('/config'); return configData; } catch (error) { throw new Error(`Failed to get Home Assistant config: ${(error as Error).message}`); } } export async function getHomeAssistantErrorLog(): Promise<{ log: string }> { try { const log = await homeAssistantRequest('/error_log'); return { log }; } catch (error) { throw new Error(`Failed to get Home Assistant error log: ${(error as Error).message}`); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/bshandley/homelab-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server