Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 43 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,43 @@
node_modules/
package-lock.json
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/
.kotlin

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
### node
node_modules


/logs
28 changes: 28 additions & 0 deletions GTFS-realtime-example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"id": "217990500977445278",
"tripUpdate": {
"trip": {
"tripId": "217990000033906692",
"startDate": "20241009",
"scheduleRelationship": "SCHEDULED"
},
"stopTimeUpdate": [
{
"stopSequence": 4,
"arrival": {
"delay": 2580,
"time": "1728498960"
},
"departure": {
"delay": 2580,
"time": "1728498960"
},
"stopId": "9022021490014017"
}
],
"vehicle": {
"id": "9031021301100580"
},
"timestamp": "1728495864"
}
}
26 changes: 14 additions & 12 deletions MMM-ResRobot.css
Original file line number Diff line number Diff line change
@@ -1,40 +1,42 @@
.ResRobot {
.MMM-ResRobot {
font-size: 75%;
line-height: 65px;
display: inline-block;
width: fit-content;
-ms-transform: translate(0, -3px); /* IE 9 */
-webkit-transform: translate(0, -3px); /* Safari */
transform: translate(0, -3px);
}

.ResRobot table {
width: 400px;
/* width: fit-content; */
}

.departuretime {
width: 20%;
align: left;
padding-right: 10px;
}

/*
.departuretype {
width: 10%;
align: right;
padding-right: 10px;
}

.linetype {
padding-right: 10px;
}


.lineno {
width: 15%;
align: right;
padding-right: 10px;
}



.trackno {
width: 10%;
align: right;
text-align: right;
padding-right: 10px;
}

.destination {
align: left;
}
text-align: left;
} */
102 changes: 72 additions & 30 deletions MMM-ResRobot.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,32 @@
* based on a script from Michael Teeuw http://michaelteeuw.nl
* MIT Licensed.
*/
Module.register("MMM-ResRobot",{
Module.register("MMM-ResRobot", {

// Define module defaults
defaults: {
updateInterval: 1 * 60 * 1000, // Update module every minute.
animationSpeed: 2000,
fade: true,
fadePoint: 0.25, // Start on 1/4th of the list.
apiBase: "https://api.resrobot.se/v2.1/departureBoard?format=json&passlist=0",
apiKey: "<YOUR RESROBOT API KEY HERE>",
ResRobot: {
apiBase: "https://api.resrobot.se/v2.1/departureBoard?format=json&passlist=0",
apiKey: "<YOUR RESROBOT API KEY HERE>",
directionFlag: "2"
},
GTFSRegionalRealtime: {
apiKey: "<YOUR GTFS-Regional-Realtime API KEY HERE>",
operator: 'xt',
stopId: '9022021480123002',
baseUrl: "https://opendata.samtrafiken.se/gtfs-rt/",
updateFreq: {
morning: {start: 6, end: 10, frequency: 60}, // 06:00–10:00
midday: {start: 10, end: 15, frequency: 120}, // 10:00–15:00
afternoon: {start: 15, end: 20, frequency: 60}, // 15:00–20:00
evening: {start: 20, end: 23, frequency: 120}, // 20:00–23:00
night: {start: 23, end: 6, frequency: 300}, // 23:00–06:00
}
},
routes: [
{from: "740020749", to: ""}, // Each route has a starting station ID from ResRobot, default: Stockholm Central Station (Metro)
], // and a destination station ID from ResRobot, default: none
Expand Down Expand Up @@ -46,25 +62,25 @@ Module.register("MMM-ResRobot",{
},

// Define required styles.
getStyles: function() {
getStyles: function () {
return ["MMM-ResRobot.css", "font-awesome.css"];
},

// Define required scripts.
getScripts: function() {
getScripts: function () {
return ["moment.js"];
},

// Define required translations.
getTranslations: function() {
return {
en: "translations/en.json",
sv: "translations/sv.json",
};
},
// Define required translations.
getTranslations: function () {
return {
en: "translations/en.json",
sv: "translations/sv.json",
};
},

// Define start sequence.
start: function() {
start: function () {
Log.info("Starting module: " + this.name);

// Set locale.
Expand All @@ -73,8 +89,8 @@ Module.register("MMM-ResRobot",{
this.initConfig();
},

socketNotificationReceived: function(notification, payload) {
Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload);
socketNotificationReceived: function (notification, payload) {
//Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload);
if (notification === "DEPARTURES") {
this.departures = payload;
this.loaded = true;
Expand All @@ -83,14 +99,15 @@ Module.register("MMM-ResRobot",{
},

// Init config
initConfig: function() {
initConfig: function () {
this.departures = [];
this.delays = [];
this.loaded = false;
this.sendSocketNotification("CONFIG", this.config);
},

// Override dom generator.
getDom: function() {
getDom: function () {
var wrapper = document.createElement("div");

if (this.config.routes === "") {
Expand All @@ -100,7 +117,8 @@ Module.register("MMM-ResRobot",{
}

if (!this.loaded) {
wrapper.innerHTML = "Fetching departures ...";
Log.log(this.name + " is not loaded!!!");
wrapper.innerHTML = "Hämtar tidtabell...";
wrapper.className = "dimmed light small";
return wrapper;
}
Expand All @@ -115,8 +133,13 @@ Module.register("MMM-ResRobot",{
break;
}
var departure = this.departures[d];
if (moment(departure.timestamp).isBefore(cutoff)) {
continue;

let calculatedDepartureTime = departure.updatedTime
? moment.unix(departure.updatedTime)
: moment(departure.timestamp);

if (calculatedDepartureTime.isBefore(cutoff)) {
continue; //this is done in node_helper as well!
}
n++;

Expand All @@ -126,13 +149,32 @@ Module.register("MMM-ResRobot",{
var depTimeCell = document.createElement("td");
depTimeCell.className = "departuretime";
depTimeCell.innerHTML = departure.departureTime;
if (departure.waitingTime < this.config.getRelative) {
if (departure.waitingTime > 1) {
depTimeCell.innerHTML = departure.waitingTime + " " + this.translate("MINUTES_SHORT");
if (departure.waitingTime/60 < this.config.getRelative) {
if (departure.waitingTime > 60 || departure.waitingTime < 0) {
depTimeCell.innerHTML = Math.round(departure.waitingTime / 60) + " " + this.translate("MINUTES_SHORT");
} else {
depTimeCell.innerHTML = this.translate("NOW");
depTimeCell.innerHTML = "<1 min";
}
}
//add GTFS-delay to timetable if pressent!
if (departure.delay && departure.delay !== 0) {
if (departure.delay > 0) {
if (departure.delay < 60 && departure.delay >= 20) {
depTimeCell.innerHTML += ` (+${departure.delay}s)`;
} else if (departure.delay >= 60) {
const delayMinutes = Math.round(departure.delay / 60)
depTimeCell.innerHTML += ` (+${delayMinutes}m)`
}
} else {
if (departure.delay > -60 && departure.delay < -20) {
depTimeCell.innerHTML += ` (${departure.delay}s tidig!)`;
} else if (departure.delay <= -60){
const delayMinutes = Math.round(departure.delay / 60)
depTimeCell.innerHTML += ` (${-delayMinutes}m tidig!)`
}
}
}

row.appendChild(depTimeCell);

var depTypeCell = document.createElement("td");
Expand All @@ -142,7 +184,7 @@ Module.register("MMM-ResRobot",{
if (this.config.coloredIcons) {
if (this.config.colorTable[departure.type]) {
typeSymbol.setAttribute("style", "color:" + this.config.colorTable[departure.type]);
} else {
} else {
typeSymbol.setAttribute("style", "color:" + this.config.colorTable[departure.type.charAt(0)]);
}
}
Expand All @@ -164,11 +206,11 @@ Module.register("MMM-ResRobot",{
var depToCell = document.createElement("td");
depToCell.className = "to";
depToCell.innerHTML = departure.to;
row.appendChild(depToCell);
//row.appendChild(depToCell);

if (this.config.fade && this.config.fadePoint < 1) {
if (this.config.fadePoint < 0) {
this.config.fadePoint = 0;
this.config.fadePoint = 0;
}
var startingPoint = this.config.maximumEntries * this.config.fadePoint;
var steps = this.departures.length - startingPoint;
Expand All @@ -188,17 +230,17 @@ Module.register("MMM-ResRobot",{
/* scheduleUpdate()
* Schedule next update.
*
* argument delay number - Milliseconds before next update. If empty, 30 seconds is used.
* argument delay number - Milliseconds before next update. If empty, 10 seconds is used.
*/
scheduleUpdate: function(delay) {
scheduleUpdate: function (delay) {
var nextLoad = 10000;
if (typeof delay !== "undefined" && delay >= 0) {
nextLoad = delay;
}

var self = this;
clearTimeout(this.updateTimer);
this.updateTimer = setTimeout(function() {
this.updateTimer = setTimeout(function () {
self.updateDom();
self.scheduleUpdate(10000);
}, nextLoad);
Expand Down
Loading