Skip to content

Commit

Permalink
fix(helpers): Round Char Temp 'C' to 1 decimal place to match HK
Browse files Browse the repository at this point in the history
  • Loading branch information
grivkees committed Feb 4, 2023
1 parent 5980bd6 commit fc7b054
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 7 deletions.
80 changes: 80 additions & 0 deletions src/helpers.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import {
convertCharTemp2SystemTemp,
convertSystemTemp2CharTemp,
processSetpointDeadband,
range,
} from './helpers';

describe('convertCharTemp2SystemTemp', () => {
test('round C', () => {
expect(convertCharTemp2SystemTemp(0, 'C')).toEqual(0);
expect(convertCharTemp2SystemTemp(30, 'C')).toEqual(30);
expect(convertCharTemp2SystemTemp(30.1, 'C')).toEqual(30);
expect(convertCharTemp2SystemTemp(30.2, 'C')).toEqual(30);
Expand All @@ -14,14 +17,91 @@ describe('convertCharTemp2SystemTemp', () => {
});

test('round F', () => {
expect(convertCharTemp2SystemTemp(-18.3, 'F')).toEqual(-1);
expect(convertCharTemp2SystemTemp(-17.8, 'F')).toEqual(0);
expect(convertCharTemp2SystemTemp(-17.2, 'F')).toEqual(1);
expect(convertCharTemp2SystemTemp(-7.8, 'F')).toEqual(18);
expect(convertCharTemp2SystemTemp(0, 'F')).toEqual(32);
expect(convertCharTemp2SystemTemp(18, 'F')).toEqual(64);
expect(convertCharTemp2SystemTemp(30, 'F')).toEqual(86);
expect(convertCharTemp2SystemTemp(30.1, 'F')).toEqual(86);
expect(convertCharTemp2SystemTemp(30.4, 'F')).toEqual(87);
expect(convertCharTemp2SystemTemp(30.5, 'F')).toEqual(87);
expect(convertCharTemp2SystemTemp(30.6, 'F')).toEqual(87);
expect(convertCharTemp2SystemTemp(30.9, 'F')).toEqual(88);
});
});

describe('convertSystemTemp2CharTemp', () => {
test('round C', () => {
expect(convertSystemTemp2CharTemp(0, 'C')).toEqual(0);
expect(convertSystemTemp2CharTemp(30, 'C')).toEqual(30);
expect(convertSystemTemp2CharTemp(30.1, 'C')).toEqual(30.1);
expect(convertSystemTemp2CharTemp(30.2, 'C')).toEqual(30.2);
expect(convertSystemTemp2CharTemp(30.5, 'C')).toEqual(30.5);
expect(convertSystemTemp2CharTemp(30.6, 'C')).toEqual(30.6);
expect(convertSystemTemp2CharTemp(30.9, 'C')).toEqual(30.9);
});

test('round F', () => {
expect(convertSystemTemp2CharTemp(-1, 'F')).toEqual(-18.3);
expect(convertSystemTemp2CharTemp(0, 'F')).toEqual(-17.8);
expect(convertSystemTemp2CharTemp(1, 'F')).toEqual(-17.2);
expect(convertSystemTemp2CharTemp(18, 'F')).toEqual(-7.8);
expect(convertSystemTemp2CharTemp(19, 'F')).toEqual(-7.2);
expect(convertSystemTemp2CharTemp(20, 'F')).toEqual(-6.7);
expect(convertSystemTemp2CharTemp(21, 'F')).toEqual(-6.1);
expect(convertSystemTemp2CharTemp(22, 'F')).toEqual(-5.6);
expect(convertSystemTemp2CharTemp(30, 'F')).toEqual(-1.1);
expect(convertSystemTemp2CharTemp(31, 'F')).toEqual(-.6);
expect(convertSystemTemp2CharTemp(32, 'F')).toEqual(0);
expect(convertSystemTemp2CharTemp(33, 'F')).toEqual(.6);
expect(convertSystemTemp2CharTemp(64, 'F')).toEqual(17.8);
expect(convertSystemTemp2CharTemp(86, 'F')).toEqual(30);
expect(convertSystemTemp2CharTemp(87, 'F')).toEqual(30.6);
expect(convertSystemTemp2CharTemp(88, 'F')).toEqual(31.1);
expect(convertSystemTemp2CharTemp(89, 'F')).toEqual(31.7);
expect(convertSystemTemp2CharTemp(90, 'F')).toEqual(32.2);
});
});

describe('convertTemp_back_and_forth', () => {
test('round C', () => {
range(-10, 100).forEach(
x => {
expect(convertCharTemp2SystemTemp(convertSystemTemp2CharTemp(x, 'C'), 'C')).toEqual(x);
expect(convertSystemTemp2CharTemp(convertCharTemp2SystemTemp(x, 'C'), 'C')).toEqual(x);
},
);
});

test('round F', () => {
range(-10, 100).forEach(
x => {
// We lose fidelity going from HK -> Carrier -> HomeKit, since we store
// to nearest 1/10 degree in HK and 1/2 degree in carrier. And the rounding
// doesn't work out well because this tests puts in C values that don't
// map exactly to F.
// So to make this test work, we need to start with C values that approx
// F values. And if we want to check both directions that means just
// nesting both tests.
expect(
convertCharTemp2SystemTemp(
convertSystemTemp2CharTemp(
convertCharTemp2SystemTemp(
convertSystemTemp2CharTemp(x, 'F'),
'F',
),
'F',
),
'F',
),
).toEqual(x);
},
);
});
});

describe('processSetpointDeadband', () => {
test('cool above heat', () => {
expect(processSetpointDeadband(60, 70, 'F', true)).toEqual([60, 70]);
Expand Down
19 changes: 12 additions & 7 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,28 @@ import { FAN_MODE } from './api/constants';

export function convertSystemTemp2CharTemp(temp: number, units: string): CharacteristicValue {
if (units === 'F') {
return 5.0 / 9.0 * (temp - 32);
return Math.round(5.0 / 9.0 * (temp - 32) * 10) / 10;
} else {
return temp;
}
}

export function convertCharTemp2SystemTemp(temp: CharacteristicValue, units: string): number {
temp = Number(temp);
// HK keeps track in C, but carrier can be either C or F. Convert if needed.
if (units === 'F') {
// HK keeps track in C, but infinity can be either C or F. Convert to F if
// needed, then round to degree for infinity.
return Math.round((9.0 / 5.0 * temp) + 32);
// Round to integer degree for carrier.
const rounded = Math.round((9.0 / 5.0 * temp) + 32);
return Math.abs(rounded) < Number.EPSILON ? 0 : rounded; // get rid of -0
} else {
// Round C to half degree for infinity.
// Round C to half degree for carrier.
return Math.round(temp * 2) / 2;
}
}

export function areCharTempsClose(t1: CharacteristicValue | null, t2: CharacteristicValue | null): boolean {
if (t1 && t2) {
return Math.abs( Number(t1) - Number(t2) ) < .1;
return Math.abs( Number(t1) - Number(t2) ) < Number.EPSILON;
} else {
return false;
}
Expand Down Expand Up @@ -70,4 +71,8 @@ export function processSetpointDeadband(
}
}
return [htsp, clsp];
}
}

export function range(start: number, end: number): number[] {
return Array.from({length: (end - start) + 1}, (_, i) => start + i);
}

0 comments on commit fc7b054

Please sign in to comment.