VAYU - OpenAir is a public repository of open software, open algorithms and open data collected on air pollution through hyperlocal mapping of air pollution in two cities - Patna and Gurgaon.
This joint initiative by UNDP, GIZ, Govt, University of Nottingham, DA, D-Coop and a large number of citizen scientists in India. With open innovation framework, this initiative aims to model an 'Open Digital Stack on Air Pollution' for Indian cities. This initiative leaverages on open source softwares, crowdsources open data, IoT sensors for field data collection, and AI/ML for modeling purposes.
Our endeavor is to prototype 'Open Digital Stack on Air Pollution' that steers collective action across a wide range of stakeholders to combat air pollution. We are building a generalizable and scalable open source model that can be adopted by several cities across the world.
- OS : Ubuntu 22.04
- gcc, g++
- make
- libsqlite3-dev
- zlib1g-dev
- Python 3.10 , python3.10-venv
- Tippecanoe
- Redis
- Node JS v20.x
- Postgress DB v15
- Nginx v1.18.x
- Clone the repository
git clone <repo-url> vayu-openair
-
Environment / secrets update
cd vayu-openair/vayu/mobile_app
nano .env
- Update the API URL
VITE_REACT_API_URL='https://vayuapi.undp.org.in'
- Update the API URL
-
Install Project dependencies
npm install
-
Build the project
npm run build
-
Environment / secrets update
cd vayu-openair/vayu/web_portal
nano .env
- Update the API URL
VITE_REACT_API_URL=https://vayuapi.undp.org.in/device/api/v1 VITE_REACT_API_URL2=https://vayuapi.undp.org.in/mobile/api/v1
- Update the API URL
-
Install Project dependencies
npm install
-
Build the project
npm run build
-
Environment / secrets update
cd vayu-openair/vayu/api
cp config.sample config.py
nano .env
-
Configure Virtual ENV for the project
python3 -m venev venv
source venv/bin/activate
-
Install Project dependencies
pip install -r requirements.txt
-
Prepare log directory
mkdir logs
-
Database migration
python manage.py makemigrations
python manage.py migrate
python manage.py migrate django_celery_beat python manage.py migrate django_celery_result
-
Start Celery as service ( Worker, Beat)
sudo nano /etc/systemd/system/celery.service
[Unit] Description=Celery Service After=network.target [Service] Type=simple User=your_user Group=your_group WorkingDirectory=/path/to/your/project ExecStart=/path/to/your/venv/bin/celery -A your_project_name worker --loglevel=INFO ExecStop=/bin/kill -s TERM $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target
sudo nano /etc/systemd/system/celery_beat.service
[Unit] Description=Celery Beat Service After=network.target [Service] Type=simple User=your_user Group=your_group WorkingDirectory=/path/to/your/project ExecStart=/path/to/your/venv/bin/celery -A your_project_name beat --loglevel=INFO ExecStop=/bin/kill -s TERM $MAINPID Restart=on-failure [Install] WantedBy=multi-user.target
Update User , Group , WorkingDirectory , ExecStart with the actual path and value in the service file Note Path of the excutables will be in the virtual env created , so activating the virtual env and running
which app
returns the path , eg :which celery
,which gunicorn
- Run the backend as system service
sudo nano /etc/systemd/system/gunicorn.service
[Unit] Description=Django Application Service After=network.target [Service] User=user Group=www-data WorkingDirectory=/home/user/undp-vayu/src/api/aq_undp ExecStart=/home/user/undp-vayu/src/api/env/bin/gunicorn --workers 3 --bind 0.0.0.0:8000 aq_undp.wsgi:application Restart=always [Install] WantedBy=multi-user.target
Update User , Group , WorkingDirectory , ExecStart with the actual path and value in the service file
-
Reload systemctl
sudo systemctl daemon-reload
-
Enable the service
sudo systemctl enable gunicorn.service sudo systemctl enable celery sudo systemctl enable celery_beat
-
Start the service
sudo systemctl start gunicorn.service sudo systemctl start celery.service sudo systemctl start celery_beat.service sudo systemctl start redis-server
-
Create Nginx Server block for exposing the service
nano /etc/nginx/sites-available/backend
Replace backend with your custom domain name
server {
listen 80;
server_name yourdomain.com;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static/ {
expires 30d; add_header Cache-Control "public, must-revalidate";
}
}
nano /etc/nginx/sites-available/mobile-app
server {
listen 80;
server_name yourdomain.com;
root /path/to/your/react/build;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
nano /etc/nginx/sites-available/web-app
server {
listen 80;
server_name yourdomain.com;
root /path/to/your/react/build;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
Replace yourdomain.com , root with custom domain name and build path
-
Create a symbolic link to the
sites-enabled
directory:sudo ln -s /etc/nginx/sites-available/backend /etc/nginx/sites-enabled/
Similarly for other sites
-
Test the Nginx configuration
sudo nginx -t
-
Reload Nginx to apply the new configuration
sudo systemctl reload nginx sudo systemctl restart nginx
- Swetha Kolluri, Head of Experimentation, UNDP India
- Shubham Tandon, Program Officer, UNDP India
- Parvathy Krishnan, Data Science Lead, UNDP India
- Renoy Girindran, University of Nottingham
- Arun Kumar Yadav, Project Coordinator, UNDP India
- Ambarish Narayanan, CIO, mistEO
- Samuel John, Founder and CEO, mistEO
- Avinash Kumar, Programme Officer (Climate & Resource), Development Alternatives