fix: gridAllowedBySoc + nightTakeoverLatched - autorise HC nuit et libère takeover après charge
This commit is contained in:
161
tools/n8n-rest-update-test.mjs
Normal file
161
tools/n8n-rest-update-test.mjs
Normal file
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const N8N_URL = process.env.N8N_URL || 'https://n8n.airtria.pro';
|
||||
const N8N_API_KEY = process.env.N8N_API_KEY;
|
||||
const WORKFLOW_ID = process.env.WORKFLOW_ID || 'ATswvGfG4KJUls0K';
|
||||
|
||||
if (!N8N_API_KEY) {
|
||||
console.error('❌ Erreur: N8N_API_KEY non défini');
|
||||
console.error(' Exportez la variable: export N8N_API_KEY="votre_token"');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const headers = {
|
||||
'X-N8N-API-KEY': N8N_API_KEY,
|
||||
'Content-Type': 'application/json'
|
||||
};
|
||||
|
||||
async function main() {
|
||||
console.log('=== Test PUT workflow n8n ===\n');
|
||||
console.log(`URL: ${N8N_URL}/api/v1/workflows/${WORKFLOW_ID}`);
|
||||
console.log(`Workflow ID: ${WORKFLOW_ID}\n`);
|
||||
|
||||
// 1. Lire le workflow
|
||||
console.log('1️⃣ Lecture du workflow via GET...');
|
||||
let getResponse;
|
||||
try {
|
||||
getResponse = await fetch(`${N8N_URL}/api/v1/workflows/${WORKFLOW_ID}`, {
|
||||
method: 'GET',
|
||||
headers
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('❌ Erreur réseau GET:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
if (!getResponse.ok) {
|
||||
console.error(`❌ GET échoué: ${getResponse.status} ${getResponse.statusText}`);
|
||||
const text = await getResponse.text();
|
||||
console.error('Réponse:', text);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const workflow = await getResponse.json();
|
||||
console.log(`✅ Workflow lu: "${workflow.name}" (${workflow.nodes?.length || 0} nodes)`);
|
||||
|
||||
// 2. Sauvegarde locale
|
||||
const backupPath = `./backup-workflow-${WORKFLOW_ID}-${Date.now()}.json`;
|
||||
console.log(`\n2️⃣ Sauvegarde locale: ${backupPath}`);
|
||||
const fs = await import('fs');
|
||||
fs.writeFileSync(backupPath, JSON.stringify(workflow, null, 2));
|
||||
console.log('✅ Backup créé');
|
||||
|
||||
// 3. Reconstruire body propre (settings minimal)
|
||||
const body = {
|
||||
name: workflow.name,
|
||||
nodes: workflow.nodes,
|
||||
connections: workflow.connections,
|
||||
settings: {
|
||||
executionOrder: workflow.settings?.executionOrder || 'v1',
|
||||
callerPolicy: workflow.settings?.callerPolicy || 'workflowsFromSameOwner'
|
||||
},
|
||||
staticData: workflow.staticData
|
||||
};
|
||||
|
||||
console.log('\n3️⃣ Body reconstruit (champs inclus):');
|
||||
console.log(' - name:', body.name);
|
||||
console.log(' - nodes:', body.nodes?.length || 0);
|
||||
console.log(' - connections:', body.connections ? 'présent' : 'absent');
|
||||
console.log(' - settings:', JSON.stringify(body.settings));
|
||||
console.log(' - staticData:', body.staticData ? 'présent' : 'absent');
|
||||
|
||||
// 4. Appliquer les corrections
|
||||
console.log('\n4️⃣ Application des corrections...');
|
||||
|
||||
// Trouver le node BATTERY_CLOUD_LOCKS
|
||||
const batteryCloudLocksNode = body.nodes.find(n => n.name === 'BATTERY_CLOUD_LOCKS');
|
||||
if (!batteryCloudLocksNode) {
|
||||
console.error('❌ Node BATTERY_CLOUD_LOCKS non trouvé');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
let jsCode = batteryCloudLocksNode.parameters.jsCode;
|
||||
|
||||
// Fix 1: gridAllowedBySoc - ajouter context.profile === 'night_hc'
|
||||
const fix1Old = 'const gridAllowedBySoc = parsed.soc <= 35 || strategy.forceGridRequested;';
|
||||
const fix1New = `const gridAllowedBySoc =
|
||||
strategy.forceGridRequested ||
|
||||
context.profile === 'night_hc' ||
|
||||
parsed.soc <= 35;`;
|
||||
|
||||
if (jsCode.includes(fix1Old)) {
|
||||
jsCode = jsCode.replace(fix1Old, fix1New);
|
||||
console.log(' ✅ Fix 1 appliqué: gridAllowedBySoc');
|
||||
} else {
|
||||
console.log(' ⚠️ Fix 1: pattern non trouvé (déjà appliqué?)');
|
||||
}
|
||||
|
||||
// Fix 2: nightTakeoverLatched - libérer quand charge terminée (soc >= 50)
|
||||
const fix2Old = `const nightTakeoverLatched =
|
||||
nightSessionActive &&
|
||||
nightTakeoverPrev &&
|
||||
parsed.soc < NIGHT_TAKEOVER_RELEASE_SOC_PCT;`;
|
||||
|
||||
const fix2New = `const vehicleChargeCompleted =
|
||||
!parsed.evcsChargingSwitchOn &&
|
||||
parsed.soc >= 50;
|
||||
const nightTakeoverLatched =
|
||||
nightSessionActive &&
|
||||
nightTakeoverPrev &&
|
||||
(
|
||||
parsed.soc < NIGHT_TAKEOVER_RELEASE_SOC_PCT ||
|
||||
vehicleChargeCompleted
|
||||
);`;
|
||||
|
||||
if (jsCode.includes(fix2Old)) {
|
||||
jsCode = jsCode.replace(fix2Old, fix2New);
|
||||
console.log(' ✅ Fix 2 appliqué: nightTakeoverLatched');
|
||||
} else {
|
||||
console.log(' ⚠️ Fix 2: pattern non trouvé (déjà appliqué?)');
|
||||
}
|
||||
|
||||
batteryCloudLocksNode.parameters.jsCode = jsCode;
|
||||
|
||||
// 5. Tenter PUT
|
||||
console.log('\n5️⃣ Tentative PUT...');
|
||||
let putResponse;
|
||||
try {
|
||||
putResponse = await fetch(`${N8N_URL}/api/v1/workflows/${WORKFLOW_ID}`, {
|
||||
method: 'PUT',
|
||||
headers,
|
||||
body: JSON.stringify(body)
|
||||
});
|
||||
} catch (err) {
|
||||
console.error('❌ Erreur réseau PUT:', err.message);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const putStatus = putResponse.status;
|
||||
const putStatusText = putResponse.statusText;
|
||||
const putResponseText = await putResponse.text();
|
||||
|
||||
console.log(`\n📊 Résultat PUT:`);
|
||||
console.log(` Status: ${putStatus} ${putStatusText}`);
|
||||
|
||||
if (putResponse.ok) {
|
||||
console.log('✅ PUT réussi!');
|
||||
const putJson = JSON.parse(putResponseText);
|
||||
console.log(` Workflow mis à jour: "${putJson.name}"`);
|
||||
} else {
|
||||
console.log('❌ PUT REFUSÉ par n8n');
|
||||
console.log('\n📄 Erreur exacte:');
|
||||
try {
|
||||
const errorJson = JSON.parse(putResponseText);
|
||||
console.log(JSON.stringify(errorJson, null, 2));
|
||||
} catch {
|
||||
console.log(putResponseText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user