**MMM-WMATA is a module for MagicMirror² that displays rail and bus arrival times from WMATA.
This module allows you to display WMATA train and bus times with expected arrivals on your MagicMirror.
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.
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 installGo to the MMM-WMATA folder inside MagicMirror² modules folder and pull the latest version from GitHub:
cd ~/MagicMirror/modules/MMM-WMATA
git pullRestart MagicMirror² after updating.
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: |
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: |
showTrainIncidents |
Whether to fetch and show train incident information. Type: |
trainIncidentUpdateInterval |
The time in seconds between train incident updates. Type: |
trainFilterFn |
A custom function to filter which trains are displayed. Type: |
busStops |
A list of bus stop IDs to fetch times for. Type: |
busUpdateInterval |
The time in seconds between bus stop updates. Type: |
showEmptyBusStops |
Whether to show bus stops that don't have expected arrivals. Type: |
busStopFilterFn |
A custom function to filter which bus stops are fetched at a given time. Type: |
busRouteIncidentFilterFn |
A custom function to filter displaying notifications for a given route. Type: |
showBusIncidents |
Whether to fetch and show bus incident information. Type: |
busIncidentUpdateInterval |
The time in seconds between bus incident updates. Type: |
hideEmptyTrains |
Whether to hide the trains section entirely when there are no active train predictions or incidents. Type: |
hideEmptyBuses |
Whether to hide the buses section entirely when there are no active bus predictions or incidents. Type: |
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'],
}
},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.
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,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.
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;
}
}Similarly to bus stop filter functions, we can filter incidents for a given route to the ones we're interested in.
busRouteIncidentFilterFn: (_incidentType, route) => route == 'D33',This function would limit displaying incidents unless the incident affected the "D33" line.
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.
