forked from winstonma/MMM-HK-Transport
-
Notifications
You must be signed in to change notification settings - Fork 0
/
node_helper.js
161 lines (141 loc) · 5.37 KB
/
node_helper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/* Magic Mirror
* Node Helper: MMM-HK-Transport
*
* By Winston / https://github.com/winstonma
* AGPL-3.0 Licensed.
*/
const ETAFetcher = require("./etafetcher.js");
const NodeHelper = require("node_helper");
const got = require('got');
const Log = require("../../js/logger");
const csv = require('csv-parser')
const fs = require('fs')
let lines = {};
const linesReference = function() {
Log.log("Start Reference");
const results = [];
fs.createReadStream('modules/MMM-IdF-Transport/referentiel-des-lignes-de-transport-en-commun-dile-de-france.csv')
.pipe(csv({ separator: '\;'}))
.on('data', (data) => results.push(data))
.on('end', () => {
results.forEach(function(item){
let busImage = "https://data.iledefrance.fr/api/explore/v2.1/catalog/datasets/referentiel-des-lignes-de-transport-en-commun-dile-de-france/files/37b0b83646222f1e3a45084a6eb6a7f7";
item.lineHtml = item.ShortName_Line;
if (item.Picto) {
item.lineHtml = `<img class="pictoIcon" src="${item.Picto}"/>`;
} else {
if (item.TransportMode.normalize() === 'bus') {
item.lineHtml = `<div class="bus" style="background-color:#${item.ColourWeb_hexa}">
<img class="lineIcon" src=${busImage}/><div class="bus">${item.ShortName_Line}</div></div>`;
}
}
lines[`STIF\:Line\:\:${item.ID_Line}\:`] = item;
});
});
}
module.exports = NodeHelper.create({
// Override start method.
start: function () {
Log.log("Starting node helper for: " + this.name);
linesReference();
this.fetchers = [];
},
// Override socketNotificationReceived received.
socketNotificationReceived: function (notification, payload) {
if (notification === 'ADD_STOP') {
this.getStopInfo(payload.stop, payload.config);
return;
}
},
/**
* Obtain the stop id from the URL
*
* @param {object} stopInfo The stopInfo.
* @param {object} config The configuration object.
*/
getStopInfo: function (stopInfo, config) {
const baseURL = "https://prim.iledefrance-mobilites.fr/marketplace/stop-monitoring?MonitoringRef=";
url = baseURL + stopInfo.stopID;
if (stopInfo.lineID)
{
url = url + "&LineRef=" + stopInfo.lineID;
}
Log.log(url)
// TODO remove debug log
Log.log("Connecting to : " + url);
// TODO remove debug log
Log.log(stopInfo);
(async () => {
try {
const {body} = await got(url, {
responseType : 'json',
headers : {apikey : config.apiKey}
});
// TODO remove debug log
Log.log(body.Siri.ServiceDelivery.StopMonitoringDelivery[0].MonitoredStopVisit[0].MonitoredVehicleJourney.MonitoredCall.ExpectedArrivalTime)
this.createFetcher(stopInfo.stopID, stopInfo, config);
} catch (error) {
this.sendSocketNotification("FETCH_ERROR", {
stopID: stopInfo.stopID,
error: error
});
}
})();
},
/**
* Creates a fetcher for an ETA feed if it doesn't exist yet.
* Otherwise, it reuses the existing one.
*
* @param {object} stopID The stopID.
* @param {object} stopInfo The stopInfo.
* @param {object} config The configuration object.
*/
createFetcher: function (stopID, stopInfo, config) {
Log.log("Create Fetcher")
if (stopInfo.lineID)
{
url = `${config.primURL}${stopID}&LineRef=${stopInfo.lineID}` || "";
} else
{
url = `${config.primURL}${stopID}` || "";
}
const reloadInterval = stopInfo.reloadInterval || config.reloadInterval || 5 * 60 * 1000;
try {
new URL(url);
} catch (error) {
this.sendSocketNotification("INCORRECT_URL", url);
return;
}
let fetcher;
if (this.fetchers[stopInfo.stopID] === undefined) {
Log.log("Create new PRIM fetcher for url: " + url + " - Interval: " + reloadInterval);
fetcher = new ETAFetcher(url, stopInfo.stopID, reloadInterval, config.apiKey, lines);
fetcher.onReceive(() => {
this.broadcastFeeds();
});
fetcher.onError((fetcher, error) => {
this.sendSocketNotification("FETCH_ERROR", {
url: fetcher.url(),
error: error
});
});
this.fetchers[stopInfo.stopID] = fetcher;
} else {
Log.log("Use existing PRIM fetcher for url: " + url);
fetcher = this.fetchers[stopInfo.stopID];
fetcher.setReloadInterval(reloadInterval);
fetcher.broadcastItems();
}
fetcher.startFetch();
},
/**
* Creates an object with all ETA items of the different registered stopID,
* and broadcasts these using sendSocketNotification.
*/
broadcastFeeds: function () {
const feeds = Object.entries(this.fetchers)
.map(([key, fetcher]) => [key, fetcher.items()])
.reduce((r, [k, v]) => ({ ...r, [k]: v }), {});
this.sendSocketNotification("STOP_ITEMS", feeds);
},
});