Welcome to the open-source repository of the Tomorrow app!👋
The Tomorrow app automatically calculates your carbon footprint by connecting to other services and apps in your life and translating activities from these apps and activities to greenhouse gas emissions.
The app is private-by-design: data will stay on device, unless the user explicitly gives consent. This code is maintained by Tomorrow.
Feel free to watch the presentation our Founder Olivier gave to the CopenhagenJS meetup, explaining what a JavaScript developer can do to combat climate change. If you have any questions, want early access to the app or just want to hang out with people fighting climate change with code, join our Slack community.
The company behind the Tomorrow app builds tech to empower organisations and individuals to understand and reduce their carbon footprint.
We're hiring great people to join our team in Copenhagen. Head over to our jobs page if you want to help out!
./co2eq
: carbon models./integrations
: contains all integrations./integrations/img
: contains all integration logos./playground
: source code of the playground./definitions.js
: constant definitions
You can help by:
- Helping us find, add and improve integrations with 3rd party services
- Helping us find, add and improve our Life Cycle Assesment / Carbon footprint data
- Giving us ideas, feedback and reporting bugs
We wrote a little article about what we believe makes a great integration. However, that shouldn't stop you from doing an integration which is interesting and useful to you! Our only requirement is that it can be quantified in greenhouse gas emissions.
Integrations can rely on an API or even on scrapers if necessary.
Here is the list of current 3rd party integrations: Official integrations:
✈️ Tripit (tracks most airlines!)- ⚡ Barry
- 🚗 Tesla Cockpit Community-supported integrations:
✈️ Ryanair (contributor:lauvrenn)✈️ Wizzair (contributor:lauvrenn)- 🚂 Rejsekort
- ⚡ Sense (contributor:snarfed)
- ⚡ Linky (contributor:bokub)
- ⚡ Ørsted (contributor:felixdq)
- 🚗 Renault Zoé
- 🚗 Uber (contributor:willtonkin)
- 🚗 Automatic (contributor:lauvrenn)
- 🚗 MinVolkswagen (contributor:folkev0gn)
You can suggest a new integration here.
If you don't have an idea on your own or prefer to debug an integration, you can find integration suggestions and bugs in the issues.
To make it easy for anyone to help out, a development playground is available:
First, run yarn
to install dependencies at the root of the repository.
Next from the playground
folder, run yarn
to install dependencies, then run yarn serve
to start the playground and point your browser to localhost:3000 to get started.
An integration gathers activities from a 3rd party datasource. To this end, 3 async methods need to be exported:
async function connect(requestLogin, requestWebView) {
const { username, password } = await requestLogin();
// ...
return newState;
}
async function collect(state = {}, logger) {
// ...
return { activities, state: newState };
}
async function disconnect() {
// ...
return newState;
}
The connect
method is used to ask for user credentials (OAuth flows are also supported).
The collect
method is called periodically (typically every few hours) to fetch new activities.
As the methods are pure, and to avoid re-asking the user for credentials everytime the collect
method is called, a state
object can be used to persist information (such as password, tokens..) across collect
s.
Activities require a certain formatting:
{
id, // a string that uniquely represents this activity
datetime, // a javascript Date object that represents the start of the activity
durationHours, // a floating point that represents the duration of the activity in decimal hours
distanceKilometers, // a floating point that represents the amount of kilometers traveled
activityType: ACTIVITY_TYPE_TRANSPORTATION,
transportationMode, // a variable (from definitions.js) that represents the transportation mode
carrier, // (optional) a string that represents the transportation company
departureAirportCode, // (for plane travel) a string that represents the departure airport, IATA code
destinationAirportCode, // (for plane travel) a string that represents the final destination airport, IATA code
departureStation, // (for other travel types) a string that represents the original starting point
destinationStation, // (for other travel types) a string that represents the final destination
}
{
id, // a string that uniquely represents this activity
datetime, // a javascript Date object that represents the start of the activity
durationHours, // a floating point that represents the duration of the activity in decimal hours
activityType: ACTIVITY_TYPE_LODGING,
hotelClass, // a variable (from definitions.js) that represents the class of the hotel
hotelName, // (optional) a string that represents the name of the hotel
locationLon, // (optional) the longitude of the location of the hotel
locationLat, // (optional) the latitude of the location of the hotel
}
{
id, // a string that uniquely represents this activity
datetime, // a javascript Date object that represents the start of the activity
durationHours, // an integer that represents the duration of the activity
activityType: ACTIVITY_TYPE_ELECTRICITY,
energyWattHours, // a float that represents the total energy used
hourlyEnergyWattHours, // (optional) an array of 24 floats that represent the hourly metering values
locationLon, // (optional) the longitude of the location of the hotel
locationLat, // (optional) the latitude of the location of the hotel
}
{
id, // a string that uniquely represents this activity
datetime, // a javascript Date object that represents the start of the activity
label, // a string that represents the transaction
merchantDisplayName, // (optional) a string that represents the merchant where the purchase was made
purchaseCategory, // a string that represents the category of the purchase. Categories can be found here: https://github.com/tmrowco/tmrowapp-contrib/blob/master/definitions.js
costAmount, // a floating point that represents the amount of the purchase
costCurrency, // a string that represents the currency in which the currency was made
bankDisplayName, // (required for integrations with banks) a string that represents the banks' name
bankIdentifier, // (required for integrations with banks) a string that uniquely represents the bank.
}
Our current models and Life Cycle assessments are accessible here. If you know better sources, please contribute with your knowledge.
If you want to add individual items or ingredients, this is done here. Ideally, the studies used should be as global as possible and it's even better if they're systemic reviews (multiple studies in one!).
Please add an issue here or directly in the app.