• Blog
  • IoT Sensor Data Management System with MongoDB and .NET

IoT Sensor Data Management System with MongoDB and .NET

Build smart, scalable IoT solutions with MongoDB and .NET

Publish date:
Discover more of what matters to you

A MongoDB database is an excellent choice when we want to build scalable and flexible applications without worrying about the database schema. MongoDB is a document database that gives us flexibility and makes developers’ lives easier, supporting multiple languages and platforms. 

Are you looking to build scalable and flexible apps quickly? The combination of MongoDB and .NET provides a powerful solution.

MongoDB Installation

To get started, install the MongoDB Community Edition, which provides a local setup of a document database for testing, database creation, and queries.

  1. Download MongoDB: Go to the official MongoDB Community Edition download page and select the version for your operating system.
  2. Install and Run MongoDB: After installation, MongoDB will run as a service on your system, making it easy to connect and perform actions based on your application’s needs.
  3. Install MongoDB Compass: Download MongoDB Compass, a user-friendly interface for viewing and managing your data. This GUI tool simplifies database operations and allows you to visualize data and execute queries easily.
  4. Connect to MongoDB: Open MongoDB Compass, and click the “+” button at the top left corner, next to the CONNECTIONS section, to add a new MongoDB connection. By default, MongoDB uses port 27017.
IoT Sensor Data Management System with MongoDB and .NET

Press Save & Connect and you will see a green connected database to start interacting with.

Inspired by what you read?
Bring this level of efficiency to your legacy systems with a .NET migration. Learn more about our .NET services.
Get the Details

IoT Sensor Data Management System

With MongoDB running, it’s time to build our application. We will develop an IoT app that collects, stores, and analyzes data from environmental sensors.

We can support various less structured data types and schemas, allowing quick adaptations in any format. Scalability is not a problem, as Mongo can support large amounts of data with powerful real-time sensor data analysis capabilities.

Let’s create a new .NET web API project and the necessary Mongo library to start our development:

123
dotnet new webapi -o SensorApp
cd SensorApp
dotnet add package MongoDB.Driver

Document Model and Database Service

We’ll create a document model and a service for database connectivity and operations to manage sensor data efficiently.

First, we’ll define a MongoSettings class to hold our database connection settings:

123456
public class MongoSettings
{
public string ConnectionURI { get; set; } = null!;
public string DatabaseName { get; set; } = null!;
public string CollectionName { get; set; } = null!;
}

Next, we’ll define the schema for sensor data by creating a SensorData class:

123456789101112
public class SensorData
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
public DateTime Timestamp { get; set; }
public double Temperature { get; set; }
public double Humidity { get; set; }
public double CO2 { get; set; }
public double ParticulateMatter { get; set; }
}

And the service that will be injected into our controllers to use Mongo:

12345678910
public class MongoService
{
private readonly IMongoCollection<SensorData> _sensorDataCollection;
public MongoService(IOptions<MongoSettings> mongoDBSettings)
{
MongoClient client = new MongoClient(mongoDBSettings.Value.ConnectionURI);
IMongoDatabase database = client.GetDatabase(mongoDBSettings.Value.DatabaseName);
_sensorDataCollection = database.GetCollection<SensorData>(mongoDBSettings.Value.CollectionName);
}
}

By using the BsonId annotation, we designate which property serves as the unique identifier for the sensor data. Additionally, [BsonRepresentation(BsonType.ObjectId)] specifies the property’s type as an ObjectId.

After that, the data that will be used from MongoSettings will be found in our appsettings.json, which will match its model:

1234567891011121314
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"MongoDB": {
"ConnectionURI": "mongodb://localhost:27017",
"DatabaseName": "sensordb",
"CollectionName": "sensors"
}
}

And finally, the service registration in Program.cs:

12
builder.Services.Configure<MongoSettings>(builder.Configuration.GetSection("MongoDB"));
builder.Services.AddSingleton<MongoService>();

Crop Monitoring

Let’s explore a real-world application of IoT in agriculture: crop monitoring. IoT sensors have transformed how farmers monitor and maintain the health and life of their agriculture.

They can get early signs of multiple parameters like temperature and humidity, allowing them to respond quickly to changing conditions and protect crop health. As developers, we will create a core system that gathers and organizes this sensor data for analysis and visualization.

Let’s dive in.

Our app is the core system that will gather all the data from sensors, creating a data collection for analysis and visualization. We will begin by implementing a method in the SensorDataService class to handle incoming sensor data:

1234
public async Task SaveDataAsync(SensorData sensorData)
{
await _sensorDataCollection.InsertOneAsync(sensorData);
}

SaveDataAsync method uses MongoDB’s asynchronous InsertOneAsync method to insert sensor readings as new documents in the collection.

In the same class, we will add another method to get sensor data by ID with the related fields. The GetDataByIdAsync method looks like this:

1234
public async Task<SensorData?> GetDataByIdAsync(string id)
{
return await _sensorDataCollection.Find(data => data.Id == id).FirstOrDefaultAsync();
}

Using MongoDB’s Find method, this retrieves the first document that matches the specified ID.

Next, we have a more advanced requirement: calculating the average temperature recorded by a sensor within a specific time period. We will introduce Mongo Builders to help us build complex queries efficiently. 

12345678
public async Task UpdateSensorDataAsync(string id, double newTemperature, double newHumidity)
{
FilterDefinition<SensorData> filter = Builders<SensorData>.Filter.Eq(data => data.Id, id);
UpdateDefinition<SensorData> update = Builders<SensorData>.Update
.Set(data => data.Temperature, newTemperature)
.Set(data => data.Humidity, newHumidity);
await _sensorDataCollection.UpdateOneAsync(filter, update);
}

We utilize the UpdateOneAsync method overload, which accepts a FilterDefinition as the first argument and an UpdateDefinition as the second. With the builders, we first filter our data based on the unique ID, and with the second, we build the query to update temperature and humidity.

Having methods to insert and update data into our MongoDB, we want to get the average temperature within a specific period. That’s how we can do it:

12345
public async Task<double> GetAverageTemperatureAsync(DateTime start, DateTime end)
{
var data = await _sensorDataCollection.Find(d => d.Timestamp >= start && d.Timestamp <= end).ToListAsync();
return data.Average(d => d.Temperature);
}

This method retrieves sensor data entries within the given time range and calculates their average temperature.

We created 4 methods for our use case that can be expanded as the application grows. We also built the foundation for constructing the API controller.

API Controller

Here’s the API controller that manages sensor data, providing a RESTful interface.

1234567891011121314151617181920212223242526272829303132333435363738
[ApiController]
[Route("[controller]")]
public class SensorDataController : ControllerBase
{
private readonly MongoService _sensorDataService;
public SensorDataController(MongoService sensorDataService)
{
_sensorDataService = sensorDataService;
}
[HttpPost]
public async Task<IActionResult> Post([FromBody] SensorData sensorData)
{
await _sensorDataService.SaveDataAsync(sensorData);
return CreatedAtAction(nameof(GetById), new { id = sensorData.Id }, sensorData);
}
[HttpGet("{id}")]
public async Task<ActionResult<SensorData>> GetById(string id)
{
var sensorData = await _sensorDataService.GetDataByIdAsync(id);
if (sensorData == null)
{
return NotFound();
}
return Ok(sensorData);
}
[HttpPut("{id}")]
public async Task<IActionResult> Update(string id, [FromBody] SensorData updatedData)
{
await _sensorDataService.UpdateSensorDataAsync(id, updatedData.Temperature, updatedData.Humidity);
return NoContent();
}
[HttpGet("average-temperature")]
public async Task<ActionResult<double>> GetAverageTemperature([FromQuery] DateTime start, [FromQuery] DateTime end)
{
var averageTemperature = await _sensorDataService.GetAverageTemperatureAsync(start, end);
return Ok(averageTemperature);
}
}

POST /api/sensordata: Add new sensor data.

GET /api/sensordata/{id}: Retrieve a sensor data entry by ID.

PUT /api/sensordata/{id}: Update temperature and humidity fields for a specific sensor data entry.

GET /api/sensordata/average-temperature?start={start}&end={end}: Calculate average temperature over a specified period.

Want your legacy systems to handle IoT data?
Migrate to .NET – clean, fast, future-proof.
Migrate

Add Mock Data using Mongo Compass

It’s time to test our application and sensor data endpoints, but we don’t have data in our database. We will use the MongoDB Compass interface to import a JSON sensor data collection. As we saw, MongoDB fully supports documents and a JSON array is the correct fit. 

  1. Open MongoDB Compass and navigate to the sensordb database.
IoT Sensor Data Management System with MongoDB and .NET

2. Click ADD DATA > Insert Document, paste the JSON data below, and save.

12345678910111213141516171819202122232425262728293031323334353637
[
{
"Timestamp": { "$date": "2024-11-01T08:30:00Z" },
"Temperature": 22.5,
"Humidity": 45.0,
"CO2": 400.0,
"ParticulateMatter": 12.0
},
{
"Timestamp": { "$date": "2024-11-01T09:00:00Z" },
"Temperature": 23.1,
"Humidity": 46.0,
"CO2": 410.0,
"ParticulateMatter": 13.0
},
{
"Timestamp": { "$date": "2024-11-01T09:30:00Z" },
"Temperature": 21.9,
"Humidity": 44.5,
"CO2": 405.0,
"ParticulateMatter": 11.5
},
{
"Timestamp": { "$date": "2024-11-01T10:00:00Z" },
"Temperature": 22.8,
"Humidity": 45.5,
"CO2": 402.0,
"ParticulateMatter": 12.3
},
{
"Timestamp": { "$date": "2024-11-01T10:30:00Z" },
"Temperature": 23.3,
"Humidity": 47.0,
"CO2": 415.0,
"ParticulateMatter": 13.2
}
]

3. The final result with the sensor data in the database:

IoT Sensor Data Management System with MongoDB and .NET

Run and Verify

Now our database has some data and we can start our application to test our endpoints. When you run the application, you should see the Swagger UI as below:

IoT Sensor Data Management System with MongoDB and .NET

Let’s try out the average temperature endpoint with a start date of 2024-11-01T08:30:00Z and an end date of 2024-11-01T10:30:00Z. The result that we get is 22.72, as you can see in the following image:

IoT Sensor Data Management System with MongoDB and .NET

We developed a foundational IoT Sensor Data Management System using .NET Core and MongoDB. This initial setup provides a flexible foundation that can be readily expanded to handle more complex data requirements. Our focus on a local setup simplifies the development process, making it easier to build and test features in a controlled environment.

Implementing TTL in MongoDB for IoT Sensor Data 

Data is at the core of modern decision-making. We use them in many decisions and circumstances as humans to evolve, predict and create a better future for ourselves. How to handle this data is also an essential step in this direction. However, not all data remains relevant forever. Old readings, once past their usefulness, become dead weight: they consume storage, slow queries, and drive up hosting costs. 

To tackle this challenge in MongoDB, Time-to-Live (TTL) indexes can be used. They are special single-field indexes that automatically remove documents from a collection after a specified period of time. IoT devices generate tons of unstructured data, and after a few days, they are outdated. 

Gain full access to the complete guide to implementing TTL in MongoDB for IoT sensor data. Fill the form to get:

  • A step-by-step TTL index implementation walkthrough
  • Best practices for managing high-volume time-series data
  • Code examples and real-world performance tips
  • Key pitfalls to avoid when using TTL in production

Get access to the article by completing your name and e-mail address.

This field is required
This field is required Invalid email address Invalid business email address
By submitting data, I agree to the Privacy Policy
Tags
Get in touch
Our benefits
  • 17+ years in legacy software modernization
  • AI Migration Tool:
    faster timelines, lower costs, better accuracy (99.9%)
  • 30–50% faster release cycles
  • 1–2 day estimate turnaround
  • Trusted by clients from USA, UK, Germany, etc.
Review
Thanks to Softacom's efforts, the solutions they delivered are already in use and have increased revenue streams.
  • Niels Thomassen
  • Microcom A/S
This field is required
This field is required Invalid email address Invalid business email address
This field is required
By submitting data, I agree to the Privacy Policy
We ll reply within 24h. No sales fluff. 100% no spam