- Node.js 20.9.0 or higher
- PostgreSQL database (local or Neon cloud)
- MQTT broker (optional, for device integration)
npm installCreate a .env file in the project root:
# Database (choose one)
# Option A: Local PostgreSQL
DATABASE_URL=postgresql://user@localhost:5432/gansytems
# Option B: Neon Cloud
# DATABASE_URL=postgresql://user:pass@ep-xxx.neon.tech/dbname?sslmode=require
# MQTT (optional)
MQTT_BROKER_URL=mqtts://your-broker.hivemq.cloud:8883
MQTT_USERNAME=your_username
MQTT_PASSWORD=your_password
# Environment
NODE_ENV=developmentnpm run migrateThis will create:
- All existing tables (users, controllers, channels, etc.)
- New
scheduled_commandstable - New columns in
pest_control_schedulestable
npm run dev:serverThe application will start on http://localhost:3000
You should see:
[Server] Ready on http://0.0.0.0:3000
[MQTT] Connected to broker (if configured)
[Scheduler] Starting scheduled command processor
[Scheduler] Initial run: processed=0, succeeded=0, failed=0
[AutoSchedule] Initial auto-schedule: created 0 commands
- Navigate to a controller detail page
- Scroll to "Scheduled Commands" section
- Click "Schedule" button
- Fill in the form:
- Channel: Select a spray pump or valve
- Action: Turn On
- Date: Today
- Time: 2 minutes from now
- Note: "Test scheduled command"
- Click "Schedule Command"
- Wait 2 minutes and verify execution
Expected Result:
- Command appears in pending list
- At scheduled time, command executes
- Device receives command via MQTT
- Command moves to history with status "executed"
- Navigate to a controller detail page
- Scroll to "Pest Control" → "Spray schedule"
- Set spray pump times:
- Turn on at: 06:00
- Turn off at: 18:00
- Click "Save Schedule"
- Check "Scheduled Commands" panel
Expected Result:
- Two scheduled commands created automatically
- One for turning ON at 06:00
- One for turning OFF at 18:00
- Commands show "Auto-schedule" in note
Check server logs for scheduler activity:
[Scheduler] Starting scheduled command processor
[AutoSchedule] Created spray pump ON command for Controller1 at 2026-04-28T06:00:00Z
[AutoSchedule] Created spray pump OFF command for Controller1 at 2026-04-28T18:00:00Z
[Scheduler] Processed 1 commands: succeeded=1, failed=0
Error: Error: connect ECONNREFUSED
Solution:
- Ensure PostgreSQL is running
- Check DATABASE_URL is correct
- Verify database exists:
psql -l
Warning: [MQTT] MQTT_BROKER_URL not set — MQTT client disabled.
Solution:
- This is normal if MQTT is not configured
- Features work without MQTT (commands stored in database)
- To enable MQTT, set MQTT_BROKER_URL in .env
Issue: No scheduler logs appear
Solution:
- Check server started with
npm run dev:server(notnpm run dev) - Look for
[Scheduler] Startingmessage - Restart server if needed
Error: Migration failed
Solution:
- Check DATABASE_URL is correct
- Ensure database exists
- Check database user has CREATE TABLE permissions
- Try running migrations manually:
npx tsx scripts/migrate.ts
# Start development server (with scheduler)
npm run dev:server
# Start Next.js dev server only (no scheduler)
npm run dev
# Build for production
npm run build
# Start production server
npm start
# Run tests
npm test
# Run tests in watch mode
npm test:watch
# Run migrations
npm run migrate
# Test new features
npx tsx scripts/test-new-features.ts
# Test scheduler manually
npx tsx scripts/test-scheduler.ts.
├── app/ # Next.js app directory
│ ├── api/ # API routes
│ │ ├── channels/[id]/
│ │ │ └── scheduled-commands/ # NEW: Schedule commands
│ │ ├── scheduled-commands/[id]/ # NEW: Cancel commands
│ │ └── controllers/[id]/
│ │ └── pest-schedule/ # UPDATED: Auto schedule
│ └── dashboard/ # Dashboard pages
├── src/
│ ├── components/ # React components
│ │ └── dashboard/
│ │ └── controller-detail.tsx # UPDATED: New panels
│ ├── lib/
│ │ ├── db/
│ │ │ └── schema.ts # UPDATED: New tables
│ │ ├── services/
│ │ │ ├── scheduled-command.service.ts # NEW
│ │ │ ├── auto-schedule.service.ts # NEW
│ │ │ └── pest.service.ts # UPDATED
│ │ ├── scheduler.ts # NEW: Background worker
│ │ ├── types.ts # UPDATED: New types
│ │ └── validators.ts # UPDATED: New schemas
├── drizzle/ # Database migrations
│ ├── 0001_add_scheduled_commands.sql # NEW
│ └── 0002_add_spray_pump_schedule.sql # NEW
├── scripts/
│ ├── migrate.ts # Migration runner
│ ├── test-new-features.ts # NEW: Feature tests
│ └── test-scheduler.ts # NEW: Scheduler test
└── server.ts # UPDATED: Scheduler init
POST /api/channels/:id/scheduled-commands
- Create a scheduled command
- Body:
{ desiredBooleanState, note, scheduledFor } - Returns: Created scheduled command
DELETE /api/scheduled-commands/:id
- Cancel a pending scheduled command
- Returns: Updated scheduled command
PUT /api/controllers/:id/pest-schedule
- Now accepts
sprayPumpStartTimeandsprayPumpEndTime - Triggers auto-schedule processing
- Returns: Updated schedule
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
MQTT_BROKER_URL |
No | MQTT broker URL (optional) |
MQTT_USERNAME |
No | MQTT username (if broker requires) |
MQTT_PASSWORD |
No | MQTT password (if broker requires) |
NODE_ENV |
No | Environment (development/production) |
PORT |
No | Server port (default: 3000) |
HOSTNAME |
No | Server hostname (default: 0.0.0.0) |
- ✅ Application is running
- ✅ Features are tested
- 📱 Connect your Arduino/ESP32 device
- 🔧 Configure MQTT for real-time updates
- 📊 Monitor scheduler logs
- 🚀 Deploy to production
- Documentation: See
*.mdfiles in project root - Test Report: See
TEST_REPORT.md - Feature Docs: See
SCHEDULED_COMMANDS.mdandAUTO_SPRAY_SCHEDULE.md - Device Integration: See
DEVICE_INTEGRATION.md
See railway.json for Railway deployment configuration.
For other platforms:
- Set environment variables
- Run
npm run build - Run
npm start - Ensure database is accessible
- Configure MQTT broker
Ready to go! 🚀
Your scheduled commands and auto spray schedule features are fully functional and ready for use.