diff --git a/lib/sensiplan.js b/lib/sensiplan.js
index 94f7b4353f932a9b51e81f7295ee20e70c85198d..8a1e7cd3159e761dc49426f9360ad72968782d3c 100644
--- a/lib/sensiplan.js
+++ b/lib/sensiplan.js
@@ -2,32 +2,42 @@ function detectTemperatureShift(temperaturesOfCycle) {
   // sensiplan rounds temps to the nearest 0.05
   const tempValues = temperaturesOfCycle.map(val => rounded(val, 0.05))
 
-  return tempValues.reduce((acc, curr) => {
-    // if we don't yet have 6 lower temps, we just collect
-    // if no shift has been detected, we collect low temps
-    // 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 getLtl(i) {
+    const sixTempsBefore = getSixTempsBefore(i)
+    return Math.max(...sixTempsBefore)
+  }
+  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
   }, {
-    low: [],
-    ltl: null,
-    shiftDetected: false
+    detected: false
   })
 }
 
@@ -36,22 +46,53 @@ function rounded(val, step) {
   return Math.round(val * inverted) / inverted
 }
 
-function checkRules(acc, curr) {
-  function regularRuleApplies() {
-    // we round the difference because of JS decimal weirdness
-    return acc.potentialHigh.length === 3 && rounded(curr - acc.ltl, 0.01) >= 0.2
+function checkIfFirstHighMeasurement(temp, i, temps, ltl) {
+  // need at least 3 high temps to form a high temperature level
+  if (i > temps.length - 3) {
+    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 (firstExceptionRuleApplies(temp, nextTemps, ltl)) {
+    return {
+      isFirstHighMeasurement: true,
+      rules: {
+        firstException: true,
+      },
+      ltl
+    }
   }
 
-  if (regularRuleApplies() || firstExceptionRuleApplies()) {
-    acc.shiftDetected = true
-    acc.high = acc.potentialHigh
-    delete acc.potentialHigh
+  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 {
   detectTemperatureShift
 }
\ No newline at end of file
diff --git a/test/sensiplan.spec.js b/test/sensiplan.spec.js
index dd9b5836260e5cab923db588c6983ae811269d98..51945ed9bdf092a59f45312a5c4c7c2d0f64aaf0 100644
--- a/test/sensiplan.spec.js
+++ b/test/sensiplan.spec.js
@@ -4,16 +4,12 @@ import { detectTemperatureShift } from '../lib/sensiplan'
 const expect = chai.expect
 
 describe.only('sensiplan', () => {
-  describe('getTemperatureStatus', () => {
+  describe('detect temperature shift', () => {
     describe('regular rule', () => {
       it('reports lower temperature status before shift', function () {
         const lowerTemps = [36.7, 36.57, 36.47, 36.49, 36.57]
         const status = detectTemperatureShift(lowerTemps)
-        expect(status).to.eql({
-          low: [36.7, 36.55, 36.45, 36.5, 36.55],
-          ltl: 36.7,
-          shiftDetected: false,
-        })
+        expect(status).to.eql({ detected: false })
       })
 
       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],
           ltl: 36.6,
           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 () {
         const tempShift = [36.47, 36.49, 36.57, 36.62, 36.55, 36.8, 36.86, 36.8]
         const status = detectTemperatureShift(tempShift)
-        expect(status).to.eql({
-          low: [36.45, 36.5, 36.55, 36.6, 36.55, 36.8],
-          ltl: 36.8,
-          potentialHigh: [36.85, 36.8],
-          shiftDetected: false
-        })
+        expect(status).to.eql({ detected: false })
       })
 
       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 status = detectTemperatureShift(tempShift)
-        expect(status).to.eql({
-          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
-        })
+        expect(status).to.eql({ detected: false })
       })
 
       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 status = detectTemperatureShift(noTempShift)
-        expect(status).to.eql({
-          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
-        })
+        expect(status).to.eql({ detected: false })
       })
     })
 
@@ -69,18 +51,15 @@ describe.only('sensiplan', () => {
           low: [36.55, 36.45, 36.5, 36.55, 36.6, 36.55],
           ltl: 36.6,
           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 status = detectTemperatureShift(firstExceptionNoShift)
-        expect(status).to.eql({
-          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
-        })
+        expect(status).to.eql({ detected: false })
       })
     })
   })