import axios, { AxiosError } from 'axios'; import { HaArea, HaEntity } from '@/types/types'; // CONFIGURAZIONE const HA_API_URL = process.env.EXPO_PUBLIC_HA_API_URL; const HA_TOKEN = process.env.EXPO_PUBLIC_HA_TOKEN; // Crea un'istanza di axios per Home Assistant const haApi = axios.create({ baseURL: HA_API_URL, headers: { 'Authorization': `Bearer ${HA_TOKEN}`, 'Content-Type': 'application/json', }, timeout: 5000, // 5 secondi di timeout }); haApi.interceptors.request.use((config) => { console.log(`[HOME ASSISTANT API REQUEST] ${config.method?.toUpperCase()} ${config.url}`); return config; }); /* * Connection test */ export const testHaConnection = async (): Promise<{ success: boolean; message: string }> => { // Controlla se le variabili d'ambiente sono caricate if (!HA_API_URL || !HA_TOKEN) { console.error("Variabili d'ambiente per Home Assistant non trovate. Assicurati che EXPO_PUBLIC_HA_API_URL and EXPO_PUBLIC_HA_TOKEN siano definite nel file .env"); return { success: false, message: "Configurazione API per Home Assistant mancante." }; } try { const response = await haApi.get('/'); // Se la risposta è OK, HA restituisce un JSON con 'message' if (response.status === 200 && response.data.message) { return { success: true, message: response.data.message }; } return { success: false, message: "Risposta inattesa dal server Home Assistant." }; } catch (error) { const axiosError = error as AxiosError; if (axiosError.code === 'ECONNABORTED' || axiosError.message.includes('timeout')) { return { success: false, message: "Timeout: Il server non risponde (IP errato o server offline)." }; } if (axiosError.response) { // Errori con una risposta dal server (es. 401, 404) if (axiosError.response.status === 401) { return { success: false, message: "Errore 401: Token non autorizzato. Controlla il Long-Lived Token." }; } if (axiosError.response.status === 404) { return { success: false, message: "Errore 404: Verifica la configurazione di Home Assistant." }; } return { success: false, message: `Errore server: Status ${axiosError.response.status}` }; } else if (axiosError.request) { // Errori di rete (la richiesta è partita ma non ha ricevuto risposta) return { success: false, message: `Errore di rete: Impossibile raggiungere ${HA_API_URL}` }; } else { // Errore generico return { success: false, message: `Errore sconosciuto: ${axiosError.message}` }; } } }; // Fetch Home Assistant Areas export const getHaAreas = async (): Promise => { try { const response = await haApi.post('/template', { "template": ` [ {%- for area_id in areas() %} {%- set area_name = area_name(area_id) %} {%- set f_id = floor_id(area_name) %} {%- set f_name = floor_name(f_id) %} { "id": "{{ area_id }}", "name": "{{ area_name }}", "floor_id": {% if f_id != None %}"{{ f_id }}"{% else %}null{% endif %}, "floor_name": {% if f_name != None %}"{{ f_name }}"{% else %}null{% endif %}, "device_count": {{area_devices(area_id)|count}} }{% if not loop.last %},{% endif %} {%- endfor %} ] ` }); const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data; // console.log("Aree recuperate da Home Assistant:", data); return data; } catch (error) { console.error("Errore recupero aree:", error); return []; // Restituisce un array vuoto in caso di errore } }; // Fetch Home Assistant Entities by Area export const getHaEntitiesByArea = async (areaId: string): Promise => { try { const response = await haApi.post('/template', { "template": ` [ {%- set area_entities = area_entities('${areaId}') %} {%- for entity_id in area_entities %} { "entity_id": {{ entity_id | tojson }}, "name": {{ state_attr(entity_id, 'friendly_name') | tojson }}, "state": {{ states(entity_id) | tojson }} }{% if not loop.last %},{% endif %} {%- endfor %} ] ` }); const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data; // console.log(`Entità recuperate per l'area ${areaId}:`, data); return data; } catch (error) { console.error(`Errore recupero entità per l'area ${areaId}:`, error); return []; // Restituisce un array vuoto in caso di errore } }; // Toggle Home Assistant Entity export const toggleHaEntity = async (entityId: string): Promise => { try { const domain = entityId.split('.')[0]; await haApi.post('/services/' + domain + '/toggle', { entity_id: entityId }); return true; } catch (error) { console.error(`Errore toggle ${entityId}:`, error); return false; } };