Skip to content

ar-dehghan-a/smart-pot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

88 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Smart Pot - IoT Device Management System

A complete IoT device management system with ESP32 devices, Node.js TypeScript backend, PostgreSQL database, and MQTT communication.

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    MQTT     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    REST API     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   ESP32     β”‚ ──────────► β”‚   Backend   β”‚ ──────────────► β”‚   Clients   β”‚
β”‚  Devices    β”‚             β”‚ (Node.js)   β”‚                 β”‚ (Web/Mobile)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                            β”‚                              β”‚
     β”‚                            β”‚                              β”‚
     β–Ό                            β–Ό                              β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”            β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Sensors   β”‚            β”‚   MQTT      β”‚                β”‚   REST API  β”‚
β”‚ (DHT22, etc)β”‚            β”‚   Broker    β”‚                β”‚   Endpoints β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜            β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚
                                β–Ό
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β”‚ PostgreSQL  β”‚
                         β”‚  Database   β”‚
                         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸš€ Quick Start

Prerequisites

  • Node.js >= 20.0.0
  • npm >= 9.0.0
  • Docker and Docker Compose (for PostgreSQL and MQTT broker)
  • ESP32 development board
  • DHT22 temperature/humidity sensor
  • Soil moisture sensor
  • Light sensor
  • Relay modules (for water control)

1. Start Infrastructure Services

Start PostgreSQL and Mosquitto MQTT broker using Docker Compose:

docker compose up -d
# or from repository root (npm workspaces helper)
npm run compose:up

This will start:

  • PostgreSQL on port 5432
  • Mosquitto MQTT broker on port 1883 (MQTT)

2. Backend Setup

  1. Navigate to the backend directory:
cd backend
  1. Install dependencies:
npm install
  1. Create a .env file in the backend directory:
# Server Configuration
NODE_ENV=development
PORT=8000

# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=smart_pot
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres

# MQTT Configuration
MQTT_URL=mqtt://localhost:1883
MQTT_USERNAME=
MQTT_PASSWORD=

# JWT Configuration
JWT_SECRET=your_jwt_secret_key_here_change_in_production
JWT_EXPIRY_HOURS=24

# Telemetry Retention (days)
TELEMETRY_RETENTION_DAYS=30

# Aggregation Worker (cron expression)
AGGREGATION_CRON=0 * * * *
  1. Run database migrations:
npm run migration:run
  1. Start the development server:
npm run dev

The server will run on http://localhost:8000

3. Frontend Setup

  1. Navigate to the frontend directory:
cd frontend
  1. Install dependencies:
npm install
  1. Configure environment variables (optional but recommended). Create a .env file in frontend:
VITE_API_BASE_URL=http://localhost:8000/api/v1
  1. Start the development server:
npm run dev

The web dashboard will be available on http://localhost:5173 (default Vite port).

4. ESP32 Setup

  1. Update the ESP32 configuration in esp32/config.h:

    #define WIFI_SSID "your_wifi_ssid"
    #define WIFI_PASSWORD "your_wifi_password"
    #define MQTT_BROKER "192.168.1.100"  // Your server IP
    #define MQTT_PORT 1883
  2. Upload the ESP32 code using Arduino IDE

  3. Ensure the ESP32 device publishes telemetry to the correct MQTT topics (see MQTT Topics section below)

πŸ“ Project Structure

smart-pot/
β”œβ”€β”€ backend/                    # Node.js TypeScript backend API
β”‚   β”œβ”€β”€ src/                    # Source code
β”‚   β”‚   β”œβ”€β”€ config/             # Configuration (env, swagger, etc.)
β”‚   β”‚   β”œβ”€β”€ controllers/        # Request handlers
β”‚   β”‚   β”œβ”€β”€ db/                 # Database config and entities
β”‚   β”‚   β”‚   β”œβ”€β”€ entities/       # TypeORM entities
β”‚   β”‚   β”‚   └── migrations/     # Database migrations (generated)
β”‚   β”‚   β”œβ”€β”€ dto/                # Request/response validation schemas (Zod)
β”‚   β”‚   β”œβ”€β”€ middlewares/        # Express middlewares
β”‚   β”‚   β”œβ”€β”€ routes/             # API route definitions
β”‚   β”‚   β”œβ”€β”€ services/           # MQTT, logger, graceful shutdown, etc.
β”‚   β”‚   β”œβ”€β”€ utils/              # Helpers and shared utilities
β”‚   β”‚   β”œβ”€β”€ workers/            # Background workers (e.g. aggregation)
β”‚   β”‚   β”œβ”€β”€ app.ts              # Express app setup
β”‚   β”‚   └── server.ts           # Server entry point
β”‚   β”œβ”€β”€ package.json            # Backend dependencies & scripts
β”‚   └── tsconfig.json           # TypeScript configuration
β”‚
β”œβ”€β”€ frontend/                   # React + TypeScript + Vite web dashboard
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ features/           # Feature-based modules (auth, device, profile, home)
β”‚   β”‚   β”œβ”€β”€ components/         # Reusable UI components & layouts (shadcn/ui)
β”‚   β”‚   β”œβ”€β”€ router/             # React Router configuration
β”‚   β”‚   β”œβ”€β”€ lib/                # HTTP client, env helpers, utils
β”‚   β”‚   └── providers/          # Global providers (React Query, theme, auth, etc.)
β”‚   β”œβ”€β”€ public/                 # Static assets & icons
β”‚   └── package.json            # Frontend dependencies & scripts
β”‚
β”œβ”€β”€ esp32/                      # ESP32 Arduino firmware
β”‚   β”œβ”€β”€ esp32.ino               # Main firmware entry
β”‚   β”œβ”€β”€ config.h                # Board- and network-level configuration
β”‚   β”œβ”€β”€ wifi_manager.*          # WiFi connection management
β”‚   β”œβ”€β”€ mqtt_manager.*          # MQTT topics, connection and messaging
β”‚   β”œβ”€β”€ relay_manager.*         # Channel modes, auto config and scheduling
β”‚   β”œβ”€β”€ time_manager.*          # RTC/time utilities
β”‚   β”œβ”€β”€ sms_manager.*           # SMS control interface (SIM800L)
β”‚   β”œβ”€β”€ utils.*                 # Shared helper functions
β”‚   └── README.md               # ESP32 documentation
β”‚
β”œβ”€β”€ mosquitto/                  # Mosquitto MQTT broker configuration
β”‚   └── config/                 # Mosquitto config files
β”œβ”€β”€ docker-compose.yml          # Docker Compose for Postgres + Mosquitto
β”œβ”€β”€ package.json                # Root monorepo config (npm workspaces)
└── README.md                   # This file

πŸ”§ Configuration

Backend Environment Variables

Create backend/.env with the following variables:

# Server Configuration
NODE_ENV=development
PORT=8000

# Database
POSTGRES_HOST=localhost
POSTGRES_PORT=5432
POSTGRES_DB=smart_pot
POSTGRES_USER=postgres
POSTGRES_PASSWORD=postgres

# MQTT Configuration
MQTT_URL=mqtt://localhost:1883
MQTT_USERNAME=              # Optional
MQTT_PASSWORD=              # Optional

# JWT Configuration
JWT_SECRET=your_jwt_secret_key_here_change_in_production
JWT_EXPIRY_HOURS=24

# Telemetry Retention (days)
TELEMETRY_RETENTION_DAYS=30

# Aggregation Worker (cron expression - runs every hour by default)
AGGREGATION_CRON=0 * * * *

ESP32 Configuration

Update esp32/config.h:

// WiFi Configuration
#define WIFI_SSID "your_wifi_ssid"
#define WIFI_PASSWORD "your_wifi_password"

// MQTT Configuration
#define MQTT_BROKER "192.168.1.100"  // Your server IP
#define MQTT_PORT 1883
#define MQTT_USERNAME ""              // Optional
#define MQTT_PASSWORD ""              // Optional

πŸ“‘ MQTT Topics

Device β†’ Backend

  • esp/{deviceId}/telemetry - Telemetry data from device

    {
      "temperature": 25.6,
      "humidity": 60.2,
      "soilMoisture": 450,
      "lightLevel": 1,
      "timestamp": 1640995200
    }
  • esp/{deviceId}/status - Device online/offline status

    {
      "online": true
    }
  • esp/{deviceId}/ack - Command acknowledgments

    {
      "commandId": "uuid",
      "type": "delivery" | "execution",
      "success": true,
      "errorMessage": "optional error message"
    }

Backend β†’ Device

  • esp/{deviceId}/command - Commands sent to device

    {
      "commandId": "uuid",
      "type": "water" | "stop-water" | "set-mode" | "set-profile" | "custom",
      "payload": { ... }
    }

🌐 API Endpoints

All API endpoints are prefixed with /api/v1

Authentication

  • POST /api/v1/auth/signup - Register a new user

    {
      "email": "user@example.com",
      "password": "securepassword",
      "name": "User Name"
    }
  • POST /api/v1/auth/login - Login and get JWT token

    {
      "email": "user@example.com",
      "password": "securepassword"
    }
  • GET /api/v1/auth/me - Get current user info (requires authentication)

Device Management

  • GET /api/v1/devices - List all devices owned by authenticated user

    • Query params: page, limit, search
  • POST /api/v1/devices/pair - Pair a device to authenticated user

    {
      "deviceId": "esp32_001",
      "name": "My Device"
    }
  • GET /api/v1/devices/:deviceId - Get device details with current status

  • PATCH /api/v1/devices/:deviceId - Update device settings

    {
      "name": "Updated Name",
      "mode": "auto" | "manual",
      "profile": { ... }
    }
  • POST /api/v1/devices/:deviceId/unpair - Unpair device from user

Device Status & Telemetry

  • GET /api/v1/devices/:deviceId/status - Get current device status

  • GET /api/v1/devices/:deviceId/history - Get telemetry history

    • Query params: from, to, type (raw or hourly), page, limit
  • POST /api/v1/devices/:deviceId/telemetry - Ingest telemetry data (internal use)

Device Commands

  • POST /api/v1/devices/:deviceId/commands/water - Send water command

    {
      "duration": 30,
      "zone": 1
    }
  • POST /api/v1/devices/:deviceId/commands/stop-water - Stop watering

  • POST /api/v1/devices/:deviceId/commands/set-mode - Change device mode

    {
      "mode": "auto" | "manual"
    }
  • POST /api/v1/devices/:deviceId/channels/auto-config - Set auto mode configuration

    {
      "threshold": 30,
      "durationSec": 300
    }
  • POST /api/v1/devices/:deviceId/commands/custom - Send custom command

    {
      "action": "custom_action",
      "params": { ... }
    }
  • GET /api/v1/devices/:deviceId/commands - Get command history

    • Query params: page, limit, status

Health

  • GET /api/v1/health - Health check endpoint

πŸ§ͺ Testing

API Testing

# Health check
curl http://localhost:8000/api/v1/health

# Sign up
curl -X POST http://localhost:8000/api/v1/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "password123",
    "name": "Test User"
  }'

# Login
curl -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "test@example.com",
    "password": "password123"
  }'

# List devices (requires JWT token)
curl http://localhost:8000/api/v1/devices \
  -H "Authorization: Bearer YOUR_JWT_TOKEN"

# Send water command (requires JWT token)
curl -X POST http://localhost:8000/api/v1/devices/esp32_001/commands/water \
  -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "duration": 30,
    "zone": 1
  }'

πŸš€ Deployment

Local Development

# Start infrastructure
docker compose up -d

# Start backend
cd backend
npm run dev

Production

# Build backend
cd backend
npm run build

# Run migrations
npm run migration:run

# Start production server
npm start

Docker Compose

The project includes Docker Compose configuration for PostgreSQL and Mosquitto:

# Start services
docker compose up -d

# Stop services
docker compose down

# Stop and remove volumes
docker compose down -v

πŸ”’ Security

  • JWT Authentication - Token-based authentication for API endpoints
  • Password Hashing - Bcrypt password hashing
  • CORS Protection - Cross-origin resource sharing configuration
  • Input Validation - Zod schema validation for all requests
  • Security Headers - Helmet security middleware
  • MQTT Authentication - Optional username/password authentication

πŸ“Š Features

  • βœ… User authentication and authorization
  • βœ… Device pairing and management
  • βœ… Real-time telemetry ingestion via MQTT
  • βœ… Telemetry history (raw and hourly aggregated)
  • βœ… Device command system with acknowledgments
  • βœ… Background workers for data aggregation
  • βœ… PostgreSQL database for data persistence
  • βœ… RESTful API with comprehensive endpoints
  • βœ… TypeScript for type safety
  • βœ… Request validation with Zod
  • βœ… Structured logging with Winston

🌍 Frontend Web Dashboard

The frontend workspace provides a modern web dashboard built with React + TypeScript + Vite + shadcn/ui:

  • Authentication: Sign up, sign in, and persistent sessions using JWT.
  • Device overview: Home page with a list of paired devices and high-level status.
  • Device details: Per-device pages showing live status, channel modes, and auto-config.
  • Channels control: Manual channel activation/deactivation and per-channel scheduling UI.
  • Telemetry views: History and report pages with charts for hourly telemetry.
  • User profile: Basic profile and preferences section.

By default the dashboard talks to the backend via VITE_API_BASE_URL (see Frontend Setup).

πŸ“Š Monitoring

Logs

The backend uses Winston for structured logging. Logs are output to the console in development and can be configured for file output in production.

Health Checks

  • GET /api/v1/health - Server health status

Database Migrations

# Generate migration
npm run migration:generate

# Run migrations
npm run migration:run

# Revert last migration
npm run migration:revert

# Show migration status
npm run migration:show

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Make your changes
  4. Run linting and type checking in relevant workspaces (e.g. npm run lint / npm run typecheck inside backend, npm run lint inside frontend)
  5. Commit your changes (git commit -m 'Add amazing feature')
  6. Push to the branch (git push origin feature/amazing-feature)
  7. Open a Pull Request

πŸ“ License

MIT License - see LICENSE file for details.

πŸ†˜ Support

For issues and questions:

  1. Check the documentation in each component
  2. Review the example code
  3. Check the ESP32 README for device-specific issues
  4. Create an issue with detailed information

πŸ”„ Roadmap

  • Database integration for sensor data storage
  • User authentication and authorization
  • Device management and pairing
  • Telemetry ingestion and history
  • Command system with acknowledgments
  • Data aggregation workers
  • Dashboard web interface (React-based web dashboard)
  • Mobile app (React Native or Flutter)
  • Cloud deployment options
  • Advanced analytics and visualization

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors