Merge pull request #24 from 0hAodha/conor

Add basic statistics and emulator handling
This commit is contained in:
2023-03-02 14:25:35 +00:00
committed by GitHub
4 changed files with 105 additions and 12 deletions

1
.gitignore vendored
View File

@ -64,5 +64,4 @@ node_modules/
# dotenv environment variables file # dotenv environment variables file
.env .env
./src/api/firebase.js
firebase.js firebase.js

View File

@ -1,6 +1,20 @@
# Running Build & Deploying it to Firebase # Running Build & Deploying it to Firebase
`npm run build && firebase deploy` `npm run build && firebase deploy`
# Running Firebase Tests
`cd functions && npm run test`
# Running Locally
1. Ensure you have Java 11 or greater installed.
2. Run `npm install` in the traintracker directory.
3. Run `npm install` in the functions directory.
4. Start the emulator (needed to emulate the functions locally) `firebase emulators:start &` (the `&` forks it into the background).
5. Run `npm run dev`
You will need to click the "Populate Database" and "Fetch Data" buttons to get data into your local version of the webapp.
To kill the npm process do `CTRL + C` in your terminal.
To kill the firebase emulators run `fg` to bring the process to the foreground, then do `CTRL + C`
# Committing # Committing
Make sure that you exclude the Firebase API key from any commits! Make sure that you exclude the Firebase API key from any commits!

View File

@ -18,7 +18,7 @@ exports.getLiveTrainData = functions.https.onRequest((request, response) => {
// fetch the "liveTrainData" collection // fetch the "liveTrainData" collection
admin.firestore().collection('liveTrainData').get().then((snapshot) => { admin.firestore().collection('liveTrainData').get().then((snapshot) => {
if (snapshot.empty) { if (snapshot.empty) {
response.send({data: "Error fetching live train data from the database"}); response.status(404).send({data: "Error fetching live train data from the database"});
return; return;
} }
// iterate through each of the collection's documents // iterate through each of the collection's documents
@ -40,7 +40,7 @@ exports.getStationData = functions.https.onRequest((request, response) => {
// fetch the "stations" collection // fetch the "stations" collection
admin.firestore().collection('stations').get().then((snapshot) => { admin.firestore().collection('stations').get().then((snapshot) => {
if (snapshot.empty) { if (snapshot.empty) {
response.send({data: "Error fetching station data from the database"}) response.status(404).send({data: "Error fetching station data from the database"})
return; return;
} }
// iterate through each of the collection's documents // iterate through each of the collection's documents

View File

@ -1,4 +1,12 @@
<template> <template>
<h2>Insights:</h2>
<p>Total number of trains: {{ this.numTrains }}</p>
<p>Number of actively running trains: {{ this.numRunningTrains }}</p>
<p>Percentage late: {{ this.percentageLate }}%</p>
<p>Percentage early or ontime: {{ this.percentageEarly }}%</p>
<p v-if="this.latestTrain['TrainCode']">Latest train: {{ this.latestTrain["TrainCode"][0] }}, {{ this.latestTrain["Direction"][0] }}, {{ this.latestTime }} mins late</p>
<p v-if="this.earliestTrain['TrainCode']">Earliest train: {{ this.earliestTrain["TrainCode"][0] }}, {{ this.earliestTrain["Direction"][0] }}, {{ this.earliestTime * -1 }} mins early</p>
<button @click="getLiveTrainData">Fetch Data</button> <button @click="getLiveTrainData">Fetch Data</button>
<button @click="postLiveTrainData">Populate Database</button> <button @click="postLiveTrainData">Populate Database</button>
@ -69,19 +77,32 @@ export default {
strokeWidth, strokeWidth,
strokeColor, strokeColor,
fillColor, fillColor,
coordinates: [], coordinates: [],
dbLiveTrainData: [], dbLiveTrainData: [],
allDataMap: {}, allDataMap: {},
selectedDataMap: {}, selectedDataMap: {},
display: false, display: false,
numTrains: 0,
numRunningTrains: 0,
numLateRunningTrains: 0,
latestTrain: {},
earliestTrain: {},
percentageEarly: 0,
percentageLate: 0,
latestTime: 0,
earliestTime: 0,
} }
}, },
created() { created() {
// initial request of data if (window.location.hostname === '127.0.0.1' || window.location.hostname === 'localhost') {
console.log("jere") this.postLiveTrainData()
this.getLiveTrainData() }
else {
this.getLiveTrainData()
}
// request new data every 60 seconds // request new data every 60 seconds
// window.setInterval(this.getLiveTrainData, 60000); // window.setInterval(this.getLiveTrainData, 60000);
}, },
@ -90,8 +111,9 @@ export default {
// fetch live train data from the Firestore database // fetch live train data from the Firestore database
getLiveTrainData() { getLiveTrainData() {
const functions = getFunctions(app); const functions = getFunctions(app);
if (window.location.hostname === '127.0.0.1') { let host = window.location.hostname
connectFunctionsEmulator(functions, "localhost", 5001); if (host === '127.0.0.1' || host === 'localhost') {
connectFunctionsEmulator(functions, host, 5001);
} }
const getData = httpsCallable(functions, 'getLiveTrainData'); const getData = httpsCallable(functions, 'getLiveTrainData');
let loader = this.$loading.show({ let loader = this.$loading.show({
@ -103,11 +125,68 @@ export default {
getData().then((response) => { getData().then((response) => {
try { try {
this.dbLiveTrainData = response.data; this.dbLiveTrainData = response.data;
console.log(this.dbLiveTrainData)
this.numRunningTrains = 0;
this.numTrains = 0;
this.numLateRunningTrains = 0;
var latest = null
var currLatestTime = 0
var earliest = null
var currEarliestTime = 0
// create an array of coordinates and hashmap with the key-values {index: JSON obj} // create an array of coordinates and hashmap with the key-values {index: JSON obj}
for(var i=0; i<this.dbLiveTrainData.length; i++) { for(var i=0; i<this.dbLiveTrainData.length; i++) {
this.coordinates[i] = ref(fromLonLat([this.dbLiveTrainData[i]["TrainLongitude"][0], this.dbLiveTrainData[i]["TrainLatitude"][0]])) this.coordinates[i] = ref(fromLonLat([this.dbLiveTrainData[i]["TrainLongitude"][0], this.dbLiveTrainData[i]["TrainLatitude"][0]]))
this.allDataMap[i] = this.dbLiveTrainData[i]; this.allDataMap[i] = this.dbLiveTrainData[i];
// check if the train is running
if (this.dbLiveTrainData[i]["TrainStatus"][0] == "R") {
this.numRunningTrains += 1;
let publicMessage = this.dbLiveTrainData[i]["PublicMessage"][0];
let startTimeStr = publicMessage.indexOf("(")
// late
if (publicMessage[startTimeStr+1] != "-" && publicMessage[startTimeStr+1] != "0") {
this.numLateRunningTrains += 1;
if (!latest) {
latest = this.dbLiveTrainData[i];
}
let timeEnd = publicMessage.indexOf(" ", startTimeStr+1);
let num = parseInt(publicMessage.substring(startTimeStr+1, timeEnd))
// new latest train
if (num > currLatestTime) {
latest = this.dbLiveTrainData[i]
currLatestTime = num
}
}
// early or ontime
else {
if (!earliest) {
earliest = this.dbLiveTrainData[i];
}
let timeEnd = publicMessage.indexOf(" ", startTimeStr+1);
let num = parseInt(publicMessage.substring(startTimeStr+1, timeEnd))
// new earliest train, negative as early trains defined as negative x mins late
if (num < currEarliestTime) {
earliest = this.dbLiveTrainData[i]
currEarliestTime = num
}
}
}
} }
this.percentageLate = ((this.numLateRunningTrains / this.numRunningTrains) * 100).toFixed(2);
this.percentageEarly = 100 - this.percentageLate;
this.numTrains = Object.keys(this.allDataMap).length;
this.latestTrain = latest;
this.earliestTrain = earliest;
this.latestTime = currLatestTime;
this.earliestTime = currEarliestTime;
loader.hide(); loader.hide();
} }
catch (error) { catch (error) {
@ -131,13 +210,14 @@ export default {
// ---------------- TESTING ---------------- // ---------------- TESTING ----------------
postLiveTrainData() { postLiveTrainData() {
const functions = getFunctions(app); const functions = getFunctions(app);
if (window.location.hostname === '127.0.0.1') { let host = window.location.hostname
connectFunctionsEmulator(functions, "localhost", 5001); if (host === '127.0.0.1' || host === 'localhost') {
connectFunctionsEmulator(functions, host, 5001);
} }
const postData = httpsCallable(functions, 'postLiveTrainData'); const postData = httpsCallable(functions, 'postLiveTrainData');
postData().then((response) => { postData().then((response) => {
console.log("Test") this.getLiveTrainData()
}) })
} }
// ---------------- TESTING ---------------- // ---------------- TESTING ----------------