A full-stack ASP.NET web application that combines two architectural paradigms: an N-tier (3-layer) web application architecture for the presentation, business logic, and data access concerns, and a LEACH-inspired Wireless Sensor Network (WSN) for distributed data collection. The system simulates 237 sensor nodes distributed across countries and territories worldwide, collects AQI (Air Quality Index) readings, persists them in SQL Server, and presents the data on an interactive world dashboard with chart analytics and email alerts.
RAPM is a demonstration of two complementary architectural patterns applied together:
N-tier (3-layer) Web Architecture — the web application strictly separates Presentation, Business Logic, and Data Access into independent deployable layers, following the standard N-tier pattern used in enterprise web application development.
LEACH-inspired WSN Distributed Architecture — the data collection layer is modelled on the LEACH (Low-Energy Adaptive Clustering Hierarchy) protocol, a well-established distributed clustering algorithm for wireless sensor networks. Sensor nodes report to elected Cluster Head (CH) nodes, which aggregate readings and forward them to a centralised Sink Node — mirroring how a real-world WSN would route data through a multi-hop hierarchy before persisting it.
The primary goal of the project is to demonstrate the integration of these two architectural paradigms: a distributed, concurrent sensor network feeding into a structured, layered web platform. The AQI data used in the simulation is synthetically generated for demonstration purposes and is designed to be replaceable with readings from physical sensors with no change to the upstream architecture.
The web application follows the classic N-tier layered architecture pattern, with each concern cleanly separated into its own deployable project:
| Tier | Project | Responsibility |
|---|---|---|
| Presentation Layer | Air Pollution Monitor |
UI rendering, session management, user interaction (WebForms + MVC 5) |
| Business Logic Layer | BusinessLayer |
WSN simulation, data aggregation, notification dispatch |
| Data Access Layer | DatabaseLayer |
SOAP web services exposing CRUD operations over SQL Server |
Each layer communicates only with the layer directly beneath it — the Presentation Layer invokes the Data Access Layer exclusively through the published SOAP service contracts (SensorDataConfig.asmx, UserManagementService.asmx), and the Business Logic Layer writes to the database through the same service interface. This loose coupling means any layer can be replaced or scaled independently.
Real-Time-Air-Monitoring-System/
├── Air Pollution Monitor/ # Presentation Layer — WebForms + MVC 5
├── BusinessLayer/ # Business Logic Layer — WSN simulation engine
└── DatabaseLayer/ # Data Access Layer — ASMX SOAP services + SQL Server
┌─────────────────────────────────────────────────────────┐
│ Presentation Layer │
│ Air Pollution Monitor │
│ (WebForms pages + MVC Dashboard + Chart.js + Map) │
└──────────────────────────┬──────────────────────────────┘
│ SOAP over HTTP
┌──────────────────────────▼──────────────────────────────┐
│ Data Access Layer │
│ DatabaseLayer │
│ SensorDataConfig.asmx UserManagementService.asmx │
└──────────────────────────┬──────────────────────────────┘
│ ADO.NET (SqlClient)
┌──────────────────────────▼──────────────────────────────┐
│ AirMonitorSystemDB │
│ Countries · Sensor · SensorReading · UserAccounts │
│ NotificationSettings · ContactMessages │
└─────────────────────────────────────────────────────────┘
▲
│ SOAP (UpdateDatabaseAQI)
┌──────────┴──────────────────────────────────────────────┐
│ Business Logic Layer │
│ BusinessLayer │
│ WSN Simulation (LEACH-based, multi-threaded) │
└─────────────────────────────────────────────────────────┘
When AirMonitor.aspx is loaded, the Presentation Layer spawns BusinessLayer.exe as a background process, which executes one full WSN simulation cycle, persists readings through the Data Access Layer, and serialises the results to Content/MapData.json for the map frontend.
The simulation is implemented in BusinessLayer/WSNSimulation.cs and is modelled on the LEACH (Low-Energy Adaptive Clustering Hierarchy) protocol — one of the foundational distributed clustering algorithms in WSN literature. LEACH organises sensor nodes into clusters, each governed by an elected Cluster Head (CH), which aggregates intra-cluster readings and relays them to the base station (Sink Node), reducing redundant transmissions and centralising data aggregation.
| Component | Count | Role |
|---|---|---|
| Sensor Nodes | 237 | Leaf nodes; each generates one AQI reading per cycle |
| Cluster Head (CH) Nodes | 79 (237 ÷ 3) | Intra-cluster aggregators; relay consolidated data to the Sink |
| Sink Node | 1 | Base station; receives all CH payloads and writes to the database |
Cluster head assignment follows a region-aware strategy: each geographic region is guaranteed at least one CH, with the remaining CH slots distributed round-robin across regions. This mirrors the spatially balanced cluster formation objective of LEACH variants and ensures no region is left without a local aggregator even under uneven sensor counts.
[Sensor Nodes] → FIFO Buffer → [Cluster Head Nodes] → [Sink Node] → SQL Server
(237 threads) (size 250) (79 threads) (1 node)
-
Sensor Nodes each run in their own thread, generate a region-appropriate AQI value, package it as a
SensorDataobject (ID,Value,ClusterHeadID,Finished), and write it into the shared FIFO buffer. -
Cluster Head Nodes each run in their own thread, read from the FIFO buffer, and match incoming
SensorDatato their assigned sensors. Once all expected sensors have reported (or a 5-second timeout elapses), the CH sends a done signal and forwards its aggregated dataset to the Sink Node. -
Sink Node waits until all 79 cluster heads have reported in. It then iterates over every sensor reading and calls
SensorDataConfig.UpdateDatabaseAQI()to persist each one intoSensorReading. -
Data Conversion — after the DB write,
DataConversion()callsGetLatestSensorReadings()and serialises the results toContent/MapData.json, which the web frontend reads to populate the world map. -
Email Notifications —
SendEmailNotif()queriesNotificationSettingsfor any user whose AQI threshold has been breached and sends an HTML alert email via SMTP.
The simulation uses a classic bounded producer-consumer pattern to safely pass data from sensor threads to cluster head threads:
// Synchronisation primitives
Semaphore fullSem; // counts filled slots — CH threads wait on this to read
Semaphore emptySem; // counts empty slots — sensor threads wait on this to write
Mutex fifoMut; // mutual exclusion on the read/write indices
object[] bufs; // circular buffer, size 250WriteToFifo(sensor side): waits for an empty slot → acquires mutex → writes → releases mutex → signals full.ReadFromFifo(CH side): waits for a full slot → acquires mutex → reads → releases mutex → signals empty.
All 237 sensor threads are started simultaneously via a ManualResetEvent start signal to simulate concurrent sensor activation. Cluster head threads then run concurrently and drain the buffer as it fills.
Since the system targets architectural demonstration rather than a live hardware deployment, AQI readings are synthetically generated at the sensor layer. Each SensorNode produces a pseudorandom integer within a region-specific range, seeded per thread via [ThreadStatic] Random to eliminate inter-thread contention and ensure statistically independent samples:
| Region ID | AQI Range | Representative Geography |
|---|---|---|
| 1 | 30 – 110 | Europe |
| 2 | 30 – 170 | Americas |
| 3 | 80 – 350 | Asia |
| 4 | 30 – 100 | Oceania |
| 5 | 50 – 250 | Africa |
| default | 0 – 500 | Unclassified |
These ranges are a simplified approximation included purely for plausible visualisation. The synthetic generation is entirely contained within SensorNode.RunSensor() — replacing it with a real hardware driver (e.g. reading from a serial-port-connected particulate sensor or an external AQI API) requires no changes to the CH aggregation, Sink, or any upstream layer.
| Page | Description |
|---|---|
Home.aspx |
Landing page |
Login.aspx |
User login with salted SHA-256 password verification |
Signup.aspx |
User registration |
AirMonitor.aspx |
World map view — triggers simulation, displays live AQI per country |
Dashboard/Index (MVC) |
Analytics dashboard — charts, rankings, alert setup |
About.aspx |
Project information |
Contact.aspx |
Contact form (stored in ContactMessages table) |
- World Map — colour-coded AQI overlay from
MapData.jsonupdated each simulation run. - Country Selector — switch the analytics view to any monitored country.
- Latest AQI Card — most recent sensor reading for the selected country.
- Weekly Chart — 7-day daily average AQI (line chart via Chart.js).
- Daily Chart — last 24 hours in 2-hour intervals (line chart).
- World Rankings — top 5 most and least polluted countries by weekly average AQI.
- AQI Alert — set a threshold and email address; receive an HTML alert when AQI is exceeded.
SQL Server database: AirMonitorSystemDB
| Table | Purpose |
|---|---|
Countries |
ISO2 code, country name, region ID |
Sensor |
Sensor ID mapped to country and region |
SensorReading |
AQI readings with timestamp and cluster head reference |
UserAccounts |
Username, email, hashed password, salt, full name |
NotificationSettings |
Per-country AQI threshold and notification email |
ContactMessages |
Messages submitted via the contact form |
- Backend: ASP.NET 4.8.1 (WebForms + MVC 5), C#
- Simulation: Multi-threaded C# console app (Semaphore, Mutex, ManualResetEvent)
- Data Access: ASMX Web Services (SOAP),
System.Data.SqlClient - Database: Microsoft SQL Server
- Frontend: Argon Dashboard (Bootstrap 4), Chart.js, custom CSS
- Email: MailKit / MimeKit
- Serialisation: System.Text.Json
- Visual Studio 2022 (with ASP.NET and .NET Desktop workloads)
- SQL Server (LocalDB or full instance)
- A Gmail account with an App Password enabled for SMTP
1. Database connection string — set your SQL Server instance in DatabaseLayer/Web.config:
<connectionStrings>
<add name="AirMonitorDB"
connectionString="Data Source=YOUR_SERVER;Initial Catalog=AirMonitorSystemDB;Integrated Security=True;TrustServerCertificate=True"
providerName="System.Data.SqlClient" />
</connectionStrings>2. SMTP credentials — set your email credentials in BusinessLayer/App.config:
<appSettings>
<add key="SmtpUser" value="YOUR_EMAIL@gmail.com" />
<add key="SmtpPassword" value="YOUR_APP_PASSWORD" />
</appSettings>3. Service endpoint — if your DatabaseLayer runs on a different port, update the service URL in Air Pollution Monitor/Web.config and BusinessLayer/App.config:
<setting name="Air_Pollution_Monitor_SDC_SensorDataConfig" serializeAs="String">
<value>https://localhost:44308/SensorDataConfig.asmx</value>
</setting>- Create the
AirMonitorSystemDBdatabase and run the schema to create all tables. - Set
DatabaseLayeras the startup project and run it to start the web services. - Set
Air Pollution Monitoras the startup project and run the web app. - Navigate to
AirMonitor.aspx— this triggers a simulation run automatically. - Open the Dashboard to explore the charts and rankings once data has populated.
To run the simulation independently:
BusinessLayer.exe
This executes one full WSN cycle and updates both the database and MapData.json.