#!/usr/bin/env node // Génère le squelette du workflow "EVCS Solar Forecast V1" : récupération de la // courbe horaire Forecast.Solar (abonnement Professional) et publication dans // les helpers du bilan. // // Cadence : 15 min. C'est la fréquence de rafraîchissement de la prévision // elle-même — l'API précise qu'interroger plus souvent n'a aucun intérêt. // 96 appels par jour pour un quota de 300 par heure. // // La clé d'API n'apparaît NULLE PART ici : elle est lue dans un helper Home // Assistant par le snapshot, et l'URL est assemblée par BUILD_FORECAST_URL. 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 nodes = [ { name: 'Schedule Forecast', type: 'n8n-nodes-base.scheduleTrigger', typeVersion: 1.2, position: [0, 0], parameters: { rule: { interval: [{ field: 'minutes', minutesInterval: 15 }] } }, }, { name: 'HA Snapshot Forecast', type: 'n8n-nodes-base.httpRequest', typeVersion: 4.2, position: [220, 0], parameters: { method: 'POST', url: `${HA_URL}/api/template`, authentication: 'genericCredentialType', genericAuthType: 'httpBearerAuth', sendHeaders: true, headerParameters: { parameters: [ { name: 'Content-Type', value: 'application/json' }, { name: 'Accept', value: 'text/plain' }, ], }, sendBody: true, bodyParameters: { parameters: [{ name: 'template', value: '(injecté depuis src/energy-balance)' }] }, options: { timeout: 15000 }, }, credentials: { httpBearerAuth: HA_CRED }, }, { name: 'BUILD_FORECAST_URL', type: 'n8n-nodes-base.code', typeVersion: 2, position: [440, 0], parameters: { jsCode: '// injecté depuis src/energy-balance/BUILD_FORECAST_URL.js' }, }, { name: 'Forecast.Solar', type: 'n8n-nodes-base.httpRequest', typeVersion: 4.2, position: [660, 0], parameters: { method: 'GET', // URL assemblée par le nœud précédent : la clé ne transite pas par ce fichier. url: '={{ $json.url }}', options: { timeout: 30000, response: { response: { responseFormat: 'text', neverError: true } }, }, }, // Si l'URL est nulle (clé absente, kill-switch), l'appel échoue sans casser // la chaîne : PARSE_FORECAST le détectera et rien ne sera publié. onError: 'continueRegularOutput', }, { name: 'PARSE_FORECAST', type: 'n8n-nodes-base.code', typeVersion: 2, position: [880, 0], parameters: { jsCode: '// injecté depuis src/energy-balance/PARSE_FORECAST.js' }, }, { name: 'BUILD_HA_CALLS_FORECAST', type: 'n8n-nodes-base.code', typeVersion: 2, position: [1100, 0], parameters: { jsCode: '// injecté depuis src/energy-balance/BUILD_HA_CALLS_FORECAST.js' }, }, { name: 'Execute HA Service Forecast', type: 'n8n-nodes-base.httpRequest', typeVersion: 4.2, position: [1320, 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 Forecast': { main: [[{ node: 'HA Snapshot Forecast', type: 'main', index: 0 }]] }, 'HA Snapshot Forecast': { main: [[{ node: 'BUILD_FORECAST_URL', type: 'main', index: 0 }]] }, BUILD_FORECAST_URL: { main: [[{ node: 'Forecast.Solar', type: 'main', index: 0 }]] }, 'Forecast.Solar': { main: [[{ node: 'PARSE_FORECAST', type: 'main', index: 0 }]] }, PARSE_FORECAST: { main: [[{ node: 'BUILD_HA_CALLS_FORECAST', type: 'main', index: 0 }]] }, BUILD_HA_CALLS_FORECAST: { main: [[{ node: 'Execute HA Service Forecast', type: 'main', index: 0 }]] }, }; const workflow = { id: '07P8I349ugna9FH4', name: 'EVCS Solar Forecast V1', nodes, connections, settings: { executionOrder: 'v1', callerPolicy: 'workflowsFromSameOwner' }, staticData: null, }; fs.writeFileSync('workflows/evcs-solar-forecast-v1.json', JSON.stringify(workflow, null, 2) + '\n'); console.log(`Squelette écrit : workflows/evcs-solar-forecast-v1.json (${nodes.length} nodes)`);