2020-05-25 22:05:14 2020-05-25 22:05:14 2020-05-25 22:05:14 789896
co2 tracker: some progress
I've been coding on my co2 emission tracker project for about a month now and there has been some (limited) progress, that my (limited) available time would allow.
First of all, I feel very positive about what level of insight and awareness the project could already give me despite the early stage it is in.
I've started by evaluating some web frameworks' facilities for quick prototyping and iterating. I looked at Spring boot, groovy on grails, and Django. I had worked with all of these before, not extensively though. I decided for Django in the end, as I knew it was pretty straight forward and quick to get a project started, so perfect for my purpose. Groovy on grails seems okay in that regard as well, but I am hesitant to use it in any of my projects, as I've heard negatively about it's lead developer and the project's community generally seems to have trouble with breaking core changes in releases and keeping up with adapting their plugins without which grails is pretty bare-stripped. Lastly, I also looked at Spring boot and while it seems good for sophisticated projects, it is also A MONSTER in complexity and it felt not well suited to quickly get a project up and running and iterating on it's code.
Then, I decided on some core use-cases I wanted the project to be able to handle and started fleshing out data structures to model these:
- Driving car $c$ with average speed $s$ km/h over a distance of $d$ km. Car $c$ having an engine that produces $e$ g co2/km
- eating $x$ kg of F, F being produced with $e$ kg co2e.
- using electrical device D for $h$ hours which uses $p$ kW. Having an electricity provider which produces $e$ g co2e / kWh
With these first use cases I started designing my Django app. However, I realized early that I didn't want to hardcode the available domains (e.g Car or Device), but that I wanted the user to be able to specify them via the UI. This prevented me from just defining all domains involved in my use cases as Django models. This would be the easiest solution by far, since I could then have leveraged the typing system of Django to describe properties of domains and such. But a tool where one needed to migrate changes to the database schema and restart the whole app each time the user wanted to add, delete or alter a domain, was a deal-breaker to me.
Hence, I came up with the following Django models, which would allow the user to define domains, actions, variables, values, events, all via the UI without needing to change the DB:
- An action describes one particular or a class of emission-producing real world actions a user can perform.
- actions have variables which allow them to describe multiple real world actions. For instance, the action “use electrical device (device😁evice)” can describe both when using the Device coffee machine, as well as the Device laptop.
- variables are typed, i.e. are assigned one particular domain
- an event takes an action and binds all its variables to values. This describes a user performing a specific real world action at a certain time, producing a computable amount of emissions.
- a value is a concrete object from a domain, which can be bound to a variable of that domain. In fact, several values of the same type can be bound to one variable (if the variable is defined as such).
- a value can have typed subvalues which can be interpreted as properties of the value itself. For instance, values of the domain Car must have a subvalue of domain Engine, which in turn must have a subvalue of domain Emission g/km.
- an action has an emission function that describes how an amount of emission (in g) can be calculated from values assigned to its variables. This emission function is evaluated for each event of that action.
Using the app – filling the models with flesh
I started using the app and filling the DB with domains, values, actions, variables, events, and some other supplementing types of models, that would describe the things I had been doing, eating, or using these days. That this turned out to be more tricky than expected and what sort of things I could learn from it nevertheless I'll describe in the next post (cliffhanger). Da da bum! :–)