#!/usr/bin/env node // Génère le squelette du workflow "EVCS Energy Balance V1" (structure, types, // credentials, positions). Le CODE des nodes est ensuite injecté depuis // src/energy-balance/ par tools/n8n-build.mjs — src/ reste la source de vérité. // Rejouable : réécrit le squelette à l'identique. 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 Trigger', type: 'n8n-nodes-base.scheduleTrigger', typeVersion: 1.2, position: [0, 0], parameters: { rule: { interval: [{ field: 'minutes', minutesInterval: 5 }] } }, }, { name: 'HA Snapshot Balance', 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: 'CENSORSHIP', type: 'n8n-nodes-base.code', typeVersion: 2, position: [440, -120], parameters: { jsCode: '// injecté depuis src/energy-balance/CENSORSHIP.js' }, }, { name: 'RESOURCE_ESTIMATE', type: 'n8n-nodes-base.code', typeVersion: 2, position: [440, 120], parameters: { jsCode: '// injecté depuis src/energy-balance/RESOURCE_ESTIMATE.js' }, }, { name: 'PREPARE_BALANCE', type: 'n8n-nodes-base.code', typeVersion: 2, position: [660, 120], parameters: { jsCode: '// injecté depuis src/energy-balance/PREPARE_BALANCE.js' }, }, { name: 'BALANCE', type: 'n8n-nodes-base.code', typeVersion: 2, position: [880, 120], parameters: { jsCode: '// injecté depuis src/energy-balance/BALANCE.js' }, }, { name: 'BUILD_HA_CALLS', type: 'n8n-nodes-base.code', typeVersion: 2, position: [1100, 120], parameters: { jsCode: '// injecté depuis src/energy-balance/BUILD_HA_CALLS.js' }, }, { name: 'Execute HA Service Balance', type: 'n8n-nodes-base.httpRequest', typeVersion: 4.2, position: [1320, 120], 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', }, ]; // Le snapshot alimente DEUX branches : CENSORSHIP qualifie l'instant présent, // RESOURCE_ESTIMATE projette la production. PREPARE_BALANCE les réunit. const connections = { 'Schedule Trigger': { main: [[{ node: 'HA Snapshot Balance', type: 'main', index: 0 }]] }, 'HA Snapshot Balance': { main: [[ { node: 'CENSORSHIP', type: 'main', index: 0 }, { node: 'RESOURCE_ESTIMATE', type: 'main', index: 0 }, ]], }, RESOURCE_ESTIMATE: { main: [[{ node: 'PREPARE_BALANCE', type: 'main', index: 0 }]] }, PREPARE_BALANCE: { main: [[{ node: 'BALANCE', type: 'main', index: 0 }]] }, BALANCE: { main: [[{ node: 'BUILD_HA_CALLS', type: 'main', index: 0 }]] }, BUILD_HA_CALLS: { main: [[{ node: 'Execute HA Service Balance', type: 'main', index: 0 }]] }, }; const workflow = { id: 'QoSfPeyGq35orF1K', name: 'EVCS Energy Balance V1', nodes, connections, settings: { executionOrder: 'v1', callerPolicy: 'workflowsFromSameOwner' }, staticData: null, }; fs.writeFileSync('workflows/evcs-energy-balance-v1.json', JSON.stringify(workflow, null, 2) + '\n'); console.log(`Squelette écrit : workflows/evcs-energy-balance-v1.json (${nodes.length} nodes)`); console.log('→ node tools/n8n-build.mjs workflows/evcs-energy-balance-v1.json');