CodeSOD: Heating Up
A common option for retrofitting heating and cooling into older homes is a mini-split, frequently tied to a heat pump. They're (relatively) cheap to install, energy efficient, and can be added without substantial modifications to the home. They also, annoyingly, are mostly controlled via IR remotes, making them challenging to wire up to home automation or even a household thermostat.
People have made solutions, and today's code comes from one of those solutions. Which, I want to stress, this code comes from an open source project for home automation, so it's not the code that's wrong, here. At first I thought it was, and had a moment of, "I'm not going to pick on some hobby project," but then I realised the hobby project points at a deeper issue.
// temperature helper these are direct mappings based on the remote float toFahrenheit(float fromCelsius) { // Lookup table for specific mappings const std::map<float, int> lookupTable = { {16.0, 61}, {16.5, 62}, {17.0, 63}, {17.5, 64}, {18.0, 65}, {18.5, 66}, {19.0, 67}, {20.0, 68}, {21.0, 69}, {21.5, 70}, {22.0, 71}, {22.5, 72}, {23.0, 73}, {23.5, 74}, {24.0, 75}, {24.5, 76}, {25.0, 77}, {25.5, 78}, {26.0, 79}, {26.5, 80}, {27.0, 81}, {27.5, 82}, {28.0, 83}, {28.5, 84}, {29.0, 85}, {29.5, 86}, {30.0, 87}, {30.5, 88} }; // Check if the input is in the lookup table auto it = lookupTable.find(fromCelsius); if (it != lookupTable.end()) { return it->second; } // Default conversion and rounding to nearest integer return roundf(fromCelsius * 1.8 + 32.0); }Okay, I am going to pick on their code a little bit; using float as a key in a map is asking for trouble, because rounding errors are going to surprise you. But honestly, failing to find the key you're looking for is better than the opposite, since that actually does the correct thing. Because if you look carefully at the table, you'll see that it's wrong.
18C, for example, should be 64F. Well, 64.4F, but we're rounding to an integer. The choice here is to roughly map every 0.5C increase to a 1F increase, which is not the conversion factor. They try and correct- note how the table mostly steps by 0.5C, but skips 19.5C.
The opposite direction is similarly bad:
// temperature helper these are direct mappings based on the remote float toCelsius(float fromFahrenheit) { // Lookup table for specific mappings const std::map<int, float> lookupTable = { {61, 16.0}, {62, 16.5}, {63, 17.0}, {64, 17.5}, {65, 18.0}, {66, 18.5}, {67, 19.0}, {68, 20.0}, {69, 21.0}, {70, 21.5}, {71, 22.0}, {72, 22.5}, {73, 23.0}, {74, 23.5}, {75, 24.0}, {76, 24.5}, {77, 25.0}, {78, 25.5}, {79, 26.0}, {80, 26.5}, {81, 27.0}, {82, 27.5}, {83, 28.0}, {84, 28.5}, {85, 29.0}, {86, 29.5}, {87, 30.0}, {88, 30.5} }; // Check if the input is in the lookup table auto it = lookupTable.find(static_cast<int>(fromFahrenheit)); if (it != lookupTable.end()) { return it->second; } // Default conversion and rounding to nearest 0.5 return roundf((fromFahrenheit - 32.0) / 1.8 * 2) / 2.0; }Here, we can be off by as much as a 1C, which is certainly a noticeable feeling.
At first glance, I thought this was just a misguided attempt at optimizing the lookup. For common values, do a lookup instead of calculating because it's faster. Seems like the kind of mistake a hobby project might make, and definitely not a WTF. But it's the comment which corrects me: these are direct mappings based on the remote.
These remotes usually have a display. So when you see on the remote that you're trying to set the temperature to a comfortable 72F, the remote is actually sending 22.5C to the unit. That's the actual temperature being sent.
Now, why on Earth does the remote behave this way? Well, I haven't cracked one open to read off the part numbers, but I'm going to go out on a limb and guess that the microcontoller in the remote doesn't handle floating point operations all that well. So it almost certainly does use a lookup table to decide what signal to send, and the lookup table is populated by "good enough" approximations of temperature conversions. There aren't a lot of places that use Fahrenheit, so being "close enough" is a reasonable solution. If you want accurate temperatures, use SI units, not "freedom units".
In the end, I'd say that neither the hobby project, nor the remote control are the WTF here; locales that insist on using weird ass units are.
.comment { border: none }Tim Curry's cause of death revealed days after the Rocky Horror Picture Show star's passing at 80
Think pencil skirts are dated? The controversial style is back for autumn - here's how to wear it
They look cheesed off! Moment mice spar in front of commuters waiting for the Tube
Stacey Solomon and Joe Swash announce major news about their future
Stacey Solomon and Joe Swash announce major news about their future
A12 to shut one way between Chelmsford and Colchester for roadworks with 22-mile diversion in place
Naomi Watts' nepo baby Kai Schreiber, 17, goes full model mode for new fashion campaign with actress mom
I put my increased bowel movements down to my active lifestyle and healthy diet. Doctors told me it was IBS... then I developed excruciating backache
Do YOU know what creates 65% of the value of a typical pension pot at retirement?
We were flying home to Edinburgh with Loganair but it abandoned us... in Birmingham: CRANE ON THE CASE
Brentwood village 'at breaking point' with 'severe gridlock' with new homes planned
Heartbroken, I sent my checklist for a dream husband out into the Universe. Within weeks I'd met him. It may sound like woo woo - but every woman looking for love needs to follow THIS spell
RICHARD EDEN: Night Oasis Noel gave The Sun's editor a slap
Plans to showcase 'incredibly special' underground Roman mosaic still on, team says
Plans to showcase 'incredibly special' underground Roman mosaic still on, team says
Oasis set to announce huge second tour in just days after Liam and Noel Gallagher proved their bitter feud is finally over
NFL rocked by tragedy as former star dies by suicide at 40... shortly after troubling final social media post
Global Heating Will Hit At Least 1.8C, UN Warns, and There Are 'No Good Outcomes'
Read more of this story at Slashdot.