{"id":55618,"date":"2026-10-21T13:13:49","date_gmt":"2026-10-21T20:13:49","guid":{"rendered":"https:\/\/www.griddb.net\/?p=55618"},"modified":"2026-10-28T14:24:47","modified_gmt":"2026-10-28T21:24:47","slug":"real-time-vehicle-emission-monitoring-with-griddb-and-emissguard","status":"publish","type":"post","link":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/","title":{"rendered":"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard"},"content":{"rendered":"<h2 id=\"introduction\"><strong>Introduction<\/strong><\/h2>\n<p>\nVehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture will show elevated CO readings before its PM2.5 levels cross into dangerous territory. A CNG bus operating in stop-start city traffic will accumulate NOx gradually across a shift, not all at once.\n<\/p>\n<p>\nThe problem with most fleet monitoring systems is not a lack of sensors. Modern vehicles carry several gas sensors, temperature probes, and air quality detectors. The real problem is that these sensors are treated as independent data points. A system that watches CO in isolation will miss the connection between rising CO and the PM2.5 spike that follows incomplete combustion.\n<\/p>\n<p>\nIn this project, we did not just build a chart that shows numbers. We built a fleet emission monitoring system called EmissGuard that connects sensor readings across eight vehicles, tracks how emission patterns change over time, and identifies cross-sensor correlations that a single-reading alert would miss. GridDB stores every reading as a time-series record and makes it available for both real-time dashboard queries and machine learning training.\n<\/p>\n<h2 id=\"why-time-series-databases-matter-for-vehicle-emission-data\"><strong>Why Time-Series Databases Matter for Vehicle Emission Data<\/strong><\/h2>\n<p>\nImagine a sensor reports an MQ135 reading of 520. Is that a problem?\n<\/p>\n<p>\nIf the reading was 180 three minutes ago and has been climbing steadily, the vehicle is likely developing a combustion issue that needs immediate attention.\n<\/p>\n<p>\nIf the reading has been between 490 and 530 for the past two hours, the vehicle may simply be operating under heavy load within its normal emission range for that condition.\n<\/p>\n<p>\nA single sensor reading is just a number. A sequence of readings over time tells the actual story.\n<\/p>\n<p>\nFleet vehicles produce a continuous stream of timestamped sensor data. Traditional relational databases were designed for transactional records. They struggle when asked to store thousands of ordered sensor readings per minute and then retrieve the most recent window efficiently.\n<\/p>\n<p>\nTime-series databases are built for exactly this type of workload. GridDB stores each sensor reading with its UTC timestamp as the row key. Retrieving the last 30 readings for any vehicle is a single TQL query that returns results in microseconds. This makes it practical to run rolling-window analysis on every poll cycle without putting pressure on the database.\n<\/p>\n<h2 id=\"why-griddb-for-fleet-emission-monitoring\"><strong>Why GridDB for Fleet Emission Monitoring<\/strong><\/h2>\n<p>\nFleet emission monitoring systems need a database that can handle high-frequency sensor ingestion from multiple vehicles simultaneously and return recent readings fast enough for real-time dashboard polling. GridDB is a memory-first NoSQL database built specifically for time-series workloads, which makes it a natural fit for this type of system.\n<\/p>\n<p>\nWe use GridDB in EmissGuard to:\n<\/p>\n<ol>\n<li>Store continuous vehicle sensor data using TIME_SERIES containers with timestamp-based row keys.<\/li>\n<li>Maintain a fixed schema per vehicle for predictable and fast reads and writes.<\/li>\n<li>Ingest sensor batches from all eight vehicles in a single multi_put operation.<\/li>\n<li>Query recent time windows efficiently using TQL for rolling-window health analysis.<\/li>\n<li>Correlate multiple sensor streams (MQ2, CO, NOx, PM2.5) across time to detect emission patterns.<\/li>\n<li>Feed stored historical data directly into a scikit-learn machine learning training pipeline.<\/li>\n<li>Support explainable alerts by giving the dashboard fast access to recent sensor history per vehicle.<\/li>\n<\/ol>\n<h4 id=\"without-griddb\"><strong>Without GridDB:<\/strong><\/h4>\n<ul>\n<li>Rolling-window AQI analysis would require expensive full scans on every poll cycle.<\/li>\n<li>Batch ingestion from eight vehicles simultaneously would create write bottlenecks.<\/li>\n<li>The ML pipeline would have no reliable source of labelled time-series data to train on.<\/li>\n<\/ul>\n<h2 id=\"system-architecture\"><strong>System Architecture<\/strong><\/h2>\n<p>\nEmissGuard simulates a fleet of eight vehicles across different fuel types and vehicle categories. Each vehicle generates readings from eight sensors at 15-second intervals. The sensor data is generated by a Python simulator, stored in GridDB through a batch insert, and served to a monitoring dashboard through a Flask REST API. The system also detects cross-sensor emission correlations and produces a fleet-wide emission index in addition to per-vehicle AQI scores.\n<\/p>\n<p><a href=\"\/wp-content\/uploads\/2026\/10\/architecture.png\"><img fetchpriority=\"high\" decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/10\/architecture.png\" alt=\"\" width=\"1535\" height=\"1025\" class=\"aligncenter size-full wp-image-55629\" srcset=\"\/wp-content\/uploads\/2026\/10\/architecture.png 1535w, \/wp-content\/uploads\/2026\/10\/architecture-300x200.png 300w, \/wp-content\/uploads\/2026\/10\/architecture-1024x684.png 1024w, \/wp-content\/uploads\/2026\/10\/architecture-768x513.png 768w, \/wp-content\/uploads\/2026\/10\/architecture-600x401.png 600w\" sizes=\"(max-width: 1535px) 100vw, 1535px\" \/><\/a><\/p>\n<p>\nThe overall system consists of the following main components:\n<\/p>\n<p><strong>Sensor Simulation Layer<\/strong><\/p>\n<p>\nA Python-based simulator generates sensor readings for all eight vehicles. It produces MQ2, MQ135, CO2, CO, NOx, PM2.5, temperature, and humidity values at regular intervals using proportional interpolation and random noise to simulate how real vehicle sensors behave over time.\n<\/p>\n<p><strong>Data Ingestion Layer<\/strong><\/p>\n<p>\nThe backend application receives the simulated readings and writes them into GridDB using the multi_put operation, which batches all eight vehicle containers into a single write request.\n<\/p>\n<p><strong>GridDB Database<\/strong><\/p>\n<p>\nGridDB stores the vehicle sensor data generated during the simulation. It acts as the central data layer from which the application retrieves recent readings when computing AQI scores and emission correlations.\n<\/p>\n<p><strong>Monitoring Dashboard<\/strong><\/p>\n<p>\nA web-based dashboard built with HTML, JavaScript, and Chart.js displays per-vehicle emission status, sensor history charts, fleet-wide emission index, and cross-sensor correlation alerts in real time.\n<\/p>\n<h2 id=\"setting-up-griddb-local-installation\"><strong>Setting Up GridDB (Local Installation)<\/strong><\/h2>\n<p>\nEmissGuard uses a locally installed GridDB instance on Ubuntu 24.04. After installing GridDB through the official Ubuntu package and starting the gridstore service, a Python application connects using the notification_member address.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">import griddb_python as griddb\r\nimport os\r\n\r\nNOTIFICATION_MEMBER = os.environ.get(&quot;GRIDDB_NOTIFICATION_MEMBER&quot;, &quot;127.0.0.1:10001&quot;)\r\nCLUSTER_NAME        = os.environ.get(&quot;GRIDDB_CLUSTER_NAME&quot;,        &quot;myCluster&quot;)\r\nUSERNAME            = os.environ.get(&quot;GRIDDB_USERNAME&quot;,            &quot;admin&quot;)\r\nPASSWORD            = os.environ.get(&quot;GRIDDB_PASSWORD&quot;,            &quot;admin&quot;)\r\n\r\ndef get_gridstore():\r\n    factory = griddb.StoreFactory.get_instance()\r\n    return factory.get_store(\r\n        notification_member=NOTIFICATION_MEMBER,\r\n        cluster_name=CLUSTER_NAME,\r\n        username=USERNAME,\r\n        password=PASSWORD,\r\n    )<\/code><\/pre>\n<\/div>\n<p>\nAll connection parameters are read from environment variables so the project runs on any GridDB installation without code changes. The defaults match a standard local setup. Once connected, the application can create containers and begin storing vehicle sensor data.\n<\/p>\n<h2 id=\"project-overview\"><strong>Project Overview<\/strong><\/h2>\n<p>\nEmissGuard monitors eight vehicles, each with its own sensor profile, warning thresholds, and GridDB container. The profiles are defined in a central configuration file called vehicles.py, which every other module imports from. This is the single source of truth for sensor ranges, critical thresholds, container names, and vehicle metadata.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">VEHICLES = {\r\n    &quot;VH001&quot;: {\r\n        &quot;display_name&quot;:  &quot;Truck Alpha&quot;,\r\n        &quot;vehicle_type&quot;:  &quot;Heavy Truck&quot;,\r\n        &quot;fuel_type&quot;:     &quot;Diesel&quot;,\r\n        &quot;container&quot;:     &quot;emissguard_vh001&quot;,\r\n        &quot;description&quot;:   &quot;Long-haul freight truck. Diesel engine, high NOx emitter.&quot;,\r\n        &quot;normal&quot;: {\r\n            &quot;mq2&quot;:         (100, 300),\r\n            &quot;mq135&quot;:       (100, 350),\r\n            &quot;co2_ppm&quot;:     (400, 600),\r\n            &quot;co_ppm&quot;:      (0,   9),\r\n            &quot;nox_ppb&quot;:     (10,  80),\r\n            &quot;pm25_ugm3&quot;:   (0,   15),\r\n            &quot;temperature&quot;: (55,  90),\r\n            &quot;humidity&quot;:    (35,  65),\r\n        },\r\n        &quot;thresholds&quot;: {\r\n            &quot;mq2&quot;:         {&quot;warning&quot;: 450,  &quot;critical&quot;: 700},\r\n            &quot;mq135&quot;:       {&quot;warning&quot;: 500,  &quot;critical&quot;: 750},\r\n            &quot;co2_ppm&quot;:     {&quot;warning&quot;: 1000, &quot;critical&quot;: 2000},\r\n            &quot;co_ppm&quot;:      {&quot;warning&quot;: 15,   &quot;critical&quot;: 35},\r\n            &quot;nox_ppb&quot;:     {&quot;warning&quot;: 150,  &quot;critical&quot;: 300},\r\n            &quot;pm25_ugm3&quot;:   {&quot;warning&quot;: 35,   &quot;critical&quot;: 75},\r\n            &quot;temperature&quot;: {&quot;warning&quot;: 120,  &quot;critical&quot;: 160},\r\n            &quot;humidity&quot;:    {&quot;warning&quot;: 80,   &quot;critical&quot;: 95},\r\n        },\r\n    },\r\n    # VH002 through VH008 follow the same structure ...\r\n}<\/code><\/pre>\n<\/div>\n<p>\nKey ideas behind the system:\n<\/p>\n<ul>\n<li><strong>Fleet-wide monitoring:<\/strong> Instead of analyzing each vehicle in isolation, the system observes all eight vehicles together and can detect when multiple vehicles show concurrent emission stress.<\/li>\n<li><strong>Pattern detection:<\/strong> It identifies small but meaningful changes in sensor values over time that may signal a developing combustion issue, rather than reacting only to single-point threshold crossings.<\/li>\n<li><strong>Cross-sensor correlation awareness:<\/strong> It models how one emission measurement can drive another. High CO often means incomplete combustion, which produces more PM2.5. Rising exhaust temperature promotes NOx formation. These relationships are checked on every analysis cycle.<\/li>\n<\/ul>\n<h2 id=\"simulating-vehicle-sensor-data\"><strong>Simulating Vehicle Sensor Data<\/strong><\/h2>\n<p>\nSince real vehicle exhaust sensors were not available, the system uses a sensor simulator to generate realistic emission readings. The simulator creates data for eight vehicles across four fuel types: Diesel, Petrol, and CNG.\n<\/p>\n<p>\nThe dataset is generated in four phases:\n<\/p>\n<ul>\n<li><strong>Safe:<\/strong> All vehicles operate within normal emission limits.<\/li>\n<li><strong>Moderate:<\/strong> VH001 (Truck Alpha) and VH007 (Lorry Eta) begin showing elevated readings.<\/li>\n<li><strong>Poor:<\/strong> Both heavy vehicles enter the poor zone; VH004 and VH002 enter moderate.<\/li>\n<li><strong>Dangerous:<\/strong> VH001 and VH007 cross critical thresholds; other vehicles show a cascade of elevated readings.<\/li>\n<\/ul>\n<p>\nThis models how emission events in real fleets often start with the heaviest vehicles and spread across the fleet through shared operational conditions.\n<\/p>\n<p>\nTo make the simulation physically realistic, the system avoids generating flat or hardcoded values. Instead it uses proportional interpolation and per-sensor random noise to calculate values dynamically:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def _interpolate(low, high, progress=None):\r\n    &quot;&quot;&quot;Smoothly interpolate between two values with optional random progress.&quot;&quot;&quot;\r\n    if progress is None:\r\n        progress = random.uniform(0.0, 1.0)\r\n    return low + progress * (high - low)\r\n\r\n\r\ndef generate_reading(vehicle_id, status=&quot;Safe&quot;, progress=0.0, timestamp=None):\r\n    cfg = VEHICLES[vehicle_id]\r\n    nrm = cfg[&quot;normal&quot;]\r\n    thr = cfg[&quot;thresholds&quot;]\r\n\r\n    vals = {k: random.uniform(*nrm[k]) for k in nrm}\r\n\r\n    noise = {\r\n        &quot;mq2&quot;:         random.uniform(-12, 12),\r\n        &quot;mq135&quot;:       random.uniform(-12, 12),\r\n        &quot;co2_ppm&quot;:     random.uniform(-15, 15),\r\n        &quot;co_ppm&quot;:      random.uniform(-0.5, 0.5),\r\n        &quot;nox_ppb&quot;:     random.uniform(-4, 4),\r\n        &quot;pm25_ugm3&quot;:   random.uniform(-1.5, 1.5),\r\n        &quot;temperature&quot;: random.uniform(-2, 2),\r\n        &quot;humidity&quot;:    random.uniform(-2, 2),\r\n    }\r\n\r\n    if status == &quot;Moderate&quot;:\r\n        prog = random.uniform(0.2, 0.55)\r\n        for key in (&quot;mq2&quot;, &quot;mq135&quot;, &quot;co2_ppm&quot;, &quot;co_ppm&quot;, &quot;nox_ppb&quot;, &quot;pm25_ugm3&quot;):\r\n            vals[key] = _interpolate(nrm[key][1], thr[key][&quot;warning&quot;], prog)\r\n\r\n    elif status == &quot;Poor&quot;:\r\n        prog = random.uniform(0.45, 0.85)\r\n        for key in (&quot;mq2&quot;, &quot;mq135&quot;, &quot;co2_ppm&quot;, &quot;co_ppm&quot;, &quot;nox_ppb&quot;, &quot;pm25_ugm3&quot;):\r\n            vals[key] = _interpolate(thr[key][&quot;warning&quot;], thr[key][&quot;critical&quot;], prog * 0.7)\r\n\r\n    elif status == &quot;Dangerous&quot;:\r\n        prog = random.uniform(0.8, 1.25)\r\n        for key in (&quot;mq2&quot;, &quot;mq135&quot;, &quot;co2_ppm&quot;, &quot;co_ppm&quot;, &quot;nox_ppb&quot;, &quot;pm25_ugm3&quot;):\r\n            overshoot = thr[key][&quot;critical&quot;] + (\r\n                thr[key][&quot;critical&quot;] - thr[key][&quot;warning&quot;]\r\n            ) * (prog - 1.0) * 0.4\r\n            vals[key] = max(thr[key][&quot;warning&quot;], overshoot)\r\n    # ...<\/code><\/pre>\n<\/div>\n<p>\nThis approach guarantees that simulated sensors drift naturally within a range and occasionally spike, rather than sitting at a fixed median value.\n<\/p>\n<h2 id=\"live-escalation-simulation\"><strong>Live Escalation Simulation<\/strong><\/h2>\n<p>\nTo demonstrate how emission events develop over time, the project includes a Python script that simulates a live escalation across the fleet.\n<\/p>\n<p>\nInstead of inserting a full dataset all at once, the script gradually sends sensor readings to GridDB to show how emission problems evolve in real vehicle fleets.\n<\/p>\n<p>\nThe simulation follows four phases:\n<\/p>\n<ul>\n<li><strong>Safe Operation:<\/strong> All vehicles emit within normal limits.<\/li>\n<li><strong>Moderate Escalation:<\/strong> VH001 and VH007 begin showing elevated MQ2 and CO2.<\/li>\n<li><strong>Poor Condition:<\/strong> Both heavy vehicles enter the poor zone; medium vehicles pick up elevated readings.<\/li>\n<li><strong>Dangerous Cascade:<\/strong> VH001 and VH007 cross critical thresholds; the fleet emission index climbs sharply.<\/li>\n<\/ul>\n<p>\nDuring the simulation, new sensor readings are continuously inserted into GridDB. This allows the dashboard to react in real time as the escalation develops across vehicles.\n<\/p>\n<p>\nA simplified example of the escalation loop is shown below:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def trigger_emission():\r\n    store = insert_data.get_gridstore()\r\n    start_sim()\r\n\r\n    i = 0\r\n    while is_sim_active():\r\n        ts    = datetime.now(timezone.utc)\r\n        phase = min(i \/\/ 4, 3)\r\n        batch = {}\r\n\r\n        for vid, cfg in VEHICLES.items():\r\n            status = PHASE_PLAN[phase].get(vid, &quot;Safe&quot;)\r\n            r      = generate_reading(vid, status, timestamp=ts)\r\n            batch[cfg[&quot;container&quot;]] = [[\r\n                ts, r[&quot;mq2&quot;], r[&quot;mq135&quot;], r[&quot;co2_ppm&quot;], r[&quot;co_ppm&quot;],\r\n                r[&quot;nox_ppb&quot;], r[&quot;pm25_ugm3&quot;], r[&quot;temperature&quot;],\r\n                r[&quot;humidity&quot;], r[&quot;aqi_status&quot;],\r\n            ]]\r\n\r\n        store.multi_put(batch)\r\n        i += 1\r\n        time.sleep(1)<\/code><\/pre>\n<\/div>\n<p>\nWhen the operator clicks the &#8220;Issue Resolved&#8221; button in the dashboard, the backend sets the simulation flag to False. The escalation loop stops and the script injects a final batch of Safe readings into GridDB. These clean readings immediately restore the fleet to a normal state on the dashboard without any manual intervention.\n<\/p>\n<h2 id=\"storing-vehicle-sensor-data-in-griddb\"><strong>Storing Vehicle Sensor Data in GridDB<\/strong><\/h2>\n<p>\nAfter generating the simulated sensor readings, the data is stored in GridDB so the monitoring system can access it. Each vehicle is assigned its own TIME_SERIES container, where readings for all eight sensors are stored with a UTC timestamp as the row key. This allows the system to retrieve vehicle sensor history in chronological order using a single TQL query.\n<\/p>\n<h3 id=\"creating-a-time-series-container\"><strong>Creating a TIME_SERIES Container<\/strong><\/h3>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def setup_containers(store):\r\n    for vid, cfg in VEHICLES.items():\r\n        con_info = griddb.ContainerInfo(\r\n            cfg[&quot;container&quot;],\r\n            [\r\n                [&quot;timestamp&quot;,   griddb.Type.TIMESTAMP],\r\n                [&quot;mq2&quot;,         griddb.Type.DOUBLE],\r\n                [&quot;mq135&quot;,       griddb.Type.DOUBLE],\r\n                [&quot;co2_ppm&quot;,     griddb.Type.DOUBLE],\r\n                [&quot;co_ppm&quot;,      griddb.Type.DOUBLE],\r\n                [&quot;nox_ppb&quot;,     griddb.Type.DOUBLE],\r\n                [&quot;pm25_ugm3&quot;,   griddb.Type.DOUBLE],\r\n                [&quot;temperature&quot;, griddb.Type.DOUBLE],\r\n                [&quot;humidity&quot;,    griddb.Type.DOUBLE],\r\n                [&quot;aqi_status&quot;,  griddb.Type.STRING],\r\n            ],\r\n            griddb.ContainerType.TIME_SERIES,\r\n        )\r\n        store.put_container(con_info)\r\n        print(f&quot;  Container ready: {cfg['container']}&quot;)<\/code><\/pre>\n<\/div>\n<p>\nThe put_container call is idempotent. Calling it on an existing container returns a reference to it without losing any stored data. This makes it safe to run insert_data.py multiple times during development and testing.\n<\/p>\n<h3 id=\"inserting-data-into-griddb\"><strong>Inserting Data into GridDB<\/strong><\/h3>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def insert_dataset(store, dataset):\r\n    batch = {}\r\n    for vid, readings in dataset.items():\r\n        container_name = VEHICLES[vid][&quot;container&quot;]\r\n        rows = []\r\n        for r in readings:\r\n            ts = datetime.fromisoformat(r[&quot;timestamp&quot;].replace(&quot;Z&quot;, &quot;+00:00&quot;))\r\n            rows.append([\r\n                ts,\r\n                r[&quot;mq2&quot;], r[&quot;mq135&quot;], r[&quot;co2_ppm&quot;], r[&quot;co_ppm&quot;],\r\n                r[&quot;nox_ppb&quot;], r[&quot;pm25_ugm3&quot;], r[&quot;temperature&quot;],\r\n                r[&quot;humidity&quot;], r[&quot;aqi_status&quot;],\r\n            ])\r\n        batch[container_name] = rows\r\n\r\n    store.multi_put(batch)<\/code><\/pre>\n<\/div>\n<p>\nThe multi_put operation writes rows to multiple containers in a single request. This significantly improves ingestion throughput when handling sensor data from eight vehicles simultaneously.\n<\/p>\n<h2 id=\"querying-sensor-data-and-computing-aqi-scores\"><strong>Querying Sensor Data and Computing AQI Scores<\/strong><\/h2>\n<p>\nOnce vehicle sensor data is stored in GridDB, the monitoring system queries recent readings to evaluate each vehicle&#8217;s emission status. The system retrieves the latest records for each vehicle and computes an AQI score based on how far the sensor values have drifted from normal ranges.\n<\/p>\n<p>\nGridDB&#8217;s Time-Series Query Language (TQL) allows the system to fetch the most recent readings from each vehicle container efficiently:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def query_recent(store, vehicle_id, limit=30):\r\n    container = store.get_container(VEHICLES[vehicle_id][&quot;container&quot;])\r\n\r\n    query = container.query(\r\n        f&quot;select * order by timestamp desc limit {limit}&quot;\r\n    )\r\n    rs = query.fetch()\r\n\r\n    readings = []\r\n    while rs.has_next():\r\n        row = rs.next()\r\n        readings.append({\r\n            &quot;timestamp&quot;:   row[0].isoformat(),\r\n            &quot;mq2&quot;:         row[1],\r\n            &quot;mq135&quot;:       row[2],\r\n            &quot;co2_ppm&quot;:     row[3],\r\n            &quot;co_ppm&quot;:      row[4],\r\n            &quot;nox_ppb&quot;:     row[5],\r\n            &quot;pm25_ugm3&quot;:   row[6],\r\n            &quot;temperature&quot;: row[7],\r\n            &quot;humidity&quot;:    row[8],\r\n            &quot;aqi_status&quot;:  row[9],\r\n        })\r\n    return readings<\/code><\/pre>\n<\/div>\n<p>\nTo prevent sudden status changes caused by a single noisy sensor reading, the system evaluates vehicle conditions using a rolling window of the five most recent readings. Averaging the latest five values makes the monitoring logic stable and resistant to temporary spikes:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">window = readings[:5]\r\n\r\navgs = {\r\n    k: sum(r[k] for r in window) \/ len(window)\r\n    for k in (&quot;mq2&quot;,&quot;mq135&quot;,&quot;co2_ppm&quot;,&quot;co_ppm&quot;,&quot;nox_ppb&quot;,&quot;pm25_ugm3&quot;,&quot;temperature&quot;,&quot;humidity&quot;)\r\n}<\/code><\/pre>\n<\/div>\n<h3 id=\"aqi-risk-scoring\"><strong>AQI Risk Scoring<\/strong><\/h3>\n<p>\nInstead of a simple status label, each vehicle receives a continuous AQI score from 0 to 100 based on exactly how far its sensor values have drifted from safe ranges. A vehicle with CO at 18 ppm (just above the 15 ppm warning threshold) and a vehicle with CO at 40 ppm (past the 35 ppm critical threshold) both count as elevated in a simple threshold system. With continuous scoring, the second vehicle scores significantly higher because its readings are more serious.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">def sensor_severity(value, normal_max, warning, critical):\r\n    if value &lt;= normal_max:\r\n        return 0.0\r\n    elif value &lt;= warning:\r\n        return 0.30 * (value - normal_max) \/ max(warning - normal_max, 1e-9)\r\n    elif value &lt;= critical:\r\n        return 0.30 + 0.70 * (value - warning) \/ max(critical - warning, 1e-9)\r\n    else:\r\n        return min(1.0 + ((value - critical) \/ max(abs(critical - warning), 1e-9)) * 0.5, 1.5)\r\n\r\n\r\ndef vehicle_aqi_score(vehicle_id, avgs):\r\n    thr = VEHICLES[vehicle_id][&quot;thresholds&quot;]\r\n    nrm = VEHICLES[vehicle_id][&quot;normal&quot;]\r\n\r\n    scores = {\r\n        &quot;mq2&quot;:       sensor_severity(avgs[&quot;mq2&quot;],       nrm[&quot;mq2&quot;][1],       thr[&quot;mq2&quot;][&quot;warning&quot;],       thr[&quot;mq2&quot;][&quot;critical&quot;]),\r\n        &quot;mq135&quot;:     sensor_severity(avgs[&quot;mq135&quot;],     nrm[&quot;mq135&quot;][1],     thr[&quot;mq135&quot;][&quot;warning&quot;],     thr[&quot;mq135&quot;][&quot;critical&quot;]),\r\n        &quot;co2_ppm&quot;:   sensor_severity(avgs[&quot;co2_ppm&quot;],   nrm[&quot;co2_ppm&quot;][1],   thr[&quot;co2_ppm&quot;][&quot;warning&quot;],   thr[&quot;co2_ppm&quot;][&quot;critical&quot;]),\r\n        &quot;co_ppm&quot;:    sensor_severity(avgs[&quot;co_ppm&quot;],    nrm[&quot;co_ppm&quot;][1],    thr[&quot;co_ppm&quot;][&quot;warning&quot;],    thr[&quot;co_ppm&quot;][&quot;critical&quot;]),\r\n        &quot;nox_ppb&quot;:   sensor_severity(avgs[&quot;nox_ppb&quot;],   nrm[&quot;nox_ppb&quot;][1],   thr[&quot;nox_ppb&quot;][&quot;warning&quot;],   thr[&quot;nox_ppb&quot;][&quot;critical&quot;]),\r\n        &quot;pm25_ugm3&quot;: sensor_severity(avgs[&quot;pm25_ugm3&quot;], nrm[&quot;pm25_ugm3&quot;][1], thr[&quot;pm25_ugm3&quot;][&quot;warning&quot;], thr[&quot;pm25_ugm3&quot;][&quot;critical&quot;]),\r\n    }\r\n    weighted = sum(scores[k] * SENSOR_WEIGHTS[k] for k in SENSOR_WEIGHTS)\r\n    return min(round(weighted * 100), 100)<\/code><\/pre>\n<\/div>\n<p>\nThe fleet-wide emission index is a weighted average across all eight vehicles. Heavier diesel vehicles like VH001 and VH007 carry higher weights because their emissions have a greater impact on the overall fleet footprint. Active emission correlations add a penalty of 8 points each, up to a maximum of 25 additional points.\n<\/p>\n<h3 id=\"emission-correlation-detection\"><strong>Emission Correlation Detection<\/strong><\/h3>\n<p>\nThe system understands that emission sensors are chemically connected. Elevated CO usually indicates incomplete combustion, which produces more particulate matter. High exhaust temperature drives NOx formation. These relationships are defined as rules in vehicles.py:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-python\">EMISSION_RULES = [\r\n    {\r\n        &quot;source&quot;:  &quot;co_ppm&quot;,\r\n        &quot;target&quot;:  &quot;pm25_ugm3&quot;,\r\n        &quot;message&quot;: (\r\n            &quot;Incomplete Combustion: Elevated CO is correlated with rising PM2.5. &quot;\r\n            &quot;Rich fuel mixture may be causing unburnt particulate matter in exhaust.&quot;\r\n        ),\r\n    },\r\n    {\r\n        &quot;source&quot;:  &quot;temperature&quot;,\r\n        &quot;target&quot;:  &quot;nox_ppb&quot;,\r\n        &quot;message&quot;: (\r\n            &quot;Thermal NOx Formation: High exhaust temperature is correlated with &quot;\r\n            &quot;elevated NOx levels. High-temperature combustion promotes nitrogen oxide formation.&quot;\r\n        ),\r\n    },\r\n    {\r\n        &quot;source&quot;:  &quot;mq2&quot;,\r\n        &quot;target&quot;:  &quot;co2_ppm&quot;,\r\n        &quot;message&quot;: (\r\n            &quot;Rich Mixture Alert: High MQ2 reading is correlated with elevated CO2. &quot;\r\n            &quot;Fuel-rich combustion detected.&quot;\r\n        ),\r\n    },\r\n]<\/code><\/pre>\n<\/div>\n<p>\nWhen a vehicle&#8217;s source sensor is in a Poor or Dangerous state, a correlation alert is raised on the dashboard showing which secondary sensor is likely to be affected next.\n<\/p>\n<h2 id=\"continuous-telemetry-stream\"><strong>Continuous Telemetry Stream<\/strong><\/h2>\n<p>\nIn addition to inserting the initial dataset, the system supports a background heartbeat producer that continuously sends Safe readings to GridDB every five seconds. This keeps the dashboard feed alive with fresh data between simulation runs.\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-bash\">python insert_data.py --live<\/code><\/pre>\n<\/div>\n<p>\nWhen the emission simulation is triggered, the producer can be left running. Its Safe readings will be overwritten by the simulation&#8217;s escalating data during the active simulation window. Once the simulation ends and the Issue Resolved button is clicked, the system injects a recovery batch of Safe readings and the dashboard returns to a clean state immediately.\n<\/p>\n<h2 id=\"building-the-monitoring-dashboard\"><strong>Building the Monitoring Dashboard<\/strong><\/h2>\n<p>\nThe EmissGuard dashboard is a single HTML file served directly by the Flask application. It uses Chart.js for time-series visualization and polls the backend API every four seconds. The interface displays per-vehicle emission cards, AQI score bars, sensor history charts across three tab panels, emission correlation alerts, and a fleet-wide escalation timeline.\n<\/p>\n<p>\nThe backend exposes a set of simple API endpoints that the dashboard polls periodically:\n<\/p>\n<table class=\"markdown-table\" style=\"border-collapse: collapse; width: 100%; margin: 1em 0;\">\n<thead>\n<tr>\n<th style=\"border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; text-align: left;\">Endpoint<\/th>\n<th style=\"border: 1px solid #ddd; padding: 8px; background-color: #f2f2f2; text-align: left;\">What it returns<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">GET \/api\/fleet<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Status of all vehicles + correlations + emission index<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">GET \/api\/vehicle\/&lt;id&gt;<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Sensor history for one vehicle (used for charts)<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">GET \/api\/stats\/&lt;id&gt;<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Min, max, and average per sensor over recent history<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">GET \/api\/timeline<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Log of emission status-change events<\/td>\n<\/tr>\n<tr>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">GET \/api\/latest<\/td>\n<td style=\"border: 1px solid #ddd; padding: 8px; text-align: left;\">Single most recent reading per vehicle<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\nBelow is a simplified example of how the dashboard fetches fleet data and updates the interface:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-javascript\">async function pollFleet() {\r\n    try {\r\n        const res  = await fetch('\/api\/fleet');\r\n        const data = await res.json();\r\n\r\n        updateStrip(data);\r\n        buildSidebar(data);\r\n        updateCorr(data);\r\n\r\n        if (!selectedVid) buildCards(data);\r\n\r\n        document.getElementById('lastTs').textContent =\r\n            new Date().toLocaleTimeString('en-IN', {hour12: false});\r\n\r\n    } catch(e) {\r\n        console.warn('Poll error:', e);\r\n    }\r\n}<\/code><\/pre>\n<\/div>\n<p>\nThe complete implementation can be found in the project repository.\n<\/p>\n<p>\nThe dashboard calls the fleet endpoint every four seconds to stay synchronized with the latest vehicle data stored in GridDB. The vehicle detail view fetches sensor history from \/api\/vehicle\/&lt;id&gt; and renders eight Chart.js line charts across three tabs: Primary Sensors (MQ2 and MQ135), Emission Gases (CO2, CO, NOx, PM2.5), and Temperature plus Humidity.\n<\/p>\n<h2 id=\"running-the-project\"><strong>Running the Project<\/strong><\/h2>\n<p>\nMake sure GridDB is running and credentials are configured as environment variables. Then run the following in order:\n<\/p>\n<div class=\"clipboard\">\n<pre><code class=\"language-bash\"># Step 1: Create containers and seed historical data (1,480 rows across 8 vehicles)\r\npython src\/insert_data.py\r\n\r\n# Step 2: Verify that data was stored correctly\r\npython src\/query_data.py\r\n\r\n# Step 3: Start the monitoring backend and dashboard\r\npython src\/app.py\r\n\r\n# Step 4 (optional): Keep the dashboard alive with a live heartbeat\r\npython src\/insert_data.py --live\r\n\r\n# Step 5 (optional): Trigger a live escalation demonstration\r\npython src\/simulate_emission.py<\/code><\/pre>\n<\/div>\n<p>\nOpen http:\/\/localhost:5050 to view the EmissGuard dashboard.\n<\/p>\n<p>\nThe project uses two separate data-feeding mechanisms to make the demonstration repeatable:\n<\/p>\n<p>\n<strong>The Background Heartbeat (insert_data.py &#8211;live):<\/strong> This script provides a stable Safe baseline so the dashboard stays active and shows green status by default.\n<\/p>\n<p>\n<strong>The Manual Escalation (simulate_emission.py):<\/strong> This script temporarily takes over with a four-phase emission event to show how pollution builds across the fleet.\n<\/p>\n<p>\nOne of the practical advantages of using GridDB here is the automatic recovery behavior. Once the escalation script finishes and the operator clicks Issue Resolved, the background producer continues sending Safe data. These new clean readings overwrite the elevated values in the rolling window and the dashboard returns to a normal state without requiring any manual reset.\n<\/p>\n<h2 id=\"results-and-dashboard-overview\"><strong>Results and Dashboard Overview<\/strong><\/h2>\n<p>\nAfter running the system, the EmissGuard dashboard displays the real-time emission status of all eight vehicles. The interface shows sensor readings for MQ2, MQ135, CO2, and PM2.5 on the fleet card view, along with the AQI score and current status badge for each vehicle.\n<\/p>\n<p><a href=\"\/wp-content\/uploads\/2026\/10\/dashboard.png\"><img decoding=\"async\" src=\"\/wp-content\/uploads\/2026\/10\/dashboard.png\" alt=\"\" width=\"1920\" height=\"1080\" class=\"aligncenter size-full wp-image-55628\" srcset=\"\/wp-content\/uploads\/2026\/10\/dashboard.png 1920w, \/wp-content\/uploads\/2026\/10\/dashboard-300x169.png 300w, \/wp-content\/uploads\/2026\/10\/dashboard-1024x576.png 1024w, \/wp-content\/uploads\/2026\/10\/dashboard-768x432.png 768w, \/wp-content\/uploads\/2026\/10\/dashboard-1536x864.png 1536w, \/wp-content\/uploads\/2026\/10\/dashboard-150x85.png 150w, \/wp-content\/uploads\/2026\/10\/dashboard-600x338.png 600w\" sizes=\"(max-width: 1920px) 100vw, 1920px\" \/><\/a><\/p>\n<h3 id=\"safe-operation\"><strong>Safe Operation<\/strong><\/h3>\n<p>\nIn the safe state, all eight vehicles operate within their normal emission ranges. The dashboard displays a low fleet emission index and all vehicle cards show a green Safe badge. The emission correlation panel shows no active alerts.\n<\/p>\n<h3 id=\"moderate-and-poor-conditions\"><strong>Moderate and Poor Conditions<\/strong><\/h3>\n<p>\nAs the simulation advances, VH001 and VH007 begin showing elevated readings. The dashboard updates their status badges to Moderate and then Poor. The fleet emission index rises as the weighted average reflects the degrading sensor values. When two or more sensors on a vehicle cross their warning thresholds simultaneously, the system detects an emission correlation and displays it in the correlation panel with a description of the likely chemical cause.\n<\/p>\n<h3 id=\"dangerous-cascade\"><strong>Dangerous Cascade<\/strong><\/h3>\n<p>\nWhen VH001 and VH007 enter the Dangerous state, the fleet emission index climbs sharply. The correlation panel shows multiple active alerts. The escalation timeline at the bottom of the dashboard logs every status-change event with a timestamp, vehicle name, and fuel type. The operator can click Issue Resolved to inject recovery data and watch the system return to normal in real time.\n<\/p>\n<h3 id=\"vehicle-detail-view\"><strong>Vehicle Detail View<\/strong><\/h3>\n<p>\nClicking any vehicle card opens a detail panel with four summary statistics (AQI score, average CO2, average CO, and maximum PM2.5) and eight Chart.js line charts organized across three tabs. The charts render up to 200 historical readings pulled from GridDB through the \/api\/vehicle\/&lt;id&gt; endpoint, giving a clear picture of how each sensor has behaved over the monitored period.\n<\/p>\n<h2 id=\"conclusion\"><strong>Conclusion<\/strong><\/h2>\n<p>\nVehicle emissions do not usually become a problem at a single moment in time. The readings build gradually. A system that only checks whether a value is above a fixed threshold today will miss the trend that has been developing over the past ten minutes.\n<\/p>\n<p>\nIn this project, we built EmissGuard, a fleet emission monitoring prototype using GridDB to store and query vehicle sensor data. By combining simulated multi-sensor readings with rolling-window analysis, weighted AQI scoring, and cross-sensor correlation rules, the system can detect early emission patterns before individual sensors cross their critical thresholds.\n<\/p>\n<p>\nGridDB TIME_SERIES containers, the multi_put batch ingestion operation, and TQL time-window queries made it straightforward to build a system that ingests data from eight vehicles simultaneously, analyzes it on every poll cycle, and feeds it into an ML training pipeline, all from a simple Python codebase with no external dependencies beyond the GridDB client and Flask.\n<\/p>\n<p>\nThe complete implementation can be found in the project repository: <a href=\"https:\/\/github.com\/DoneByManthan\/GridDB-EmissGuard\">github.com\/DoneByManthan\/GridDB-EmissGuard<\/a>\n<\/p>\n<p>\nIn the future, this approach could be extended with anomaly detection models trained on the historical GridDB data to identify unusual emission signatures that do not fit any predefined rule.\n<\/p>\n<p>\nPer-vehicle baseline learning, where the system builds a personal normal profile from the first week of data for each vehicle, would make the threshold system more accurate for mixed fleets where different vehicles have genuinely different operating profiles. Integration with real OBD-II sensor hardware would allow the same codebase to transition from simulation to production monitoring without changes to the GridDB storage or analysis layers.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture will show elevated CO readings before its PM2.5 levels cross into dangerous territory. A CNG bus operating in stop-start city traffic will accumulate NOx gradually across a shift, not all at [&hellip;]<\/p>\n","protected":false},"author":779,"featured_media":55632,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[121],"tags":[],"class_list":["post-55618","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.8 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard | GridDB: Open Source Time Series Database for IoT<\/title>\n<meta name=\"description\" content=\"Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard | GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"og:description\" content=\"Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/\" \/>\n<meta property=\"og:site_name\" content=\"GridDB: Open Source Time Series Database for IoT\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/griddbcommunity\/\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-21T20:13:49+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-28T21:24:47+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.griddb.net\/wp-content\/uploads\/2026\/10\/emissguard_featured.png\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"630\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"reviewer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:site\" content=\"@GridDBCommunity\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"reviewer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"13 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/\"},\"author\":{\"name\":\"reviewer\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#\\\/schema\\\/person\\\/9796b06dbb0e63dcaaf67892e45c3df2\"},\"headline\":\"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard\",\"datePublished\":\"2026-10-21T20:13:49+00:00\",\"dateModified\":\"2026-10-28T21:24:47+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/\"},\"wordCount\":2834,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/#primaryimage\"},\"thumbnailUrl\":\"\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/emissguard_featured.png\",\"articleSection\":[\"Blog\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/\",\"url\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/\",\"name\":\"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard | GridDB: Open Source Time Series Database for IoT\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/#primaryimage\"},\"thumbnailUrl\":\"\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/emissguard_featured.png\",\"datePublished\":\"2026-10-21T20:13:49+00:00\",\"dateModified\":\"2026-10-28T21:24:47+00:00\",\"description\":\"Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/blog\\\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\\\/#primaryimage\",\"url\":\"\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/emissguard_featured.png\",\"contentUrl\":\"\\\/wp-content\\\/uploads\\\/2026\\\/10\\\/emissguard_featured.png\",\"width\":1200,\"height\":630},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#website\",\"url\":\"https:\\\/\\\/www.griddb.net\\\/\",\"name\":\"GridDB: Open Source Time Series Database for IoT\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.griddb.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#organization\",\"name\":\"Fixstars\",\"url\":\"https:\\\/\\\/www.griddb.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.griddb.net\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/fixstars_logo_web_tagline.png\",\"contentUrl\":\"https:\\\/\\\/www.griddb.net\\\/wp-content\\\/uploads\\\/2019\\\/04\\\/fixstars_logo_web_tagline.png\",\"width\":200,\"height\":83,\"caption\":\"Fixstars\"},\"image\":{\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/griddbcommunity\\\/\",\"https:\\\/\\\/x.com\\\/GridDBCommunity\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/griddb-by-toshiba\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.griddb.net\\\/#\\\/schema\\\/person\\\/9796b06dbb0e63dcaaf67892e45c3df2\",\"name\":\"reviewer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/56c7498f718fe0de13a8d0595e73985d070bf1fb1bcd75b4f3d4de32b5c7ad46?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/56c7498f718fe0de13a8d0595e73985d070bf1fb1bcd75b4f3d4de32b5c7ad46?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/56c7498f718fe0de13a8d0595e73985d070bf1fb1bcd75b4f3d4de32b5c7ad46?s=96&d=mm&r=g\",\"caption\":\"reviewer\"},\"url\":\"https:\\\/\\\/www.griddb.net\\\/en\\\/author\\\/reviewer\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard | GridDB: Open Source Time Series Database for IoT","description":"Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/","og_locale":"en_US","og_type":"article","og_title":"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard | GridDB: Open Source Time Series Database for IoT","og_description":"Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture","og_url":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/","og_site_name":"GridDB: Open Source Time Series Database for IoT","article_publisher":"https:\/\/www.facebook.com\/griddbcommunity\/","article_published_time":"2026-10-21T20:13:49+00:00","article_modified_time":"2026-10-28T21:24:47+00:00","og_image":[{"width":1200,"height":630,"url":"https:\/\/www.griddb.net\/wp-content\/uploads\/2026\/10\/emissguard_featured.png","type":"image\/png"}],"author":"reviewer","twitter_card":"summary_large_image","twitter_creator":"@GridDBCommunity","twitter_site":"@GridDBCommunity","twitter_misc":{"Written by":"reviewer","Est. reading time":"13 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/#article","isPartOf":{"@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/"},"author":{"name":"reviewer","@id":"https:\/\/www.griddb.net\/#\/schema\/person\/9796b06dbb0e63dcaaf67892e45c3df2"},"headline":"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard","datePublished":"2026-10-21T20:13:49+00:00","dateModified":"2026-10-28T21:24:47+00:00","mainEntityOfPage":{"@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/"},"wordCount":2834,"commentCount":0,"publisher":{"@id":"https:\/\/www.griddb.net\/#organization"},"image":{"@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2026\/10\/emissguard_featured.png","articleSection":["Blog"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/","url":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/","name":"Real-Time Vehicle Emission Monitoring with GridDB and EmissGuard | GridDB: Open Source Time Series Database for IoT","isPartOf":{"@id":"https:\/\/www.griddb.net\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/#primaryimage"},"image":{"@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/#primaryimage"},"thumbnailUrl":"\/wp-content\/uploads\/2026\/10\/emissguard_featured.png","datePublished":"2026-10-21T20:13:49+00:00","dateModified":"2026-10-28T21:24:47+00:00","description":"Introduction Vehicle emissions do not become dangerous in a single instant. The process is gradual. A diesel truck running a slightly rich fuel mixture","inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/en\/blog\/real-time-vehicle-emission-monitoring-with-griddb-and-emissguard\/#primaryimage","url":"\/wp-content\/uploads\/2026\/10\/emissguard_featured.png","contentUrl":"\/wp-content\/uploads\/2026\/10\/emissguard_featured.png","width":1200,"height":630},{"@type":"WebSite","@id":"https:\/\/www.griddb.net\/#website","url":"https:\/\/www.griddb.net\/","name":"GridDB: Open Source Time Series Database for IoT","description":"","publisher":{"@id":"https:\/\/www.griddb.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.griddb.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.griddb.net\/#organization","name":"Fixstars","url":"https:\/\/www.griddb.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.griddb.net\/#\/schema\/logo\/image\/","url":"https:\/\/www.griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","contentUrl":"https:\/\/www.griddb.net\/wp-content\/uploads\/2019\/04\/fixstars_logo_web_tagline.png","width":200,"height":83,"caption":"Fixstars"},"image":{"@id":"https:\/\/www.griddb.net\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/griddbcommunity\/","https:\/\/x.com\/GridDBCommunity","https:\/\/www.linkedin.com\/company\/griddb-by-toshiba"]},{"@type":"Person","@id":"https:\/\/www.griddb.net\/#\/schema\/person\/9796b06dbb0e63dcaaf67892e45c3df2","name":"reviewer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/56c7498f718fe0de13a8d0595e73985d070bf1fb1bcd75b4f3d4de32b5c7ad46?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/56c7498f718fe0de13a8d0595e73985d070bf1fb1bcd75b4f3d4de32b5c7ad46?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/56c7498f718fe0de13a8d0595e73985d070bf1fb1bcd75b4f3d4de32b5c7ad46?s=96&d=mm&r=g","caption":"reviewer"},"url":"https:\/\/www.griddb.net\/en\/author\/reviewer\/"}]}},"_links":{"self":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/55618","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/users\/779"}],"replies":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/comments?post=55618"}],"version-history":[{"count":3,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/55618\/revisions"}],"predecessor-version":[{"id":55631,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/posts\/55618\/revisions\/55631"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media\/55632"}],"wp:attachment":[{"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/media?parent=55618"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/categories?post=55618"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.griddb.net\/en\/wp-json\/wp\/v2\/tags?post=55618"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}