fix: Ensure sequential watering by adding explicit OFF for other pots and increased delays

This commit is contained in:
Wizznu 2026-06-02 08:10:01 +07:00
parent b81cc38773
commit f9e89fe826
1 changed files with 66 additions and 0 deletions

View File

@ -199,10 +199,40 @@ const wateringWorker = new Worker(
console.log(` Target: ${sensorData.batasBawah}% → ${sensorData.batasAtas}%`); console.log(` Target: ${sensorData.batasBawah}% → ${sensorData.batasAtas}%`);
} }
// Log queue status for debugging
try {
const queueCounts = await wateringQueue.getJobCounts();
console.log(`\n 📊 QUEUE STATUS AT JOB START:`);
console.log(` Active jobs: ${queueCounts.active}`);
console.log(` Waiting jobs: ${queueCounts.waiting}`);
console.log(` ⚠️ If > 1 active, sequential watering WILL FAIL!`);
} catch (queueError) {
console.warn(` ⚠️ Could not get queue status: ${queueError.message}`);
}
try { try {
const BREAK_BETWEEN_POTS_MS = 30000; // 30 seconds break between pots const BREAK_BETWEEN_POTS_MS = 30000; // 30 seconds break between pots
const potCount = potNumbers.length; const potCount = potNumbers.length;
// ==================== SAFETY: Turn OFF all pot valves at start ====================
// Ensure clean state - all pots OFF before starting sequential watering
console.log(`\n🛡️ SAFETY: Ensuring all pot valves are OFF at start...`);
const safetyOffUpdates = {
mosvet_3: false, // Pot 1
mosvet_4: false, // Pot 2
mosvet_5: false, // Pot 3
mosvet_6: false, // Pot 4
mosvet_7: false, // Pot 5
};
try {
await updateFirebaseSmart('aktuator', safetyOffUpdates, 2);
console.log(`✅ All pot valves confirmed OFF`);
} catch (safetyError) {
console.warn(`⚠️ Safety OFF attempt failed: ${safetyError.message}`);
}
console.log(`⏳ Waiting 2 seconds to stabilize initial state...`);
await sleep(2000); // 2 second delay to ensure all pots really OFF
if (String(type || '').startsWith('waktu_')) { if (String(type || '').startsWith('waktu_')) {
const scheduleTime = job.data.scheduleTime || 'jadwal'; const scheduleTime = job.data.scheduleTime || 'jadwal';
const potText = potCount > 1 ? `pot ${potNumbers.join(', ')}` : `pot ${potNumbers[0]}`; const potText = potCount > 1 ? `pot ${potNumbers.join(', ')}` : `pot ${potNumbers[0]}`;
@ -237,6 +267,21 @@ const wateringWorker = new Worker(
console.log(` ║ POT ${pot} [${potSequence}/${potCount}]`.padEnd(40) + ``); console.log(` ║ POT ${pot} [${potSequence}/${potCount}]`.padEnd(40) + ``);
console.log(` ╚════════════════════════════════════════╝`); console.log(` ╚════════════════════════════════════════╝`);
// IMPORTANT: Turn OFF all OTHER pots first to ensure only current pot is ON
const offOthersUpdates = {};
for (const otherPot of potNumbers) {
if (otherPot !== pot && otherPot >= 1 && otherPot <= 5) {
offOthersUpdates[`mosvet_${otherPot + 2}`] = false; // Turn OFF other pots
}
}
if (Object.keys(offOthersUpdates).length > 0) {
console.log(` 🔴 Turn OFF other pots: ${Object.keys(offOthersUpdates).join(', ')}`);
await updateFirebaseSmart('aktuator', offOthersUpdates, 2);
console.log(` ⏳ Waiting 1 second before turning ON current pot...`);
await sleep(1000); // 1 second delay to ensure all pots OFF before turning ON new one
}
// Turn ON pumps + current pot valve // Turn ON pumps + current pot valve
const onUpdates = {}; const onUpdates = {};
if (pompaAir) onUpdates['mosvet_1'] = true; if (pompaAir) onUpdates['mosvet_1'] = true;
@ -337,6 +382,8 @@ const wateringWorker = new Worker(
// Break 30 detik sebelum pot berikutnya (jika ada) // Break 30 detik sebelum pot berikutnya (jika ada)
if (potIndex < potCount - 1) { if (potIndex < potCount - 1) {
console.log(` ⏳ Waiting 2 seconds to stabilize...`);
await sleep(2000); // 2 second stabilization after pot OFF
console.log(`\n ⏸️ BREAK 30 DETIK sebelum POT ${potNumbers[potIndex + 1]}...`); console.log(`\n ⏸️ BREAK 30 DETIK sebelum POT ${potNumbers[potIndex + 1]}...`);
for (let breakTime = 30; breakTime > 0; breakTime--) { for (let breakTime = 30; breakTime > 0; breakTime--) {
if (breakTime % 10 === 0 || breakTime <= 5) { if (breakTime % 10 === 0 || breakTime <= 5) {
@ -422,6 +469,25 @@ wateringWorker.on('failed', (job, err) => {
console.error(`❌ Worker failed job ${job?.id}:`, err.message); console.error(`❌ Worker failed job ${job?.id}:`, err.message);
}); });
// ⚠️ IMPORTANT: Verify worker concurrency is actually 1
console.log(`\n🔧 WATERING WORKER CONFIGURATION:`);
console.log(` Concurrency: ${config.worker.concurrency} (MUST BE 1 FOR SEQUENTIAL MODE)`);
console.log(` Lock Duration: ${config.worker.lockDuration}ms`);
console.log(` Remove on Complete: Keep 100 completed jobs`);
console.log(` Remove on Fail: Keep 50 failed jobs`);
if (config.worker.concurrency !== 1) {
console.error(`❌ CRITICAL: Worker concurrency is NOT 1! This will break sequential watering!`);
console.error(` Current value: ${config.worker.concurrency}`);
console.error(` Please fix config.worker.concurrency = 1`);
}
console.log(`\n💧 SEQUENTIAL WATERING MODE ENABLED:`);
console.log(` - Pots will be watered ONE AT A TIME`);
console.log(` - 30 second break between each pot`);
console.log(` - Applies to: Jadwal (Waktu Mode) + Threshold (Sensor Mode)`);
console.log(` - Only 1 job can run at a time (concurrency=1)\n`);
// ==================== WAKTU MODE (TIME SCHEDULER) ==================== // ==================== WAKTU MODE (TIME SCHEDULER) ====================
let lastScheduleCheck = {}; let lastScheduleCheck = {};