def test_soc(sim): """ A not very extensive test that verifies the SOC drains to zero as expected with a provided current. """ sim.start_logging('sim_traces/soc_tests.blf') # run the sim till we get an SOC message for i in range(2000): sim.tick() #if 'BmsStatus_SOC' in sim.signals: # break assert 'BmsStatus_SOC' in sim.signals, "BmsStatus never sent" assert sim.signals['BmsStatus_SOC'] == 100, 'SOC did not start at 100%' sim.set_current(400) drain_time_ms = 14000 for i in range(drain_time_ms): sim.tick() # get last SOC update sim.set_current(0) for i in range(2000): sim.tick() assert sim.signals['BmsStatus_SOC'] <= 93
def test_temperature_faults(sim): """ Vary thermistor voltages and check for shutdown line assertion. """ sim.start_logging('sim_traces/temperature_faults.blf') for i in range(0, 1000): sim.tick() assert sim.signals['BmsFaultVector_OVER_TEMPERATURE'] == 0 assert sim.signals['BmsFaultVector_TEMPERATURE_IRRATIONAL'] == 0 assert sim.get_shutdown_line() == 1 sim.stage_temp_info(therm_index=0, voltage=3.0) for i in range(0, 3000): sim.tick() assert sim.signals['BmsFaultVector_OVER_TEMPERATURE'] == 0 assert sim.signals['BmsFaultVector_TEMPERATURE_IRRATIONAL'] == 1 # Could check shutdown line here but it doesn't assert for 10s on irrational condition sim.stage_temp_info(therm_index=0, voltage=.5) for i in range(0, 3000): sim.tick() assert sim.signals['BmsFaultVector_OVER_TEMPERATURE'] == 1 assert sim.signals['BmsFaultVector_TEMPERATURE_IRRATIONAL'] == 0 assert sim.get_shutdown_line( ) == 0 # shutdown should assert immediately here
def test_balancing(sim): """ Verify cells balance when they are above the charging threshold and when they are too far ahead of other cells. """ sim.start_logging('sim_traces/balancing.blf') # shouldn't start with AIRs closed (assuming on charger, so this closes the AIRs) assert sim.get_charge_enable() == False # start charging for i in range(0, 90): sim.stage_cell_info(i, 3.9, False) sim.set_charger_available(1) charging = None for i in range(0, 8000): sim.tick() if 'BmsChargeRequest_Control' in sim.signals: charging = not sim.signals[ 'BmsChargeRequest_Control'] # yes this is active low for some reason assert charging, "Charging did not begin" # now set every other cell to a voltage that should trigger balancing for i in range(1, 91, 2): sim.stage_cell_info(i, 4.31, False) # cells that are above the charging threshold should be balanced even if they arent that far behind the largest voltage sim.stage_cell_info(0, 4.29, False) # enter balancing for i in range(0, 10000): sim.tick() for i in range(2, 90, 2): assert sim.read_drain_state(i) == False, "Wrong cell drained" for i in range(1, 91, 2): assert sim.read_drain_state( i) == True, "Cell not drained when appropriate" # should have AIRs closed when balancing assert sim.get_charge_enable() == True assert sim.read_drain_state(0) == True, "Cell not drained when appropriate"
def test_charging_fault(sim): sim.start_logging('sim_traces/charging_fault.blf') # simulate charging condition for i in range(0, 90): sim.stage_cell_info(i, 2.0, False) sim.set_charger_available(True) # make sure we start charging started_charging = None for i in range(0, 5000): sim.tick() if 'BmsChargeRequest_Control' in sim.signals: started_charging = (sim.signals['BmsChargeRequest_Control'] == 0) if started_charging: break assert started_charging, "Did not start charging." # # cause an overtemperature fault sim.stage_temp_info(0, .5) # wait till there's a fault then make sure charging stops soon after faulted = None for i in range(0, 10000): sim.tick() faulted = (sim.signals['BmsFaultVector_OVER_TEMPERATURE'] == 1) if (faulted): break assert faulted, "Temperature fault never occured." stopped_charging = False for i in range(0, 1500): sim.tick() stopped_charging = (sim.signals['BmsChargeRequest_Control'] == 1) if stopped_charging: break assert stopped_charging, "Charging did not stop on fault."
def test_blink_check(sim): """ Basic test to make sure freertos tasks are running and bms interface works. If this breaks, your code changes likely broke something fundamental to the sim. ...Or you changed the status led nominal pattern Verifies Status LED blinks once every three seconds. """ sim.start_logging("sim_traces/smoke_tests.blf") led_was_off = False led_was_on = False for ms in range(0, 3000): sim.tick() led_state = sim.get_status_led() if led_state == True: led_was_on = True elif led_state == False: led_was_off = True; assert led_was_off == True, "Status LED failed to turn off" assert led_was_on == True, "Status LED failed to turn on"
def test_out_of_charge(sim): sim.start_logging('sim_traces/out_of_charge.blf') for i in range(0, 1000): sim.tick() assert sim.get_shutdown_line( ) == 1, "Shutdown line asserted on startup." # simulate current and make sure we're still running sim.set_current(100) for i in range(0, 5000): sim.tick() assert sim.get_shutdown_line( ) == 1, "Shutdown line asserted during regular driving." # set a single cell voltage to below the shut down threshold sim.stage_cell_info(0, 1.2, False) for i in range(0, 1500): sim.tick() assert sim.get_shutdown_line( ) == 0, "BMS did not request shutdown with a bottomed out cell!"
def test_charge_to_full(sim): sim.start_logging('sim_traces/charge_to_full.blf') # set up a charging condition for i in range(0, 90): sim.stage_cell_info(i, 2.0, False) # make sure we start out not charging for i in range(0, 1000): sim.tick() assert 'BmsChargeRequest_Control' not in sim.signals # simulate a plug in sim.set_charger_available(True) # wait for charging to be requested charge_requested = None for i in range(0, 5000): sim.tick() if ('BmsChargeRequest_Control' in sim.signals): charge_requested = sim.signals['BmsChargeRequest_Control'] if charge_requested == False: break assert charge_requested == 0, 'Charging did not start on plug in!' # charge for a bit, simulate nominal charging current sim.set_current(50) # max charge current / 2 for i in range(0, 10000): sim.tick() # make sure we stay charging assert sim.signals[ 'BmsChargeRequest_Control'] == 0, "Stopped charging spontaneously!" # simulate charged condition for i in range(0, 90): sim.stage_cell_info(i, 4.25, False) # make sure we stop charging stopped_charging = None for i in range(0, 5000): sim.tick() stopped_charging = (sim.signals['BmsChargeRequest_Control'] == 1) if stopped_charging: break assert stopped_charging, "Charging did not stop on full charge condition." # now to test if balancing state can be re-entered # drain cells, cycle connector for i in range(0, 90): sim.stage_cell_info(i, 4.1, False) sim.set_charger_available(False) for i in range(1000): sim.tick() # plug connector back in, wait 30 seconds, should end up in charging state sim.set_charger_available(True) sim.set_current(13.8) for i in range(35000): sim.tick() assert sim.signals[ 'BmsStatus_ChargeState'] == 'ChargeState_CONNECTED_CHARGING' # now simulate balancing condition sim.stage_cell_info(15, 4.3, False) for i in range(1000): sim.tick() assert sim.signals[ 'BmsStatus_ChargeState'] == 'ChargeState_CONNECTED_BALANCING'