Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update carbon calculations for GIS server (richer modes) #576

Merged
merged 28 commits into from
Jul 2, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
0ed9378
added connection config file with 0.0.0.0 instead of localhost, for d…
tms-martins May 13, 2019
f929f1b
updated trip modes and carbon data, refactored main carbon calculations
tms-martins May 27, 2019
3f79598
restored optimal and worst carbon footprint calculations
tms-martins Jun 3, 2019
315703b
a few corrections after first round of PR review, carbon calc for mod…
tms-martins Jun 11, 2019
68d66af
restored IN_VEHICLE to standardMETs
tms-martins Jun 11, 2019
d8e0a27
Add i18n for most of the app
DO3B Jun 17, 2019
a552c10
Fix issues and add consent files management
DO3B Jun 17, 2019
ff15d04
Fix #4
DO3B Jun 17, 2019
83d4a56
updatecheck i18n and minor fixes
DO3B Jun 18, 2019
29bfaf7
Add forgotten key
DO3B Jun 18, 2019
91d8d8b
Add i18n for modes and purposes
DO3B Jun 18, 2019
5b94703
Change loadAndPopulateOptions to use lang
DO3B Jun 19, 2019
f8db039
Change static formats by locale aware formats
DO3B Jun 19, 2019
07982ac
Change comment to match reality
shankari Jun 19, 2019
f03c1ff
Merge pull request #584 from fabmob/i18n-emission
shankari Jun 19, 2019
01c8f6c
added connection config file with 0.0.0.0 instead of localhost, for d…
tms-martins May 13, 2019
f0df6a0
updated trip modes and carbon data, refactored main carbon calculations
tms-martins May 27, 2019
546f083
restored optimal and worst carbon footprint calculations
tms-martins Jun 3, 2019
d9cd5e3
a few corrections after first round of PR review, carbon calc for mod…
tms-martins Jun 11, 2019
7b5aad0
restored IN_VEHICLE to standardMETs
tms-martins Jun 11, 2019
e3746e1
Always use WALKING instead of ON_FOOT; other small celan-ups
tms-martins Jun 24, 2019
dc929da
updated base (rebased on master after PR 584), added ON_FOOT to WALKI…
tms-martins Jun 24, 2019
3cc0597
Merge branch 'update_carbon_calc_for_GIS' of https://github.com/tms-m…
tms-martins Jun 24, 2019
a4737e2
Tidied up for PR/merge.
tms-martins Jul 1, 2019
30e661d
Restore the e-mission server to the CSP
shankari Jul 1, 2019
8220ddb
Fixed property names (missing quotes)
tms-martins Jul 1, 2019
fe2c575
Merge branch 'update_carbon_calc_for_GIS' of https://github.com/tms-m…
tms-martins Jul 1, 2019
c34dd15
Corrected/restored commented code
tms-martins Jul 1, 2019
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
4 changes: 3 additions & 1 deletion www/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com http://nominatim.openstreetmap.org https://e-mission.eecs.berkeley.edu https://api.ionic.io/push/tokens emission: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: http://*.tile.openstreetmap.org http://tile.stamen.com https://*.tile.stamen.com http://*.tile.stamen.com 'unsafe-inline'">
shankari marked this conversation as resolved.
Show resolved Hide resolved
<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com http://nominatim.openstreetmap.org http://192.168.1.238 https://api.ionic.io/push/tokens emission: 'unsafe-eval'; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' data: http://*.tile.openstreetmap.org http://tile.stamen.com https://*.tile.stamen.com http://*.tile.stamen.com 'unsafe-inline'">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also remove from PR :)

<title></title>

<link href="lib/ionic/css/ionic.css" rel="stylesheet">
Expand Down Expand Up @@ -106,6 +106,8 @@
<script src="lib/angular-nvd3/dist/angular-nvd3.min.js"></script>
<script src="lib/nz-tour/dist/nz-tour.min.js"></script>
<link rel="stylesheet" href="lib/nvd3/build/nv.d3.css">
<!-- TIAGO: allow debug with weinre -->
<script src="http://192.168.1.238:8090/target/target-script-min.js#anonymous"></script>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove? Seems to be hardcoded to your IP.

</head>

<body ng-app="emission">
Expand Down
92 changes: 67 additions & 25 deletions www/js/metrics-factory.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,61 @@ angular.module('emission.main.metrics.factory', ['emission.plugin.kvstore'])
.factory('FootprintHelper', function() {
var fh = {};
var footprint = {
train: 92/1609,
car: 287/1609,
ON_FOOT: 0,
BICYCLING: 0
}
var readable = function(v) {
return v > 9999? Math.round(v / 1000) + 'k kg CO₂' : Math.round(v) + ' kg CO₂';
ON_FOOT: 0,
BICYCLING: 0,
CAR: 267/1609,
BUS: 278/1609,
TRAIN: 92/1609,
AIR_OR_HSR: 217/1609
}
var mtokm = function(v) {
return v / 1000;
}
fh.getFootprintRaw = function(distance, mode) {
if (mode === "IN_VEHICLE") {
return [footprint.train * mtokm(distance), footprint.car * mtokm(distance)];
} else {
return footprint[mode] * mtokm(distance);

fh.readableFormat = function(v) {
tms-martins marked this conversation as resolved.
Show resolved Hide resolved
return v > 9999? Math.round(v / 1000) + 'k kg CO₂' : Math.round(v) + ' kg CO₂';
}
fh.getFootprintForMetrics = function(userMetrics) {
var result = 0;
tms-martins marked this conversation as resolved.
Show resolved Hide resolved
for (var i in userMetrics) {
var mode = userMetrics[i].key;
if (mode in footprint) {
result += footprint[mode] * mtokm(userMetrics[i].values);
}
else if (mode == "IN_VEHICLE") {
result += ((footprint[CAR] + footprint[BUS] + footprint[TRAIN]) / 3) * mtokm(userMetrics[i].values);
tms-martins marked this conversation as resolved.
Show resolved Hide resolved
}
else {
console.debug('WARNING: FootprintHelper.getFootprintFromMetrics() was requested for an unknown mode: ' + mode + " metrics JSON: " + JSON.stringify(userMetrics));
}
}
return result;
}
fh.getFootprint = function(distance, mode) {
if (mode === "IN_VEHICLE") {
return readable(footprint.train * mtokm(distance)) + ' ~ ' + readable(footprint.car * mtokm(distance));
} else {
return readable(footprint[mode] * mtokm(distance));
fh.getLowestFootprintForDistance = function(distance) {
var lowestFootprint = Number.MAX_VALUE;
for (var mode in footprint) {
if (mode == 'ON_FOOT' || mode == 'BICYCLING') {
// these modes aren't considered when determining the lowest carbon footprint
}
else {
lowestFootprint = Math.min(lowestFootprint, footprint[mode]);
tms-martins marked this conversation as resolved.
Show resolved Hide resolved
}
}
return lowestFootprint * mtokm(distance);
}
fh.getHighestFootprintForDistance = function(distance) {
var highestFootprint = 0;
for (var mode in footprint) {
highestFootprint = Math.max(highestFootprint, footprint[mode]);
shankari marked this conversation as resolved.
Show resolved Hide resolved
}
return highestFootprint * mtokm(distance);
}
return fh;
})

.factory('CalorieCal', function(KVStore){

var cc = {};
var cc = {};
var USER_DATA_KEY = "user-data";

cc.set = function(info) {
Expand All @@ -52,7 +76,7 @@ angular.module('emission.main.metrics.factory', ['emission.plugin.kvstore'])
};
cc.getMet = function(mode, speed) {
if (!standardMETs[mode]) {
console.log("Illegal mode");
console.log("CalorieCal.getMet() Illegal mode: " + mode);
return 0; //So the calorie sum does not break with wrong return type
}
for (var i in standardMETs[mode]) {
Expand Down Expand Up @@ -130,12 +154,6 @@ angular.module('emission.main.metrics.factory', ['emission.plugin.kvstore'])
mets: 9.8
}
},
"IN_VEHICLE": {
shankari marked this conversation as resolved.
Show resolved Hide resolved
"ALL": {
range: [0, Number.MAX_VALUE],
mets: 0
}
},
"BICYCLING": {
"VERY_VERY_SLOW": {
range: [0, 5.5],
Expand Down Expand Up @@ -165,6 +183,30 @@ angular.module('emission.main.metrics.factory', ['emission.plugin.kvstore'])
range: [20, Number.MAX_VALUE],
mets: 15.8
}
},
"CAR": {
"ALL": {
range: [0, Number.MAX_VALUE],
mets: 0
}
},
"BUS": {
"ALL": {
range: [0, Number.MAX_VALUE],
mets: 0
}
},
"TRAIN": {
"ALL": {
range: [0, Number.MAX_VALUE],
mets: 0
}
},
"AIR_OR_HSR": {
"ALL": {
range: [0, Number.MAX_VALUE],
mets: 0
}
}
}
return cc;
Expand Down
120 changes: 69 additions & 51 deletions www/js/metrics.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
var lastWeekCalories = 0;
var lastWeekCarbon = "0 kg CO₂";
var twoWeeksAgoCarbon = "";
var lastWeekCarbonInt = [];
var twoWeeksAgoCarbonInt = [];
var lastWeekCarbonInt = 0;
var twoWeeksAgoCarbonInt = 0;
var twoWeeksAgoCalories = 0;

var DURATION = "duration";
Expand All @@ -24,7 +24,7 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
$scope.onCurrentTrip = function() {
window.cordova.plugins.BEMDataCollection.getState().then(function(result) {
Logger.log("Current trip state" + JSON.stringify(result));
if(JSON.stringify(result) == "\"STATE_ONGOING_TRIP\""||
if(JSON.stringify(result) == "\"STATE_ONGOING_TRIP\""||
JSON.stringify(result) == "\"local.state.ongoing_trip\"") {
$state.go("root.main.current");
}
Expand Down Expand Up @@ -410,9 +410,13 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
delete clonedData.metric;
clonedData.metric_list = [DURATION, MEDIAN_SPEED, COUNT, DISTANCE];
clonedData.is_return_aggregate = true;
// TIAGO: change for PR
var getMetricsResult = $http.post(
"https://e-mission.eecs.berkeley.edu/result/metrics/timestamp",
"http://192.168.1.238:8080/result/metrics/timestamp",
clonedData)
// var getMetricsResult = $http.post(
// "https://e-mission.eecs.berkeley.edu/result/metrics/timestamp",
// clonedData)
return getMetricsResult;
}

Expand Down Expand Up @@ -443,7 +447,7 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
$scope.caloriesData.userCalories = 0;
$scope.caloriesData.aggrCalories = 0;
$scope.caloriesData.lastWeekUserCalories = 0;
$scope.caloriesData.changeInPercentage = "0%"
$scope.caloriesData.changeInPercentage = "0%";
$scope.caloriesData.change = " change";

$scope.carbonData.userCarbon = "0 kg CO₂";
Expand Down Expand Up @@ -522,7 +526,9 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
title: "Error loading aggregate data, averages not available",
template: JSON.stringify(error)
});
console.log(error);
console.debug("TIAGO: Error loading aggregate data:");
console.debug(JSON.stringify(error, null, 2));
//console.log(error);
});
};

Expand Down Expand Up @@ -574,6 +580,7 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
}

$scope.fillAggregateValues = function(agg_metrics_arr) {
console.debug("TIAGO: fillAggregateValues() agg_metrics_arr " + JSON.stringify(agg_metrics_arr, null, 2));
if (first) {
var aggDuration = agg_metrics_arr[0].slice(0, 7);
var aggMedianSpeed = agg_metrics_arr[1].slice(0, 7);
Expand Down Expand Up @@ -699,77 +706,83 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
$scope.fillFootprintCardUserVals = function(userDistance, twoWeeksAgoDistance) {
if (userDistance) {
var userCarbonData = getSummaryDataRaw(userDistance, 'distance');
console.debug('TIAGO: fillFootprintCardUserVals userDistance ' + JSON.stringify(userDistance, null, 2));
console.debug("TIAGO: fillFootprintCardUserVals userCarbonData (distances, from getSummaryDataRaw)" + JSON.stringify(userCarbonData, null, 2));

var optimalDistance = getOptimalFootprintDistance(userDistance);
var worstDistance = getWorstFootprintDistance(userDistance);
var worstDistance = getWorstFootprintDistance(userDistance);
var date1 = $scope.selectCtrl.fromDateTimestamp;
var date2 = $scope.selectCtrl.toDateTimestamp;
var duration = moment.duration(date2.diff(date1));
var days = duration.asDays();
//$scope.ca2020 = 43.771628 / 5 * days; // kg/day

$scope.carbonData.ca2035 = Math.round(40.142892 / 5 * days) + ' kg CO₂'; // kg/day
$scope.carbonData.ca2050 = Math.round(8.28565 / 5 * days) + ' kg CO₂';
//$scope.carbonData.userCarbon = [];
for (var i in userCarbonData) {
//$scope.carbonData.userCarbon.push({key: userCarbonData[i].key, values: FootprintHelper.getFootprint(userCarbonData[i].values, userCarbonData[i].key)});
if (userCarbonData[i].key === "IN_VEHICLE") {
$scope.carbonData.userCarbon = FootprintHelper.getFootprint(userCarbonData[i].values, userCarbonData[i].key);
$scope.carbonData.optimalCarbon = FootprintHelper.getFootprint(optimalDistance, userCarbonData[i].key);
$scope.carbonData.worstCarbon = FootprintHelper.getFootprint(worstDistance, userCarbonData[i].key);
lastWeekCarbonInt = FootprintHelper.getFootprintRaw(userCarbonData[i].values, userCarbonData[i].key);
}
}

$scope.carbonData.userCarbon = FootprintHelper.readableFormat(FootprintHelper.getFootprintForMetrics(userCarbonData));
shankari marked this conversation as resolved.
Show resolved Hide resolved
$scope.carbonData.optimalCarbon = FootprintHelper.readableFormat(FootprintHelper.getLowestFootprintForDistance(optimalDistance));
$scope.carbonData.worstCarbon = FootprintHelper.readableFormat(FootprintHelper.getHighestFootprintForDistance(worstDistance));
lastWeekCarbonInt = FootprintHelper.getFootprintForMetrics(userCarbonData);
}
else {
console.log("TIAGO: fillFootprintCardUserVals ERROR: can't fill most carbon values because userDistance is " + JSON.stringify(userDistance, null, 2));
}

if (first) {
if (twoWeeksAgoDistance) {
var userCarbonData = getSummaryDataRaw(twoWeeksAgoDistance, 'distance');
for (var i in userCarbonData) {
if (userCarbonData[i].key === "IN_VEHICLE") {
twoWeeksAgoCarbon = FootprintHelper.getFootprint(userCarbonData[i].values, userCarbonData[i].key);
twoWeeksAgoCarbonInt = FootprintHelper.getFootprintRaw(userCarbonData[i].values, userCarbonData[i].key);
if(first){
lastWeekCarbon = twoWeeksAgoCarbon;
}
$scope.carbonData.lastWeekUserCarbon = lastWeekCarbon;
}
}
var userCarbonDataTwoWeeks = getSummaryDataRaw(twoWeeksAgoDistance, 'distance');
twoWeeksAgoCarbon = 0;
twoWeeksAgoCarbonInt = 0;

twoWeeksAgoCarbonInt = FootprintHelper.getFootprintForMetrics(userCarbonDataTwoWeeks);

twoWeeksAgoCarbon = FootprintHelper.readableFormat(twoWeeksAgoCarbonInt);
lastWeekCarbon = twoWeeksAgoCarbon;
}
}
$scope.carbonData.lastWeekUserCarbon = lastWeekCarbon;

var change = "";
console.log("Running calculation with "
+ (lastWeekCarbonInt[0] + lastWeekCarbonInt[1])
+ " and "
+ (twoWeeksAgoCarbonInt[0] + twoWeeksAgoCarbonInt[1]))
var calculation = (((lastWeekCarbonInt[0] + lastWeekCarbonInt[1]) / 2)
/ ((twoWeeksAgoCarbonInt[0] + twoWeeksAgoCarbonInt[1]) / 2))
* 100 - 100;
console.log("Running calculation with " + lastWeekCarbonInt + " and " + twoWeeksAgoCarbonInt);
var calculation = (lastWeekCarbonInt/twoWeeksAgoCarbonInt) * 100 - 100;

// TODO: Refactor this so that we can filter out bad values ahead of time
// instead of having to work around it here
if (isValidNumber(calculation)) {
if(lastWeekCarbonInt[0] > twoWeeksAgoCarbonInt[0]){
$scope.carbonData.change = " increase over a week";
$scope.carbonUp = true;
$scope.carbonDown = false;
} else {
$scope.carbonData.change = " decrease over a week"
$scope.carbonUp = false;
$scope.carbonDown = true;
}
$scope.carbonData.changeInPercentage = Math.abs(Math.round(calculation)) + "%"
if(lastWeekCarbonInt > twoWeeksAgoCarbonInt){
$scope.carbonData.change = " increase over a week";
$scope.carbonUp = true;
$scope.carbonDown = false;
} else {
$scope.carbonData.change = " decrease over a week"
$scope.carbonUp = false;
$scope.carbonDown = true;
}
$scope.carbonData.changeInPercentage = Math.abs(Math.round(calculation)) + "%"
}
else {
console.debug("TIAGO: fillFootprintCardUserVals() WARNING: calculation for carbon change is not a valid number: " + calculation);
$scope.carbonData.change = " (no change)";
$scope.carbonData.changeInPercentage = '0%';
}
};

$scope.fillFootprintAggVals = function(aggDistance) {
if (aggDistance) {
var aggrCarbonData = getAvgSummaryDataRaw(aggDistance, 'distance');

// TIAGO: please remove before PR, and turn into an issue?
// It can happen that the mode "ON_FOOT" has a NaN value.
// This may be due to the fact that the aggregated values are requested
// from the main e-mission server and not from our own.
for (var i in aggrCarbonData) {
if (aggrCarbonData[i].key === "IN_VEHICLE") {
$scope.carbonData.aggrVehicleRange = FootprintHelper.getFootprintRaw(aggrCarbonData[i].values, aggrCarbonData[i].key);
$scope.carbonData.aggrCarbon = FootprintHelper.getFootprint(aggrCarbonData[i].values, aggrCarbonData[i].key);
if (isNaN(aggrCarbonData[i].values)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been investigated a bit more using the master phone branch and turned into an issue.
e-mission/e-mission-docs#422

console.debug("TIAGO: fillFootprintAggVals() WARNING: value is NaN for mode " + aggrCarbonData[i].key + ", changing to 0");
aggrCarbonData[i].values = 0;
}
}

$scope.carbonData.aggrCarbon = FootprintHelper.readableFormat(FootprintHelper.getFootprintForMetrics(aggrCarbonData));
}
};

Expand Down Expand Up @@ -854,6 +867,7 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
}
return rtn;
}

var getSummaryDataRaw = function(metrics, metric) {
var data = getDataFromMetrics(metrics);
for (var i = 0; i < data.length; i++) {
Expand All @@ -870,15 +884,19 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
}
return data;
}

/*var sortNumber = function(a,b) {
return a - b;
}*/

var getOptimalFootprintDistance = function(metrics){
console.debug("TIAGO: getOptimalFootprintDistance() metrics: " + JSON.stringify(metrics, null, 2));
var data = getDataFromMetrics(metrics);
var distance = 0;
var longTrip = 5000;
// total distance for long trips using motorized vehicles
for(var i = 0; i < data.length; i++) {
if(data[i].key == "IN_VEHICLE") {
if(data[i].key == "CAR" || data[i].key == "BUS" || data[i].key == "TRAIN" || data[i].key == "AIR_OR_HSR") {
for(var j = 0; j < data[i].values.length; j++){
if(data[i].values[j][1] >= longTrip){
distance += data[i].values[j][1];
Expand Down Expand Up @@ -1199,5 +1217,5 @@ angular.module('emission.main.metrics',['nvd3', 'emission.services', 'ionic-date
return ($scope.expandedc)? "expanded-calorie-card" : "small-calorie-card";
}


});
15 changes: 15 additions & 0 deletions www/json/connectionConfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"connectUrl": "http://192.168.1.238:8080",
tms-martins marked this conversation as resolved.
Show resolved Hide resolved
"android": {
"auth": {
"method": "prompted-auth",
"clientID": "ignored"
}
},
"ios": {
"auth": {
"method": "prompted-auth",
"clientID": "ignored"
}
}
}
Loading