#!/usr/bin/env node // Génère le squelette du workflow "EVCS Energy Profiles Daily V1" : recalcul // quotidien des profils horaires (consommation, enveloppe de production, taux // de censure) à partir de l'historique Home Assistant. // Le CODE des nodes est injecté depuis src/energy-balance/ par n8n-build.mjs. import fs from 'node:fs'; const HA_CRED = { id: 'uv3sknYYigxBkaVN', name: 'Bearer Auth account 2' }; const HA_URL = 'http://10.10.10.17:8123'; const ENTITIES = [ 'sensor.airtria_mpii_v1_energy_from_inverter_to_ac_out', 'sensor.airtria_mpii_v1_energy_from_ac_in_1_to_ac_out', 'sensor.evcs_hq2239dnt7p_total_energy', 'sensor.gx_device_pv_energy', 'sensor.victron_battery_soc', ].join(','); // Fenêtre demandée : 30 jours. L'API ne renvoie que ce que la rétention // conserve (10 jours au 24/08, 90 une fois la nouvelle rétention accumulée), // donc la fenêtre s'élargira d'elle-même sans rien changer ici. // ⚠️ `end_time` est OBLIGATOIRE : sans lui, /api/history/period ne renvoie // qu'UNE SEULE journée, silencieusement. const HISTORY_URL = "={{ '" + HA_URL + "/api/history/period/' " + '+ new Date(Date.now() - 30 * 86400000).toISOString() ' + "+ '?end_time=' + encodeURIComponent(new Date().toISOString()) " + "+ '&filter_entity_id=" + ENTITIES + "' " + "+ '&minimal_response&significant_changes_only=0' }}"; const nodes = [ { name: 'Schedule Daily', type: 'n8n-nodes-base.scheduleTrigger', typeVersion: 1.2, position: [0, 0], parameters: { rule: { interval: [{ field: 'days', triggerAtHour: 3, triggerAtMinute: 30 }] } }, }, { name: 'HA History', type: 'n8n-nodes-base.httpRequest', typeVersion: 4.2, position: [220, 0], parameters: { method: 'GET', url: HISTORY_URL, authentication: 'genericCredentialType', genericAuthType: 'httpBearerAuth', options: { timeout: 120000, response: { response: { responseFormat: 'text' } }, }, }, credentials: { httpBearerAuth: HA_CRED }, }, { name: 'DAILY_PROFILES', type: 'n8n-nodes-base.code', typeVersion: 2, position: [440, 0], parameters: { jsCode: '// injecté depuis src/energy-balance/DAILY_PROFILES.js' }, }, { name: 'BUILD_HA_CALLS_PROFILES', type: 'n8n-nodes-base.code', typeVersion: 2, position: [660, 0], parameters: { jsCode: '// injecté depuis src/energy-balance/BUILD_HA_CALLS_PROFILES.js' }, }, { name: 'Execute HA Service Profiles', type: 'n8n-nodes-base.httpRequest', typeVersion: 4.2, position: [880, 0], parameters: { method: 'POST', url: `={{ '${HA_URL}/api/services/' + $json.domain + '/' + $json.service }}`, authentication: 'genericCredentialType', genericAuthType: 'httpBearerAuth', sendHeaders: true, headerParameters: { parameters: [ { name: 'Content-Type', value: 'application/json' }, { name: 'accept', value: 'application/json' }, ], }, sendBody: true, specifyBody: 'json', jsonBody: '={{ $json.data }}', options: { timeout: 15000 }, }, credentials: { httpBearerAuth: HA_CRED }, onError: 'continueRegularOutput', }, ]; const connections = { 'Schedule Daily': { main: [[{ node: 'HA History', type: 'main', index: 0 }]] }, 'HA History': { main: [[{ node: 'DAILY_PROFILES', type: 'main', index: 0 }]] }, DAILY_PROFILES: { main: [[{ node: 'BUILD_HA_CALLS_PROFILES', type: 'main', index: 0 }]] }, BUILD_HA_CALLS_PROFILES: { main: [[{ node: 'Execute HA Service Profiles', type: 'main', index: 0 }]] }, }; const workflow = { id: 'N6UaB4ZozsbRPrFb', name: 'EVCS Energy Profiles Daily V1', nodes, connections, settings: { executionOrder: 'v1', callerPolicy: 'workflowsFromSameOwner' }, staticData: null, }; fs.writeFileSync('workflows/evcs-energy-profiles-daily-v1.json', JSON.stringify(workflow, null, 2) + '\n'); console.log(`Squelette écrit : workflows/evcs-energy-profiles-daily-v1.json (${nodes.length} nodes)`);