Change API so it doesn't return unnecessary info
This commit is contained in:
+73
-32
@@ -2,32 +2,42 @@ function detectTemperatureShift(temperaturesOfCycle) {
|
|||||||
// sensiplan rounds temps to the nearest 0.05
|
// sensiplan rounds temps to the nearest 0.05
|
||||||
const tempValues = temperaturesOfCycle.map(val => rounded(val, 0.05))
|
const tempValues = temperaturesOfCycle.map(val => rounded(val, 0.05))
|
||||||
|
|
||||||
return tempValues.reduce((acc, curr) => {
|
function getLtl(i) {
|
||||||
// if we don't yet have 6 lower temps, we just collect
|
const sixTempsBefore = getSixTempsBefore(i)
|
||||||
// if no shift has been detected, we collect low temps
|
return Math.max(...sixTempsBefore)
|
||||||
// after the shift has been detected, we count them as part
|
|
||||||
// of the higher temperature phase
|
|
||||||
if (acc.low.length < 6) {
|
|
||||||
acc.low.push(curr)
|
|
||||||
acc.ltl = Math.max(...acc.low)
|
|
||||||
// TODO these are the same
|
|
||||||
} else if (curr <= acc.ltl && !acc.potentialHigh && !acc.shiftDetected) {
|
|
||||||
acc.low.push(curr)
|
|
||||||
acc.low.shift(curr)
|
|
||||||
acc.ltl = Math.max(...acc.low)
|
|
||||||
} else if (!acc.shiftDetected){
|
|
||||||
if (!acc.potentialHigh) acc.potentialHigh = []
|
|
||||||
acc.potentialHigh.push(curr)
|
|
||||||
checkRules(acc, curr)
|
|
||||||
} else {
|
|
||||||
acc.high.push(curr)
|
|
||||||
}
|
}
|
||||||
|
function getSixTempsBefore(i) {
|
||||||
|
return tempValues.slice(0, i).slice(-6)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempValues.reduce((acc, temp, i) => {
|
||||||
|
// need at least 6 low temps before we can detect a first high measurement
|
||||||
|
if (i < 6) return acc
|
||||||
|
|
||||||
|
// if we've already detected a shift, we put it with the other high level temps
|
||||||
|
if(acc.detected) {
|
||||||
|
acc.high.push(temp)
|
||||||
|
return acc
|
||||||
|
}
|
||||||
|
|
||||||
|
// is the temp a candidate for a first high measurement?
|
||||||
|
const ltl = getLtl(i)
|
||||||
|
if (temp <= ltl) return acc
|
||||||
|
|
||||||
|
const checkResult = checkIfFirstHighMeasurement(temp, i, tempValues, ltl)
|
||||||
|
// if we don't have a winner, keep going
|
||||||
|
if (!checkResult.isFirstHighMeasurement) return acc
|
||||||
|
|
||||||
|
// if we do, remember the details and start collecting the high level temps
|
||||||
|
acc.detected = true
|
||||||
|
acc.high = [temp]
|
||||||
|
acc.rules = checkResult.rules
|
||||||
|
acc.ltl = ltl
|
||||||
|
acc.low = getSixTempsBefore(i)
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
}, {
|
}, {
|
||||||
low: [],
|
detected: false
|
||||||
ltl: null,
|
|
||||||
shiftDetected: false
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,20 +46,51 @@ function rounded(val, step) {
|
|||||||
return Math.round(val * inverted) / inverted
|
return Math.round(val * inverted) / inverted
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkRules(acc, curr) {
|
function checkIfFirstHighMeasurement(temp, i, temps, ltl) {
|
||||||
function regularRuleApplies() {
|
// need at least 3 high temps to form a high temperature level
|
||||||
// we round the difference because of JS decimal weirdness
|
if (i > temps.length - 3) {
|
||||||
return acc.potentialHigh.length === 3 && rounded(curr - acc.ltl, 0.01) >= 0.2
|
return { isFirstHighMeasurement: false }
|
||||||
|
}
|
||||||
|
const nextTemps = temps.slice(i + 1, i + 4)
|
||||||
|
|
||||||
|
if (regularRuleApplies(temp, nextTemps, ltl)) {
|
||||||
|
return {
|
||||||
|
isFirstHighMeasurement: true,
|
||||||
|
rules: {
|
||||||
|
regular: true,
|
||||||
|
},
|
||||||
|
ltl
|
||||||
}
|
}
|
||||||
function firstExceptionRuleApplies() {
|
|
||||||
return acc.potentialHigh.length === 4 && curr > acc.ltl
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regularRuleApplies() || firstExceptionRuleApplies()) {
|
if (firstExceptionRuleApplies(temp, nextTemps, ltl)) {
|
||||||
acc.shiftDetected = true
|
return {
|
||||||
acc.high = acc.potentialHigh
|
isFirstHighMeasurement: true,
|
||||||
delete acc.potentialHigh
|
rules: {
|
||||||
|
firstException: true,
|
||||||
|
},
|
||||||
|
ltl
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
isFirstHighMeasurement: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function regularRuleApplies(temp, nextTemps, ltl) {
|
||||||
|
if (!nextTemps.every(temp => temp > ltl)) return false
|
||||||
|
const thirdTemp = nextTemps[1]
|
||||||
|
// we round the difference because of JS decimal weirdness
|
||||||
|
if (rounded(thirdTemp - ltl, 0.1) < 0.2) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
function firstExceptionRuleApplies(temp, nextTemps, ltl) {
|
||||||
|
if (!nextTemps.every(temp => temp > ltl)) return false
|
||||||
|
const fourthTemp = nextTemps[2]
|
||||||
|
if (fourthTemp > ltl) return true
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
|||||||
+11
-32
@@ -4,16 +4,12 @@ import { detectTemperatureShift } from '../lib/sensiplan'
|
|||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
describe.only('sensiplan', () => {
|
describe.only('sensiplan', () => {
|
||||||
describe('getTemperatureStatus', () => {
|
describe('detect temperature shift', () => {
|
||||||
describe('regular rule', () => {
|
describe('regular rule', () => {
|
||||||
it('reports lower temperature status before shift', function () {
|
it('reports lower temperature status before shift', function () {
|
||||||
const lowerTemps = [36.7, 36.57, 36.47, 36.49, 36.57]
|
const lowerTemps = [36.7, 36.57, 36.47, 36.49, 36.57]
|
||||||
const status = detectTemperatureShift(lowerTemps)
|
const status = detectTemperatureShift(lowerTemps)
|
||||||
expect(status).to.eql({
|
expect(status).to.eql({ detected: false })
|
||||||
low: [36.7, 36.55, 36.45, 36.5, 36.55],
|
|
||||||
ltl: 36.7,
|
|
||||||
shiftDetected: false,
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('detects temperature shift correctly', function () {
|
it('detects temperature shift correctly', function () {
|
||||||
@@ -23,41 +19,27 @@ describe.only('sensiplan', () => {
|
|||||||
low: [36.55, 36.45, 36.5, 36.55, 36.6, 36.55],
|
low: [36.55, 36.45, 36.5, 36.55, 36.6, 36.55],
|
||||||
ltl: 36.6,
|
ltl: 36.6,
|
||||||
high: [36.8, 36.85, 36.8],
|
high: [36.8, 36.85, 36.8],
|
||||||
shiftDetected: true
|
detected: true,
|
||||||
|
rules: { regular: true }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it('detects no temperature shift when there are no 6 low temps', function () {
|
it('detects no temperature shift when there are no 6 low temps', function () {
|
||||||
const tempShift = [36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.8]
|
const tempShift = [36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.8]
|
||||||
const status = detectTemperatureShift(tempShift)
|
const status = detectTemperatureShift(tempShift)
|
||||||
expect(status).to.eql({
|
expect(status).to.eql({ detected: false })
|
||||||
low: [36.45, 36.5, 36.55, 36.6, 36.55, 36.8],
|
|
||||||
ltl: 36.8,
|
|
||||||
potentialHigh: [36.85, 36.8],
|
|
||||||
shiftDetected: false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('detects no temperature shift if the shift is not high enough', function () {
|
it('detects no temperature shift if the shift is not high enough', function () {
|
||||||
const tempShift = [36.57, 36.7, 36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.8]
|
const tempShift = [36.57, 36.7, 36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.8]
|
||||||
const status = detectTemperatureShift(tempShift)
|
const status = detectTemperatureShift(tempShift)
|
||||||
expect(status).to.eql({
|
expect(status).to.eql({ detected: false })
|
||||||
low: [36.7, 36.45, 36.5, 36.55, 36.6, 36.55],
|
|
||||||
ltl: 36.7,
|
|
||||||
potentialHigh: [36.8, 36.85, 36.8],
|
|
||||||
shiftDetected: false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
|
|
||||||
it('detects missing temperature shift correctly', function () {
|
it('detects missing temperature shift correctly', function () {
|
||||||
const noTempShift = [36.7, 36.57, 36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.77]
|
const noTempShift = [36.7, 36.57, 36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.77]
|
||||||
const status = detectTemperatureShift(noTempShift)
|
const status = detectTemperatureShift(noTempShift)
|
||||||
expect(status).to.eql({
|
expect(status).to.eql({ detected: false })
|
||||||
low: [36.55, 36.45, 36.5, 36.55, 36.6, 36.55],
|
|
||||||
ltl: 36.6,
|
|
||||||
potentialHigh: [36.8, 36.85, 36.75],
|
|
||||||
shiftDetected: false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -69,18 +51,15 @@ describe.only('sensiplan', () => {
|
|||||||
low: [36.55, 36.45, 36.5, 36.55, 36.6, 36.55],
|
low: [36.55, 36.45, 36.5, 36.55, 36.6, 36.55],
|
||||||
ltl: 36.6,
|
ltl: 36.6,
|
||||||
high: [36.8, 36.85, 36.75, 36.65],
|
high: [36.8, 36.85, 36.75, 36.65],
|
||||||
shiftDetected: true
|
detected: true,
|
||||||
|
rules: { firstException: true }
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.skip('detects missing temperature shift correctly', function () {
|
it('detects missing temperature shift correctly', function () {
|
||||||
const firstExceptionNoShift = [36.7, 36.57, 36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.77, 36.57]
|
const firstExceptionNoShift = [36.7, 36.57, 36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.77, 36.57]
|
||||||
const status = detectTemperatureShift(firstExceptionNoShift)
|
const status = detectTemperatureShift(firstExceptionNoShift)
|
||||||
expect(status).to.eql({
|
expect(status).to.eql({ detected: false })
|
||||||
low: [36.7, 36.55, 36.45, 36.5, 36.55, 36.6, 36.55, 36.8, 36.85, 36.75, 36.55],
|
|
||||||
ltl: 36.85,
|
|
||||||
shiftDetected: false
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user