Production-ready system for remotely controlling an elevator unlock relay through an ESP32 device. The system includes a backend API, cross-platform mobile/web applications, and ESP32 firmware.
βββββββββββββββββββ βββββββββββββββββββ
β Mobile App ββββββββββΊβ Backend API β
β (Android/iOS) β HTTPS β (NestJS) β
βββββββββββββββββββ ββββββββββ¬βββββββββ
β
βββββββββββββββββββ β
β Web App ββββββββββββββββββββ€
β (Browser) β HTTPS β
βββββββββββββββββββ β
β HTTPS
ββββββββββΌβββββββββ
β ESP32 Device β
β (Firmware) β
ββββββββββ¬βββββββββ
β
ββββββββΌβββββββ
β LED/Relay β
β (Control) β
βββββββββββββββ
- Tech: NestJS + TypeScript + PostgreSQL + Prisma
- Features: JWT auth, role-based access, device management, switch control API
- Port: 3000 (default)
- Tech: Angular + Ionic + Capacitor
- Platforms: Web, Android, iOS (single codebase)
- Features: Manual control, GPS/WiFi auto-unlock, admin dashboard
- Tech: Arduino framework + PlatformIO
- Features: Server polling, PULSE mode, LED/relay control
Quick start with Docker:
docker-compose up -dAccess:
- Web App: http://localhost:8080
- API: http://localhost:3000
- Default login: admin@remotecon.local / admin123
For detailed Docker instructions, see DOCKER.md.
cd backend
npm install
cp .env.example .env
# Edit .env with your database credentials
npm run prisma:generate
npm run migrate
npm run seed
npm run start:devDefault admin: admin@remotecon.local / admin123
Web version:
cd app
npm install
npm start
# Open http://localhost:8100Android/iOS:
npm install
ionic build
npx cap sync android # or ios
npx cap open android # or ioscd esp32
# Edit src/config.h with WiFi and server details
pio run --target upload
pio device monitorDATABASE_URL="postgresql://user:pass@localhost:5432/remotecon"
JWT_ACCESS_SECRET="your-secret-key"
JWT_REFRESH_SECRET="your-refresh-secret"
PORT=3000Edit app/src/environments/environment.ts:
apiUrl: 'http://localhost:3000/api' // Your backend URLEdit esp32/src/config.h:
#define WIFI_SSID "YourWiFi"
#define WIFI_PASSWORD "password"
#define SERVER_URL "http://192.168.1.100:3000/api"
#define DEVICE_KEY "test-device-key-12345"- β JWT access + refresh tokens (15min / 7day)
- β Bcrypt password hashing
- β Rate limiting on auth endpoints (5 req/min)
- β Role-based authorization (USER, ADMIN)
- β Device authentication via deviceKey
- β User approval workflow (admin must approve new registrations)
- Register and login (requires admin approval)
- Manual switch enable/disable
- GPS auto-unlock (20 min when arriving home)
- WiFi auto-unlock (10 min when connecting to home WiFi)
- Persistent notification with "Turn Off" button
- Configure home location and WiFi networks
- Approve/reject user registrations
- View all devices and their status
- Monitor last ESP32 poll time
- View current switch state per device
- OFF: Switch/LED off
- PULSE: Toggle at intervals (e.g., 500ms ON every 10s)
- CONTINUOUS: Stay on (not currently used)
Backend:
cd backend
npm test
npm run test:covFrontend:
cd app
npm testIntegration:
- Start backend
- Start frontend (web or mobile)
- Register user β Admin approves β Login
- Enable switch β ESP32 LED lights up
- Verify pulse timing matches settings
remotecon/
βββ backend/ # NestJS backend
β βββ prisma/ # Database schema & migrations
β βββ src/
β β βββ auth/ # Authentication module
β β βββ users/ # User management
β β βββ devices/ # Device & switch control
β β βββ prisma/ # Prisma service
β βββ README.md
βββ app/ # Angular + Ionic frontend
β βββ src/
β β βββ app/
β β β βββ services/ # API, auth, switch services
β β β βββ guards/ # Route guards
β β β βββ pages/ # UI pages/components
β β βββ environments/
β βββ android/ # Android platform
β βββ ios/ # iOS platform
β βββ README.md
βββ esp32/ # ESP32 firmware
β βββ src/
β β βββ main.cpp # Main firmware code
β β βββ config.h # Configuration
β βββ platformio.ini # PlatformIO config
β βββ README.md
βββ README.md # This file
- Backend first: Set up database, run migrations, seed data
- Test API: Use Postman/curl to test endpoints
- Frontend: Connect to backend, test auth flow
- ESP32: Configure device credentials, test polling
- Integration: Complete end-to-end flow
| Feature | Web | Android | iOS |
|---|---|---|---|
| Auth & Manual Control | β | β | β |
| GPS Auto-Unlock | β | β | β |
| WiFi Auto-Unlock | β | β | |
| Notifications | β | β | β |
| Admin Dashboard | β | β | β |
Backend won't start:
- Check PostgreSQL is running
- Verify DATABASE_URL in .env
- Run migrations:
npm run migrate
Frontend can't connect:
- Check apiUrl in environment files
- Ensure backend is running
- Verify CORS settings in backend
ESP32 not polling:
- Check WiFi credentials
- Verify SERVER_URL is reachable from ESP32 network
- Check device_key matches database
- View serial monitor for errors
GPS/WiFi not working:
- Mobile only feature (won't work on web)
- Check platform permissions granted
- iOS requires special entitlements for WiFi SSID
- Deploy to cloud (Heroku, AWS, DigitalOcean)
- Use managed PostgreSQL
- Enable HTTPS
- Set strong JWT secrets
- Configure CORS for frontend URL
- Web: Build and deploy to static hosting (Netlify, Vercel)
- Android: Build APK/AAB, upload to Play Store
- iOS: Archive in Xcode, upload to App Store
- Use production server URL (HTTPS recommended)
- Store device credentials securely
- Add watchdog timer
- Use reliable power supply
- Replace LED with actual relay for elevator control
MIT
For issues or questions:
- Check component-specific READMEs (backend/, app/, esp32/)
- Review troubleshooting sections
- Check serial monitor output (ESP32)
- Verify network connectivity between components