Power Apps NFC School Bus App: Real-Time Tracking & Insights

In the interior of Portugal, school-aged children have to travel dozens of kilometers daily to attend school. For many families, the long distance between home and school has been a difficult problem to solve. Fortunately, today, some municipalities offer transportation services that allow these children to reach school on time and in comfort, helping them perform at their best—and have fun doing so.

My team and I had the privilege of developing a Power Apps application that records the children’s check-ins on the various school buses. The app stores all relevant information: check-in date and time, bus stop location, route and direction, pass validity, and student identification.

Process, Investment, and App Data

The process of building a Canvas App in the Power Platform is quite fast. The entire project took about a month—from the idea to reading the first passes. We started with a design concept for an Android application capable of reading NFC tags. For the students, all that is needed is a card they tap on the phone—nothing more.

The investment required is minimal. The only requirement for the client is an Office 365 account, which costs less than €10 per month. NFC cards cost less than €1 each.

The data infrastructure is also very simple. Since the app doesn’t require processing large data volumes, we used SharePoint lists as the backend. This avoids delegation issues within the app.

Application Design

The app design is intuitive. The bus driver needs to set a few basic configurations when launching the app, such as the route and direction, and whether bus stops should be identified automatically or manually. That’s it.

To enable automatic stop detection, it was necessary to collect the geographical coordinates of each stop and use the Power Apps location feature. Then, by calculating the distance between the mobile device’s current position and each stop, the app identifies the closest one.

This part of the development is slightly more technical, so here’s the Power Fx formula that makes it work:


Set(gblLatitudeAtual, Location.Latitude);
Set(gblLongitudeAtual, Location.Longitude);

// Calculate the distance to each stop and store it in the "Distance" column
If(tglDetecaoParagem.Checked, // if automatic stop detection is active
    ClearCollect(
        colRotasComDistancia,
        ForAll(
            colRotas,
            {
                Paragem: Paragem,
                Latitude: Latitude,
                Longitude: Longitude,
                Distancia:
                    6371000 * 2 * 
                    Asin(
                        Sqrt(
                            Power(Sin((Latitude - gblLatitudeAtual) * Pi() / 180 / 2), 2) +
                            Cos(gblLatitudeAtual * Pi() / 180) * 
                            Cos(Latitude * Pi() / 180) * 
                            Power(Sin((Longitude - gblLongitudeAtual) * Pi() / 180 / 2), 2)
                        )
                    )
            }
        )
    );

    // Find the stop with the shortest distance
    Set(
        gblParagemMaisProxima,
        First(
            SortByColumns(colRotasComDistancia, "Distancia", SortOrder.Ascending)
        ).Paragem
    ),

    // Set the stop based on the dropdown selection
    Set(
        gblParagemMaisProxima, 
        drpParagens.Selected.Paragem
    )
);

As shown in the code above, there are essentially three blocks:

  • In the first block, the current geographic coordinates are stored in global variables gblLatitudeAtual e gblLongitudeAtual using the Location function.
  • In the second block, if automatic stop detection is active, a collection is created (a variable that holds multiple records in memory) containing all stops and their distance in meters from the current location.
  • In the third block, the collection is sorted by ascending distance to find the closest stop, which is stored in the global variable gblParagemMaisProxima.

This process is only necessary if automatic detection is enabled. If manual selection is preferred, the driver can choose the stop from a dropdown. In that case, the previous screen would be replaced by the following:

NFC Pass Scanning

Since children usually board the bus in a hurry, a continuous scanning process is essential. That is, after one pass is scanned, another should follow immediately, and so on. The scanning process must not be too slow, but also not too fast—so we chose a two-second interval between scans. This gives the driver enough time to verify if the pass was read correctly without creating long queues.

While the app waits for the next pass to be scanned, the following screen is displayed:

If the pass is not recognized or has expired, the following screen is displayed, along with a friendly alert sound, allowing the driver to decide what to do. The same happens if the pass is valid but still expired:

Offline Data

In some locations, mobile data access is unreliable, and the device may lose connection for a few minutes. To ensure all scans are eventually saved to SharePoint, the app must continue to function even while offline.


// If online, send data to SharePoint

If(
    Connection.Connected,
        Patch(
            LeiturasNFC,
            Defaults(LeiturasNFC),
            {ID_NFC: Coalesce(Text, URI), ROTA_ID: gblIdRota, DataHora: Now()}
        ),
        // Otherwise, save data locally
        Collect(colDadosLocais, 
            {IDNFC: Coalesce(Text, URI), ROTAID: gblIdRota, DATAHORA: Now()})
)

If there’s no connection, the data is stored locally on the device and automatically sent to SharePoint once the connection is restored. This process runs every minute.

Power BI Reading Analysis

Finally, to analyze pass readings, we created a Power BI report that retrieves data from the SharePoint lists. The analysis uses Power BI’s interactive visuals, which are extremely flexible. Since we also have geographic information, we can plot the data on maps and visualize indicators such as:

  • Number of students per stop
  • Check-in times per stop
  • Number of valid and expired passes
Partilhe o seu amor
Nuno Nogueira
Nuno Nogueira
Artigos: 36

Deixe um comentário

Your email address will not be published. Required fields are marked *