#!/usr/bin/env python3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  unittest 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  unittest . mock  import  patch 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								from  openpilot . common . params  import  Params 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								from  openpilot . selfdrive . thermald . power_monitoring  import  PowerMonitoring ,  CAR_BATTERY_CAPACITY_uWh ,  \
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                                CAR_CHARGING_RATE_W ,  VBATT_PAUSE_CHARGING ,  DELAY_SHUTDOWN_TIME_S 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# Create fake time 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								ssb  =  0. 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  mock_time_monotonic ( ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  global  ssb 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  ssb  + =  1. 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  ssb 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								TEST_DURATION_S  =  50 
 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								GOOD_VOLTAGE  =  12  *  1e3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								VOLTAGE_BELOW_PAUSE_CHARGING  =  ( VBATT_PAUSE_CHARGING  -  1 )  *  1e3 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								def  pm_patch ( name ,  value ,  constant = False ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  if  constant : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  patch ( f " openpilot.selfdrive.thermald.power_monitoring. { name } " ,  value ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  return  patch ( f " openpilot.selfdrive.thermald.power_monitoring. { name } " ,  return_value = value ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								@patch ( " time.monotonic " ,  new = mock_time_monotonic ) 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								class  TestPowerMonitoring ( unittest . TestCase ) : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  setUp ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . params  =  Params ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Test to see that it doesn't do anything when pandaState is None 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  test_pandaState_present ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  _  in  range ( 10 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      pm . calculate ( None ,  None ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . assertEqual ( pm . get_power_used ( ) ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . assertEqual ( pm . get_car_battery_capacity ( ) ,  ( CAR_BATTERY_CAPACITY_uWh  /  10 ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to see that it doesn't integrate offroad when ignition is True 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_offroad_ignition ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  _  in  range ( 10 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      pm . calculate ( GOOD_VOLTAGE ,  True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    self . assertEqual ( pm . get_power_used ( ) ,  0 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to see that it integrates with discharging battery 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_offroad_integration_discharging ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  _  in  range ( TEST_DURATION_S  +  1 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( GOOD_VOLTAGE ,  False ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      expected_power_usage  =  ( ( TEST_DURATION_S / 3600 )  *  POWER_DRAW  *  1e6 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertLess ( abs ( pm . get_power_used ( )  -  expected_power_usage ) ,  10 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check positive integration of car_battery_capacity 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_car_battery_integration_onroad ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  _  in  range ( TEST_DURATION_S  +  1 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( GOOD_VOLTAGE ,  True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      expected_capacity  =  ( ( TEST_DURATION_S / 3600 )  *  CAR_CHARGING_RATE_W  *  1e6 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertLess ( abs ( pm . get_car_battery_capacity ( )  -  expected_capacity ) ,  10 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check positive integration upper limit 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_car_battery_integration_upper_limit ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh  -  1000 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  _  in  range ( TEST_DURATION_S  +  1 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( GOOD_VOLTAGE ,  True ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      estimated_capacity  =  CAR_BATTERY_CAPACITY_uWh  +  ( CAR_CHARGING_RATE_W  /  3600  *  1e6 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertLess ( abs ( pm . get_car_battery_capacity ( )  -  estimated_capacity ) ,  10 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check negative integration of car_battery_capacity 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_car_battery_integration_offroad ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  _  in  range ( TEST_DURATION_S  +  1 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( GOOD_VOLTAGE ,  False ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      expected_capacity  =  CAR_BATTERY_CAPACITY_uWh  -  ( ( TEST_DURATION_S / 3600 )  *  POWER_DRAW  *  1e6 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertLess ( abs ( pm . get_car_battery_capacity ( )  -  expected_capacity ) ,  10 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check negative integration lower limit 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_car_battery_integration_lower_limit ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  4 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  1000 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  _  in  range ( TEST_DURATION_S  +  1 ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( GOOD_VOLTAGE ,  False ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      estimated_capacity  =  0  -  ( ( 1 / 3600 )  *  POWER_DRAW  *  1e6 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertLess ( abs ( pm . get_car_battery_capacity ( )  -  estimated_capacity ) ,  10 ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check policy of stopping charging after MAX_TIME_OFFROAD_S 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_max_time_offroad ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    MOCKED_MAX_OFFROAD_TIME  =  3600 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  0  # To stop shutting down for other reasons 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    with  pm_patch ( " MAX_TIME_OFFROAD_S " ,  MOCKED_MAX_OFFROAD_TIME ,  constant = True ) ,  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      start_time  =  ssb 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ignition  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      while  ssb  < =  start_time  +  MOCKED_MAX_OFFROAD_TIME : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( GOOD_VOLTAGE ,  ignition ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ssb  -  start_time )  %  1000  ==  0  and  ssb  <  start_time  +  MOCKED_MAX_OFFROAD_TIME : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          self . assertFalse ( pm . should_shutdown ( ignition ,  True ,  start_time ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertTrue ( pm . should_shutdown ( ignition ,  True ,  start_time ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_car_voltage ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  0  # To stop shutting down for other reasons 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TEST_TIME  =  350 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S  =  50 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    with  pm_patch ( " VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S " ,  VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S ,  constant = True ) ,  \
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								         pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ignition  =  False 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      start_time  =  ssb 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  i  in  range ( TEST_TIME ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( VOLTAGE_BELOW_PAUSE_CHARGING ,  ignition ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  i  %  10  ==  0 : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          self . assertEqual ( pm . should_shutdown ( ignition ,  True ,  start_time ,  True ) , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								                           ( pm . car_voltage_mV  <  VBATT_PAUSE_CHARGING  *  1e3  and 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            ( ssb  -  start_time )  >  VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S  and 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                             ( ssb  -  start_time )  >  DELAY_SHUTDOWN_TIME_S ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . assertTrue ( pm . should_shutdown ( ignition ,  True ,  start_time ,  True ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check policy of not stopping charging when DisablePowerDown is set 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  test_disable_power_down ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  0  # To stop shutting down for other reasons 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TEST_TIME  =  100 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . params . put_bool ( " DisablePowerDown " ,  True ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ignition  =  False 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  i  in  range ( TEST_TIME ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( VOLTAGE_BELOW_PAUSE_CHARGING ,  ignition ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  i  %  10  ==  0 : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          self . assertFalse ( pm . should_shutdown ( ignition ,  True ,  ssb ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertFalse ( pm . should_shutdown ( ignition ,  True ,  ssb ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  # Test to check policy of not stopping charging when ignition 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  test_ignition ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  0  # To stop shutting down for other reasons 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TEST_TIME  =  100 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      ignition  =  True 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      for  i  in  range ( TEST_TIME ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( VOLTAGE_BELOW_PAUSE_CHARGING ,  ignition ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  i  %  10  ==  0 : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          self . assertFalse ( pm . should_shutdown ( ignition ,  True ,  ssb ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertFalse ( pm . should_shutdown ( ignition ,  True ,  ssb ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  # Test to check policy of not stopping charging when harness is not connected 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  def  test_harness_connection ( self ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    POWER_DRAW  =  0  # To stop shutting down for other reasons 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TEST_TIME  =  100 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    with  pm_patch ( " HARDWARE.get_current_power_draw " ,  POWER_DRAW ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      pm . car_battery_capacity_uWh  =  CAR_BATTERY_CAPACITY_uWh 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      ignition  =  False 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      for  i  in  range ( TEST_TIME ) : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        pm . calculate ( VOLTAGE_BELOW_PAUSE_CHARGING ,  ignition ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  i  %  10  ==  0 : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								          self . assertFalse ( pm . should_shutdown ( ignition ,  False ,  ssb ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								      self . assertFalse ( pm . should_shutdown ( ignition ,  False ,  ssb ,  False ) ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								  def  test_delay_shutdown_time ( self ) : 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pm  =  PowerMonitoring ( ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pm . car_battery_capacity_uWh  =  0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    ignition  =  False 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    in_car  =  True 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    offroad_timestamp  =  ssb 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    started_seen  =  True 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    pm . calculate ( VOLTAGE_BELOW_PAUSE_CHARGING ,  ignition ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ssb  <  offroad_timestamp  +  DELAY_SHUTDOWN_TIME_S : 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								      self . assertFalse ( pm . should_shutdown ( ignition ,  in_car , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                          offroad_timestamp , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                          started_seen ) , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								                       f " Should not shutdown before  { DELAY_SHUTDOWN_TIME_S }  seconds offroad time " ) 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								    self . assertTrue ( pm . should_shutdown ( ignition ,  in_car , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                       offroad_timestamp , 
  
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								                                       started_seen ) , 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    f " Should shutdown after  { DELAY_SHUTDOWN_TIME_S }  seconds offroad time " ) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								if  __name__  ==  " __main__ " : 
 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  unittest . main ( )