{"abstract":"The furnace starts as soon as the room dips below setpoint and short-cycles around it.","category":"HVAC thermostat control","checks":8,"contract":"Auto heat/cool thermostat sampled once per minute (temps in tenths F). If the cooling setpoint is less than 3.0 F above the heating setpoint it is pushed up to heat_sp + 30 (the heating setpoint wins). Heating starts below heat_sp - 1.0 F and ends at temp >= heat_sp; cooling starts above cool_sp + 1.0 F and ends at temp <= cool_sp. After a heating call ends, cooling may not start until 5 minutes later, and vice versa. Return heat, cool or idle per minute.","evaluation_group":"w2-hvac-thermostat-control-auto-changeover-deadband","failed_approach":"Using half the differential still starts heating too early.","family":"w2-hvac-thermostat-control-auto-changeover-deadband-heat-start-differential","id":"FA-92346","implementations":{"attempt":{"sha256":"5275c7da69c905bf71aeac0133124a4db95a59d626a99654a0031b216d749c04","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(heat_sp, cool_sp, temps):\n    diff = 10\n    if cool_sp - heat_sp < 30:\n        cool_sp = heat_sp + 30\n    state = 'idle'\n    last_heat_end = None\n    last_cool_end = None\n    out = []\n    for minute, temp in enumerate(temps):\n        if state == 'heat' and temp >= heat_sp:\n            state = 'idle'\n            last_heat_end = minute\n        elif state == 'cool' and temp <= cool_sp:\n            state = 'idle'\n            last_cool_end = minute\n        if state == 'idle':\n            if temp < heat_sp - diff // 2 and (last_cool_end is None or minute - last_cool_end >= 5):\n                state = 'heat'\n            elif temp > cool_sp + diff and (last_heat_end is None or minute - last_heat_end >= 5):\n                state = 'cool'\n        out.append(state)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['regression: scenario 6',\n   [680,\n    720,\n    [666, 650, 675, 664, 671, 693, 693, 695, 674, 675, 657, 635, 629, 632, 629, 632, 636, 632, 620]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['regression: scenario 1',\n   [680, 690, [693, 687, 709, 709, 685, 704, 684, 680, 686, 687, 679]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: scenario 2',\n   [680, 700, [681, 686, 698, 703, 724, 744, 752, 732, 755, 742, 762, 772]],\n   ['idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool']],\n  ['control: scenario 3',\n   [680,\n    740,\n    [649,\n     667,\n     643,\n     622,\n     637,\n     657,\n     634,\n     649,\n     674,\n     654,\n     672,\n     675,\n     698,\n     687,\n     666,\n     654,\n     670,\n     645,\n     654,\n     637,\n     651,\n     672]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']]],\n [['regression: scenario 2',\n   [680, 710, [674, 681, 688, 699, 718, 698, 716, 709, 691, 672, 678, 701, 724, 699, 683, 698, 691, 701]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle']],\n  ['regression: scenario 9',\n   [680, 720, [674, 698, 687, 683, 659, 647, 658, 656, 658, 674, 664, 656, 672, 650]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 700, [687, 695, 710, 721, 712, 724, 736, 738, 737, 740, 748]],\n   ['idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool']],\n  ['regression: scenario 3',\n   [680, 690, [686, 679, 704, 696, 678, 658, 635, 648, 643, 657, 650, 661, 672, 691, 687, 685, 708, 687]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle']]],\n [['regression: scenario 5',\n   [680, 740, [676, 673, 693, 690, 714, 709, 715, 740, 727, 735, 738, 752, 754, 729, 752, 746]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'idle',\n    'cool',\n    'cool']],\n  ['regression: scenario 16',\n   [680, 740, [684, 671, 648, 650, 634, 633, 624, 643, 667, 647, 630, 639]],\n   ['idle', 'idle', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 710, [758, 778, 769, 788, 780, 787, 790, 773, 789, 766, 785, 779, 790, 790, 790, 777, 790]],\n   ['cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']],\n  ['control: scenario 2',\n   [680, 740, [646, 654, 672, 672, 692, 717, 736, 759, 769, 790, 790]],\n   ['heat', 'heat', 'heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']]],\n [['regression: scenario 11',\n   [680, 690, [661, 683, 677, 656, 633, 621, 620, 620, 620, 629, 635, 658, 682, 657, 659, 665]],\n   ['heat',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'heat',\n    'heat',\n    'heat']],\n  ['regression: scenario 12',\n   [680, 710, [710, 715, 700, 681, 698, 674, 698, 701, 681, 675, 664]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['regression: scenario 1',\n   [680,\n    690,\n    [671, 646, 636, 635, 620, 625, 635, 653, 659, 636, 645, 633, 620, 628, 620, 638, 653, 655, 666, 678]],\n   ['idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: scenario 2',\n   [680, 740, [655, 638, 663, 641, 622, 636, 628, 621, 621, 620, 635, 632, 644, 651, 656, 675, 687]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle']]],\n [['regression: scenario 9',\n   [680, 690, [673, 694, 686, 686, 699, 720, 727, 736, 726, 719]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool']],\n  ['regression: scenario 34',\n   [680,\n    700,\n    [735,\n     716,\n     727,\n     705,\n     684,\n     664,\n     652,\n     673,\n     670,\n     688,\n     692,\n     705,\n     701,\n     720,\n     743,\n     746,\n     741,\n     746,\n     763,\n     788,\n     790]],\n   ['cool',\n    'cool',\n    'cool',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 720, [774, 779, 785, 790, 790, 781, 778, 777, 770, 767, 743, 730, 708, 690]],\n   ['cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'idle',\n    'idle']],\n  ['regression: scenario 2',\n   [680,\n    710,\n    [701,\n     679,\n     702,\n     721,\n     727,\n     748,\n     743,\n     720,\n     741,\n     738,\n     762,\n     769,\n     758,\n     740,\n     744,\n     725,\n     748,\n     728,\n     742,\n     755,\n     769]],\n   ['idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"broken":{"sha256":"67846e5521136de4612e54048da95f303d53336c69c283a3be919c6e88668746","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(heat_sp, cool_sp, temps):\n    diff = 10\n    if cool_sp - heat_sp < 30:\n        cool_sp = heat_sp + 30\n    state = 'idle'\n    last_heat_end = None\n    last_cool_end = None\n    out = []\n    for minute, temp in enumerate(temps):\n        if state == 'heat' and temp >= heat_sp:\n            state = 'idle'\n            last_heat_end = minute\n        elif state == 'cool' and temp <= cool_sp:\n            state = 'idle'\n            last_cool_end = minute\n        if state == 'idle':\n            if temp < heat_sp and (last_cool_end is None or minute - last_cool_end >= 5):\n                state = 'heat'\n            elif temp > cool_sp + diff and (last_heat_end is None or minute - last_heat_end >= 5):\n                state = 'cool'\n        out.append(state)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['regression: scenario 6',\n   [680,\n    720,\n    [666, 650, 675, 664, 671, 693, 693, 695, 674, 675, 657, 635, 629, 632, 629, 632, 636, 632, 620]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['regression: scenario 1',\n   [680, 690, [693, 687, 709, 709, 685, 704, 684, 680, 686, 687, 679]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: scenario 2',\n   [680, 700, [681, 686, 698, 703, 724, 744, 752, 732, 755, 742, 762, 772]],\n   ['idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool']],\n  ['control: scenario 3',\n   [680,\n    740,\n    [649,\n     667,\n     643,\n     622,\n     637,\n     657,\n     634,\n     649,\n     674,\n     654,\n     672,\n     675,\n     698,\n     687,\n     666,\n     654,\n     670,\n     645,\n     654,\n     637,\n     651,\n     672]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']]],\n [['regression: scenario 2',\n   [680, 710, [674, 681, 688, 699, 718, 698, 716, 709, 691, 672, 678, 701, 724, 699, 683, 698, 691, 701]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle']],\n  ['regression: scenario 9',\n   [680, 720, [674, 698, 687, 683, 659, 647, 658, 656, 658, 674, 664, 656, 672, 650]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 700, [687, 695, 710, 721, 712, 724, 736, 738, 737, 740, 748]],\n   ['idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool']],\n  ['regression: scenario 3',\n   [680, 690, [686, 679, 704, 696, 678, 658, 635, 648, 643, 657, 650, 661, 672, 691, 687, 685, 708, 687]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle']]],\n [['regression: scenario 5',\n   [680, 740, [676, 673, 693, 690, 714, 709, 715, 740, 727, 735, 738, 752, 754, 729, 752, 746]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'idle',\n    'cool',\n    'cool']],\n  ['regression: scenario 16',\n   [680, 740, [684, 671, 648, 650, 634, 633, 624, 643, 667, 647, 630, 639]],\n   ['idle', 'idle', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 710, [758, 778, 769, 788, 780, 787, 790, 773, 789, 766, 785, 779, 790, 790, 790, 777, 790]],\n   ['cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']],\n  ['control: scenario 2',\n   [680, 740, [646, 654, 672, 672, 692, 717, 736, 759, 769, 790, 790]],\n   ['heat', 'heat', 'heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']]],\n [['regression: scenario 11',\n   [680, 690, [661, 683, 677, 656, 633, 621, 620, 620, 620, 629, 635, 658, 682, 657, 659, 665]],\n   ['heat',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'heat',\n    'heat',\n    'heat']],\n  ['regression: scenario 12',\n   [680, 710, [710, 715, 700, 681, 698, 674, 698, 701, 681, 675, 664]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['regression: scenario 1',\n   [680,\n    690,\n    [671, 646, 636, 635, 620, 625, 635, 653, 659, 636, 645, 633, 620, 628, 620, 638, 653, 655, 666, 678]],\n   ['idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: scenario 2',\n   [680, 740, [655, 638, 663, 641, 622, 636, 628, 621, 621, 620, 635, 632, 644, 651, 656, 675, 687]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle']]],\n [['regression: scenario 9',\n   [680, 690, [673, 694, 686, 686, 699, 720, 727, 736, 726, 719]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool']],\n  ['regression: scenario 34',\n   [680,\n    700,\n    [735,\n     716,\n     727,\n     705,\n     684,\n     664,\n     652,\n     673,\n     670,\n     688,\n     692,\n     705,\n     701,\n     720,\n     743,\n     746,\n     741,\n     746,\n     763,\n     788,\n     790]],\n   ['cool',\n    'cool',\n    'cool',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 720, [774, 779, 785, 790, 790, 781, 778, 777, 770, 767, 743, 730, 708, 690]],\n   ['cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'idle',\n    'idle']],\n  ['regression: scenario 2',\n   [680,\n    710,\n    [701,\n     679,\n     702,\n     721,\n     727,\n     748,\n     743,\n     720,\n     741,\n     738,\n     762,\n     769,\n     758,\n     740,\n     744,\n     725,\n     748,\n     728,\n     742,\n     755,\n     769]],\n   ['idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"},"fixed":{"sha256":"916988fe422badcccd9cb0b4165300b97a2bbfd44ba59ce78b6368411e980a64","source":"\"\"\"Failure Map reference implementation. Python standard library only.\"\"\"\nimport json\n\nN = 1\nobservations = []\ndef solve(heat_sp, cool_sp, temps):\n    diff = 10\n    if cool_sp - heat_sp < 30:\n        cool_sp = heat_sp + 30\n    state = 'idle'\n    last_heat_end = None\n    last_cool_end = None\n    out = []\n    for minute, temp in enumerate(temps):\n        if state == 'heat' and temp >= heat_sp:\n            state = 'idle'\n            last_heat_end = minute\n        elif state == 'cool' and temp <= cool_sp:\n            state = 'idle'\n            last_cool_end = minute\n        if state == 'idle':\n            if temp < heat_sp - diff and (last_cool_end is None or minute - last_cool_end >= 5):\n                state = 'heat'\n            elif temp > cool_sp + diff and (last_heat_end is None or minute - last_heat_end >= 5):\n                state = 'cool'\n        out.append(state)\n    return out\ndef check(label, actual, expected):\n    observations.append({\"check\": label, \"actual\": actual, \"expected\": expected, \"passed\": actual == expected})\nfixtures = [[['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['regression: scenario 6',\n   [680,\n    720,\n    [666, 650, 675, 664, 671, 693, 693, 695, 674, 675, 657, 635, 629, 632, 629, 632, 636, 632, 620]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['regression: scenario 1',\n   [680, 690, [693, 687, 709, 709, 685, 704, 684, 680, 686, 687, 679]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: scenario 2',\n   [680, 700, [681, 686, 698, 703, 724, 744, 752, 732, 755, 742, 762, 772]],\n   ['idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool']],\n  ['control: scenario 3',\n   [680,\n    740,\n    [649,\n     667,\n     643,\n     622,\n     637,\n     657,\n     634,\n     649,\n     674,\n     654,\n     672,\n     675,\n     698,\n     687,\n     666,\n     654,\n     670,\n     645,\n     654,\n     637,\n     651,\n     672]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']]],\n [['regression: scenario 2',\n   [680, 710, [674, 681, 688, 699, 718, 698, 716, 709, 691, 672, 678, 701, 724, 699, 683, 698, 691, 701]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle']],\n  ['regression: scenario 9',\n   [680, 720, [674, 698, 687, 683, 659, 647, 658, 656, 658, 674, 664, 656, 672, 650]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 700, [687, 695, 710, 721, 712, 724, 736, 738, 737, 740, 748]],\n   ['idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool', 'cool']],\n  ['regression: scenario 3',\n   [680, 690, [686, 679, 704, 696, 678, 658, 635, 648, 643, 657, 650, 661, 672, 691, 687, 685, 708, 687]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle']]],\n [['regression: scenario 5',\n   [680, 740, [676, 673, 693, 690, 714, 709, 715, 740, 727, 735, 738, 752, 754, 729, 752, 746]],\n   ['idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'idle',\n    'cool',\n    'cool']],\n  ['regression: scenario 16',\n   [680, 740, [684, 671, 648, 650, 634, 633, 624, 643, 667, 647, 630, 639]],\n   ['idle', 'idle', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat', 'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 710, [758, 778, 769, 788, 780, 787, 790, 773, 789, 766, 785, 779, 790, 790, 790, 777, 790]],\n   ['cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']],\n  ['control: scenario 2',\n   [680, 740, [646, 654, 672, 672, 692, 717, 736, 759, 769, 790, 790]],\n   ['heat', 'heat', 'heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']]],\n [['regression: scenario 11',\n   [680, 690, [661, 683, 677, 656, 633, 621, 620, 620, 620, 629, 635, 658, 682, 657, 659, 665]],\n   ['heat',\n    'idle',\n    'idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle',\n    'heat',\n    'heat',\n    'heat']],\n  ['regression: scenario 12',\n   [680, 710, [710, 715, 700, 681, 698, 674, 698, 701, 681, 675, 664]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'heat']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['regression: scenario 1',\n   [680,\n    690,\n    [671, 646, 636, 635, 620, 625, 635, 653, 659, 636, 645, 633, 620, 628, 620, 638, 653, 655, 666, 678]],\n   ['idle',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat']],\n  ['control: scenario 2',\n   [680, 740, [655, 638, 663, 641, 622, 636, 628, 621, 621, 620, 635, 632, 644, 651, 656, 675, 687]],\n   ['heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'heat',\n    'idle']]],\n [['regression: scenario 9',\n   [680, 690, [673, 694, 686, 686, 699, 720, 727, 736, 726, 719]],\n   ['idle', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'cool', 'cool']],\n  ['regression: scenario 34',\n   [680,\n    700,\n    [735,\n     716,\n     727,\n     705,\n     684,\n     664,\n     652,\n     673,\n     670,\n     688,\n     692,\n     705,\n     701,\n     720,\n     743,\n     746,\n     741,\n     746,\n     763,\n     788,\n     790]],\n   ['cool',\n    'cool',\n    'cool',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']],\n  ['control: heat then locked cool',\n   [680, 700, [650, 660, 690, 700, 712, 725, 725, 725, 715, 710]],\n   ['heat', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool', 'idle']],\n  ['regression: exact thresholds',\n   [680, 720, [670, 669, 680, 731, 730, 720, 721]],\n   ['idle', 'heat', 'idle', 'idle', 'idle', 'idle', 'idle']],\n  ['control: short heat cycle then hot',\n   [680, 760, [660, 685, 790, 790, 790, 790, 790, 790]],\n   ['heat', 'idle', 'idle', 'idle', 'idle', 'idle', 'cool', 'cool']],\n  ['control: deadband squeeze',\n   [700, 705, [740, 741, 735, 730, 729]],\n   ['idle', 'cool', 'cool', 'idle', 'idle']],\n  ['control: scenario 1',\n   [680, 720, [774, 779, 785, 790, 790, 781, 778, 777, 770, 767, 743, 730, 708, 690]],\n   ['cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'idle',\n    'idle']],\n  ['regression: scenario 2',\n   [680,\n    710,\n    [701,\n     679,\n     702,\n     721,\n     727,\n     748,\n     743,\n     720,\n     741,\n     738,\n     762,\n     769,\n     758,\n     740,\n     744,\n     725,\n     748,\n     728,\n     742,\n     755,\n     769]],\n   ['idle',\n    'idle',\n    'idle',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool',\n    'cool']]]]\nfor label, args, expected in fixtures[N-1]:\n    check(label, solve(*args), expected)\nprint(json.dumps({\"observations\": observations, \"passed\": all(x[\"passed\"] for x in observations)}, ensure_ascii=False))\nraise SystemExit(0 if all(x[\"passed\"] for x in observations) else 1)\n"}},"limitations":"A deterministic bounded teaching model of one thermostat or HVAC controller decision evaluated per sample. Temperatures are integer tenths of a degree Fahrenheit unless stated otherwise. The contract is a stipulated toy convention, not a claim of conformance to any manufacturer, ASHRAE guideline or code. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.","method":"Deterministic executable model with adversarial boundary fixtures.","provenance":{"created_by":"Failure Map","dependencies":"Python standard library","family":"w2-hvac-thermostat-control-auto-changeover-deadband-heat-start-differential","generated_at":"2026-09-29T14:51:44.945803+00:00","license":"CC0-1.0","python":"3.12.14","seed":1,"split":"open-access"},"relevance":"Residential and light-commercial thermostats make these decisions sample by sample; each defect changes equipment calls in a way that shows up as short cycling, comfort complaints or equipment stress.","repair":"Start heating only below heat_sp - 1.0 F.","root_cause":"The heat start test compares against heat_sp instead of heat_sp minus the differential.","sha256":"c73db85caca40c9f8d49b0cad1af079eeeee165783c209a24624a7cf50e5b916","title":"Heating call starts without its differential · case 01","variant":1,"variant_policy":"Five numbered records share a model and may reuse boundary fixtures.","verification":{"attempt":{"elapsed_ms":42.845,"exit_code":1,"observations":[{"actual":["heat","heat","idle","idle","idle","idle","idle"],"check":"regression: exact thresholds","expected":["idle","heat","idle","idle","idle","idle","idle"],"passed":false},{"actual":["heat","heat","heat","heat","heat","idle","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat"],"check":"regression: scenario 6","expected":["heat","heat","heat","heat","heat","idle","idle","idle","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat","heat"],"passed":false},{"actual":["heat","heat","idle","idle","idle","idle","idle","cool","cool","idle"],"check":"control: heat then locked cool","expected":["heat","heat","idle","idle","idle","idle","idle","cool","cool","idle"],"passed":true},{"actual":["heat","idle","idle","idle","idle","idle","cool","cool"],"check":"control: short heat cycle then hot","expected":["heat","idle","idle","idle","idle","idle","cool","cool"],"passed":true},{"actual":["idle","cool","cool","idle","idle"],"check":"control: deadband squeeze","expected":["idle","cool","cool","idle","idle"],"passed":true},{"actual":["idle","idle","idle","idle","idle","idle","idle","idle","idle","idle","idle"],"check":"regression: scenario 1","expected":["idle","idle","idle","idle","idle","idle","idle","idle","idle","idle","idle"],"passed":true},{"actual":["idle","idle","idle","idle","cool","cool","cool","cool","cool","cool","cool","cool"],"check":"control: scenario 2","expected":["idle","idle","idle","idle","cool","cool","cool","cool","cool","cool","cool","cool"],"passed":true},{"actual":["heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat"],"check":"control: scenario 3","expected":["heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: exact thresholds\", \"actual\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"passed\": false}, {\"check\": \"regression: scenario 6\", \"actual\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"expected\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"passed\": false}, {\"check\": \"control: heat then locked cool\", \"actual\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"idle\"], \"expected\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"idle\"], \"passed\": true}, {\"check\": \"control: short heat cycle then hot\", \"actual\": [\"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\"], \"expected\": [\"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\"], \"passed\": true}, {\"check\": \"control: deadband squeeze\", \"actual\": [\"idle\", \"cool\", \"cool\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"cool\", \"cool\", \"idle\", \"idle\"], \"passed\": true}, {\"check\": \"regression: scenario 1\", \"actual\": [\"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"passed\": true}, {\"check\": \"control: scenario 2\", \"actual\": [\"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\"], \"expected\": [\"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\"], \"passed\": true}, {\"check\": \"control: scenario 3\", \"actual\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"expected\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"passed\": true}], \"passed\": false}\n"},"broken":{"elapsed_ms":39.596,"exit_code":1,"observations":[{"actual":["heat","heat","idle","idle","idle","idle","idle"],"check":"regression: exact thresholds","expected":["idle","heat","idle","idle","idle","idle","idle"],"passed":false},{"actual":["heat","heat","heat","heat","heat","idle","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat"],"check":"regression: scenario 6","expected":["heat","heat","heat","heat","heat","idle","idle","idle","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat","heat"],"passed":false},{"actual":["heat","heat","idle","idle","idle","idle","idle","cool","cool","idle"],"check":"control: heat then locked cool","expected":["heat","heat","idle","idle","idle","idle","idle","cool","cool","idle"],"passed":true},{"actual":["heat","idle","idle","idle","idle","idle","cool","cool"],"check":"control: short heat cycle then hot","expected":["heat","idle","idle","idle","idle","idle","cool","cool"],"passed":true},{"actual":["idle","cool","cool","idle","idle"],"check":"control: deadband squeeze","expected":["idle","cool","cool","idle","idle"],"passed":true},{"actual":["idle","idle","idle","idle","idle","idle","idle","idle","idle","idle","heat"],"check":"regression: scenario 1","expected":["idle","idle","idle","idle","idle","idle","idle","idle","idle","idle","idle"],"passed":false},{"actual":["idle","idle","idle","idle","cool","cool","cool","cool","cool","cool","cool","cool"],"check":"control: scenario 2","expected":["idle","idle","idle","idle","cool","cool","cool","cool","cool","cool","cool","cool"],"passed":true},{"actual":["heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat"],"check":"control: scenario 3","expected":["heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat"],"passed":true}],"passed":false,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: exact thresholds\", \"actual\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"passed\": false}, {\"check\": \"regression: scenario 6\", \"actual\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"expected\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"passed\": false}, {\"check\": \"control: heat then locked cool\", \"actual\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"idle\"], \"expected\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"idle\"], \"passed\": true}, {\"check\": \"control: short heat cycle then hot\", \"actual\": [\"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\"], \"expected\": [\"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\"], \"passed\": true}, {\"check\": \"control: deadband squeeze\", \"actual\": [\"idle\", \"cool\", \"cool\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"cool\", \"cool\", \"idle\", \"idle\"], \"passed\": true}, {\"check\": \"regression: scenario 1\", \"actual\": [\"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"heat\"], \"expected\": [\"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"passed\": false}, {\"check\": \"control: scenario 2\", \"actual\": [\"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\"], \"expected\": [\"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\"], \"passed\": true}, {\"check\": \"control: scenario 3\", \"actual\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"expected\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"passed\": true}], \"passed\": false}\n"},"fixed":{"elapsed_ms":42.1,"exit_code":0,"observations":[{"actual":["idle","heat","idle","idle","idle","idle","idle"],"check":"regression: exact thresholds","expected":["idle","heat","idle","idle","idle","idle","idle"],"passed":true},{"actual":["heat","heat","heat","heat","heat","idle","idle","idle","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat","heat"],"check":"regression: scenario 6","expected":["heat","heat","heat","heat","heat","idle","idle","idle","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat","heat"],"passed":true},{"actual":["heat","heat","idle","idle","idle","idle","idle","cool","cool","idle"],"check":"control: heat then locked cool","expected":["heat","heat","idle","idle","idle","idle","idle","cool","cool","idle"],"passed":true},{"actual":["heat","idle","idle","idle","idle","idle","cool","cool"],"check":"control: short heat cycle then hot","expected":["heat","idle","idle","idle","idle","idle","cool","cool"],"passed":true},{"actual":["idle","cool","cool","idle","idle"],"check":"control: deadband squeeze","expected":["idle","cool","cool","idle","idle"],"passed":true},{"actual":["idle","idle","idle","idle","idle","idle","idle","idle","idle","idle","idle"],"check":"regression: scenario 1","expected":["idle","idle","idle","idle","idle","idle","idle","idle","idle","idle","idle"],"passed":true},{"actual":["idle","idle","idle","idle","cool","cool","cool","cool","cool","cool","cool","cool"],"check":"control: scenario 2","expected":["idle","idle","idle","idle","cool","cool","cool","cool","cool","cool","cool","cool"],"passed":true},{"actual":["heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat"],"check":"control: scenario 3","expected":["heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","heat","idle","idle","heat","heat","heat","heat","heat","heat","heat","heat"],"passed":true}],"passed":true,"stderr":"","stdout":"{\"observations\": [{\"check\": \"regression: exact thresholds\", \"actual\": [\"idle\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"passed\": true}, {\"check\": \"regression: scenario 6\", \"actual\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"expected\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"passed\": true}, {\"check\": \"control: heat then locked cool\", \"actual\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"idle\"], \"expected\": [\"heat\", \"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"idle\"], \"passed\": true}, {\"check\": \"control: short heat cycle then hot\", \"actual\": [\"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\"], \"expected\": [\"heat\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\"], \"passed\": true}, {\"check\": \"control: deadband squeeze\", \"actual\": [\"idle\", \"cool\", \"cool\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"cool\", \"cool\", \"idle\", \"idle\"], \"passed\": true}, {\"check\": \"regression: scenario 1\", \"actual\": [\"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"expected\": [\"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\", \"idle\"], \"passed\": true}, {\"check\": \"control: scenario 2\", \"actual\": [\"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\"], \"expected\": [\"idle\", \"idle\", \"idle\", \"idle\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\", \"cool\"], \"passed\": true}, {\"check\": \"control: scenario 3\", \"actual\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"expected\": [\"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"idle\", \"idle\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\", \"heat\"], \"passed\": true}], \"passed\": true}\n"}},"verified":true,"visibility":"public"}