Skip to content

Repository files navigation

MMM-WMATA

**MMM-WMATA is a module for MagicMirror² that displays rail and bus arrival times from WMATA.

Description

This module allows you to display WMATA train and bus times with expected arrivals on your MagicMirror.

Screenshot

Example: WMATA Schedule

How it Works

After you installed MMM-WMATA you just configure it with the train and bus stations that you'd like to monitor. You'll need to generate a developer key at WMATA's website.

For more information see the Configuration section.

Installation

Just clone MMM-WMATA into the modules folder of your MagicMirror² installation:

cd ~/MagicMirror/modules
git clone https://github.com/btoconnor/MMM-WMATA
cd MMM-WMATA
npm install

Update

Go to the MMM-WMATA folder inside MagicMirror² modules folder and pull the latest version from GitHub:

cd ~/MagicMirror/modules/MMM-WMATA
git pull

Restart MagicMirror² after updating.

Configuration

In order to use this module, you need to provide your apiKey and at least one of trainStations or busStops to monitor.

These are the possible options:

Option Description
apiKey

An API key generated from WMATA's developer portal.

REQUIRED Type: string
Example: "eyhJbcG..."
Default value: none

trainStations

A list of train station IDs to fetch times for. See here for a list of codes.

trainUpdateInterval

The time in seconds between rail time updates.

Type: integer
Example: 60 (The train times will be refreshed every 60 seconds (1 minute).)
Default value: 60 (1 minute)
Unit: seconds

showTrainIncidents

Whether to fetch and show train incident information.

Type: boolean
Default value: true

trainIncidentUpdateInterval

The time in seconds between train incident updates.

Type: integer
Example: 60 (The train incidents will be refreshed every 60 seconds (1 minute).)
Default value: 300 (5 minute)
Unit: seconds

trainFilterFn

A custom function to filter which trains are displayed.

Type: function
Default value: All trains are displayed.
Note: See below for information on providing a custom function.

busStops

A list of bus stop IDs to fetch times for.

Type: array
Example: ['1001195', '1001196']
Default value: []

busUpdateInterval

The time in seconds between bus stop updates.

Type: integer
Example: 60 (The bus times will be refreshed every 60 seconds (1 minute).)
Default value: 60 (1 minute)
Unit: seconds

showEmptyBusStops

Whether to show bus stops that don't have expected arrivals.

Type: boolean
Example: true (Bus stops will be shown even if there are no currently predicted buses.)
Default value: true

busStopFilterFn

A custom function to filter which bus stops are fetched at a given time.

Type: function
See notes below.
Default value: All specified buses are fetched at the given interval.
Note: See below for information on providing a custom function.

busRouteIncidentFilterFn

A custom function to filter displaying notifications for a given route.

Type: function
See notes below.
Default value: All bus incidents will be shown.

showBusIncidents

Whether to fetch and show bus incident information.

Type: boolean
Default value: true

busIncidentUpdateInterval

The time in seconds between bus incident updates.

Type: integer
Example: 60 (The bus incidents will be refreshed every 60 seconds (1 minute).)
Default value: 300 (5 minute)
Unit: seconds

hideEmptyTrains

Whether to hide the trains section entirely when there are no active train predictions or incidents.

Type: boolean
Default value: true

hideEmptyBuses

Whether to hide the buses section entirely when there are no active bus predictions or incidents.

Type: boolean
Default value: true

Here is an example of an entry in config.js:

{
    module: "MMM-WMATA",
    header: "WMATA",
    position: "top_left",
    config: {
        apiKey: "eyhJbcG...",
        trainStations: ['C02'],
        busStops: ['1001195'],
    }
},

Train Filter Function

You can provide a custom function to filter which trains are displayed. The function receives a train object and must return a boolean — true to display the train, false to hide it.

Train objects contain properties such as Line, Destination, DestinationName, DestinationCode, Min, MinNumber (numeric minutes until arrival), and LocationName.

Example

To only show Silver line trains:

trainFilterFn: (train) => train.Line === 'SV',

To hide trains arriving in more than 15 minutes:

trainFilterFn: (train) => train.MinNumber <= 15,

To hide trains arriving in less than 5 minutes:

trainFilterFn: (train) => train.MinNumber >= 5,

Bus Stop Filter Functions

The train and bus APIs work slightly differently. We can make a single API call with all the list of train stops and parse them locally to show trains per station. However, the bus stop API works differently - we must make a single API call per stop. To make matters more complicated, buses tend to have separate stops per direction, and in many cases will stop at very similar locations, but technically be separate stops even in the same directions. Many times buses only run to a given "stop" for a few hours a day, even though the line may be active in different directions for different parts of the day. Providing dozens of bus stops could easily exhaust the free API limit and most would be checking on bus stops that are not active at a given point during the day.

In order to avoid exhausting the API limit, you can provide a function in your configuration file that will allow you to remove a given bus stop from being fetched outside of hours of expected operation. The default function is to fetch all bus stops at the given busUpdateInterval.

Example

Let's say a fictional bus line, the "SCHOOL" line, only operates Monday - Friday from 7am to 9am at a given stop "CORNER". Refreshing the stop "CORNER" would be useless outside of those hours.

The filter function is provided the current time, and the stationCode, and must return a boolean determining whether we should fetch bus arrivals for this station.

A potential filter function would be the following:

function(now_datetime, stationCode) {
  const day = now_datetime.getDay();
  const hours = now_datetime.getHours();

  const isWeekend = day == 0 || day == 6;
  const isWeekday = !isWeekend;

  if (stationCode == 'CORNER') {
      // CORNER is only used M-F in the morning
      return (isWeekday && (hours > 6) && (hours < 10));
  } else {
      // It is recommended to return true by default if a bus stop isn't
      // explicitly handled.
      return true;
  }
}

Bus Route Incident Filter Functions

Similarly to bus stop filter functions, we can filter incidents for a given route to the ones we're interested in.

Example:

busRouteIncidentFilterFn: (_incidentType, route) => route == 'D33',

This function would limit displaying incidents unless the incident affected the "D33" line.

Special Thanks

I originally attempted to use MMM-DCMetroTimes, but had some issues with bus times on lines that didn't run throughout the day. While I ultimately rewrote this plugin from scratch, I referenced the code of this repository during development.

About

MagicMirror² module for DC Metro Area's WMATA System

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages