Supporting multiple measurement units

Chalk sketch of two puzzles with words ingress and egress

I’m working on a freelance project in which I need to support multiple measurement units. In the App customers can provide their required flow rate in litres per second, litres per minute, litres per hour, cubic meters per hour, gallons a minute or imperial gallons per minute.

Warning: This gets really complicated, fast!

Imperial and Metric

You might have noticed we need to support imperial and metric measurement units. Well, that means we need to support mm, meters, degrees Celsius and the relevant inferior imperial versions some people still use. You know who you are.

Ingress and Egress

To keep business code simple, I have ingress object. These ingress objects take all the given values and convert them to a ‘known’ unit of measurement for each type. I then process all my calculations and do not need to be concerned with converting anything whilst I’m calculating. Once everything is calculated I pass everything into the egress objects, these convert all the data to the original unit and format.

Customer data is sacred

I store everything in the given format. I’ve tended to find over that it is better to store the original customer data and convert behind the scenes. Customers do not like it when their entered values of three gets returned as the 2.99997 the next time it appears on the screen.

I’m only a little way into the project but so far this is working well. Having a single interface to deal with is making my business code much simpler. I only need to care about the units for a value at the start and the end.

Hopefully, all goes well, only time will tell.

This project is the gift that keeps on giving, here is another post on integrating with Business Central.

Blog posts on freelance projects are deliberately a little vague as I can’t really divulge too much, I can talk about general stuff but obviously I’m never going to mention specifics.

Jobs and tasks gamble paid off

I have spent the last 12 months developing a product for one of my long-term clients, I’m going to refer to the product as EWAQO for the rest of this post.

I initially thought EWAQO would be three to four months of work, lockdowns, homeschooling, the pandemic in general and feature creep put paid to that.

EWAQO is far from the largest product I’ve worked on, I’ve been a professional developer for over twenty years and have worked at scale, it is however the largest product I’ve created single-handled. The Costs to Expect API, Website and App are big when combined, EWAQO is in a world of its own, it has so many different systems and is immense.

I decided early on to go deep with queues and scheduled tasks, I wanted to keep the App fast for the user and do as much of the heavy lifting as possible behind the scenes. Typically, I’m using queues for complex user-initiated tasks/actions and scheduled tasks are for processing.

It is easy to handle the complex stuff behind the scenes, but there is a problem, you need some visibility. Before I wrote the first job I created the interface, that way the client can see what is happening, is a job running? Did it fail? What was the output? Who initiated it? etc.

This was the masterstroke and made so much of the complexity possible, the client could see what is happening, job classes and tasks are simpler to create because you don’t need to worry about the front-end, it all came together brilliantly.

I’m not done with EWAQO, as of writing, there are 27 jobs and 26 scheduled tasks and I have visibility of each one, I can see when they are running, what is due, when and why they fail, it all just works.

We are working toward the soft-release of Costs to Expect this year, part of that is developing two smallish apps that act as companions. Both apps will borrow heavily from what I learned developing EWAQO.