hitl_tester.modules.bms.charger
Provides controls for the Rigol DL711 Power Supply.
(c) 2020-2024 TurnAround Factor, Inc.
#
CUI DISTRIBUTION CONTROL
Controlled by: DLA J68 R&D SBIP
CUI Category: Small Business Research and Technology
Distribution/Dissemination Controls: PROTECTED BY SBIR DATA RIGHTS
POC: GOV SBIP Program Manager Denise Price, 571-767-0111
Distribution authorized to U.S. Government Agencies only, to protect information not owned by the
U.S. Government and protected by a contractor’s ‘limited rights’ statement, or received with the understanding that
it is not routinely transmitted outside the U.S. Government (determination made September 14, 2024). Other requests
for this document shall be referred to ACOR DLA Logistics Operations (J-68), 8725 John J. Kingman Rd., Suite 4317,
Fort Belvoir, VA 22060-6221
#
SBIR DATA RIGHTS
Contract No.:SP4701-23-C-0083
Contractor Name: TurnAround Factor, Inc.
Contractor Address: 10365 Wood Park Ct. Suite 313 / Ashland, VA 23005
Expiration of SBIR Data Rights Period: September 24, 2029
The Government's rights to use, modify, reproduce, release, perform, display, or disclose technical data or computer
software marked with this legend are restricted during the period shown as provided in paragraph (b)(4) of the Rights
in Noncommercial Technical Data and Computer Software--Small Business Innovative Research (SBIR) Program clause
contained in the above identified contract. No restrictions apply after the expiration date shown above. Any
reproduction of technical data, computer software, or portions thereof marked with this legend must also reproduce
the markings.
1""" 2Provides controls for the Rigol DL711 Power Supply. 3 4# (c) 2020-2024 TurnAround Factor, Inc. 5# 6# CUI DISTRIBUTION CONTROL 7# Controlled by: DLA J68 R&D SBIP 8# CUI Category: Small Business Research and Technology 9# Distribution/Dissemination Controls: PROTECTED BY SBIR DATA RIGHTS 10# POC: GOV SBIP Program Manager Denise Price, 571-767-0111 11# Distribution authorized to U.S. Government Agencies only, to protect information not owned by the 12# U.S. Government and protected by a contractor’s ‘limited rights’ statement, or received with the understanding that 13# it is not routinely transmitted outside the U.S. Government (determination made September 14, 2024). Other requests 14# for this document shall be referred to ACOR DLA Logistics Operations (J-68), 8725 John J. Kingman Rd., Suite 4317, 15# Fort Belvoir, VA 22060-6221 16# 17# SBIR DATA RIGHTS 18# Contract No.:SP4701-23-C-0083 19# Contractor Name: TurnAround Factor, Inc. 20# Contractor Address: 10365 Wood Park Ct. Suite 313 / Ashland, VA 23005 21# Expiration of SBIR Data Rights Period: September 24, 2029 22# The Government's rights to use, modify, reproduce, release, perform, display, or disclose technical data or computer 23# software marked with this legend are restricted during the period shown as provided in paragraph (b)(4) of the Rights 24# in Noncommercial Technical Data and Computer Software--Small Business Innovative Research (SBIR) Program clause 25# contained in the above identified contract. No restrictions apply after the expiration date shown above. Any 26# reproduction of technical data, computer software, or portions thereof marked with this legend must also reproduce 27# the markings. 28""" 29 30from __future__ import annotations 31 32import atexit 33from time import sleep 34 35from hitl_tester.modules.bms.plateset import Plateset 36from hitl_tester.modules.bms_types import SafeResource 37from hitl_tester.modules.logger import logger 38 39MAX_ATTEMPTS = 60 40 41 42class Charger: 43 """Rigol DL711 Power Supply command wrapper.""" 44 45 def __init__(self, resource: SafeResource): 46 """ 47 Initialize the DL711 wrapper with a specific PyVISA resource. 48 This class does NOT open the resource, you have to open it for yourself! 49 """ 50 self.resource = resource 51 self.target_amps: float = 0 52 self.target_volts: float = 0 53 self.reset() 54 55 @atexit.register 56 def __atexit__(): 57 """Configure a safe shut down for when the class instance is destroyed.""" 58 self.disable() 59 60 def __call__(self, volts: float, amps: float, ce_switch: bool = True): 61 self.set_profile(volts, amps) 62 Plateset().ce_switch = ce_switch 63 return self 64 65 def __enter__(self): 66 self.enable() 67 return self 68 69 def __exit__(self, exc_type, exc_value, exc_traceback): 70 self.disable() 71 Plateset().ce_switch = False 72 73 def set_profile(self, volts: float, amps: float): 74 """Sets charging profile""" 75 self.target_volts = volts 76 self.target_amps = amps 77 self.resource.write(f":APPL {volts}, {amps}") 78 sleep(1) # The charger needs time to process the previous commands 79 80 def _amps_limit(self, new_amps_limit: float): 81 """Sets output current limit""" 82 self.resource.write(f":CURR:PROT {new_amps_limit}") 83 84 def _volts_limit(self, new_volts_limit: float): 85 """Sets output voltage limit""" 86 self.resource.write(f":VOLT:PROT {new_volts_limit}") 87 88 amps_limit = property(None, _amps_limit) # make this function accessible as a write-only attribute 89 volts_limit = property(None, _volts_limit) # make this function accessible as a write-only attribute 90 91 @property 92 def amps(self) -> float: 93 """Reads the current being sourced""" 94 return float(self.resource.query(":MEAS:CURR?")) 95 96 @amps.setter 97 def amps(self, new_amps: float): 98 """Sets the power supply output current""" 99 self.target_amps = new_amps 100 self.resource.write(f":CURR {new_amps}") 101 102 @property 103 def volts(self) -> float: 104 """Reads the volts being sourced""" 105 return float(self.resource.query(":MEAS:VOLT?")) 106 107 @volts.setter 108 def volts(self, new_volts: float): 109 """Sets the power supply output voltage""" 110 self.target_volts = new_volts 111 self.resource.write(f":VOLT {new_volts}") 112 113 def enable(self): 114 """Enables power supply output""" 115 logger.write_info_to_report("Enabling charger") 116 sleep(1) 117 Plateset().charger_switch = True # Turn on the charger switch 118 sleep(1) 119 self.resource.write(":OUTP:STAT ON") 120 sleep(1) # This instrument needs time to initialize 121 122 def disable(self): 123 """Disables power supply output""" 124 logger.write_info_to_report("Disabling charger") 125 Plateset().charger_switch = False # Turn off the charger switch 126 self.resource.write(":OUTP:STAT OFF") 127 sleep(1) # The charger needs time to process the previous commands 128 129 def reset(self): 130 """Resets the instrument""" 131 self.resource.write("*RST") 132 sleep(3)
MAX_ATTEMPTS =
60
class
Charger:
43class Charger: 44 """Rigol DL711 Power Supply command wrapper.""" 45 46 def __init__(self, resource: SafeResource): 47 """ 48 Initialize the DL711 wrapper with a specific PyVISA resource. 49 This class does NOT open the resource, you have to open it for yourself! 50 """ 51 self.resource = resource 52 self.target_amps: float = 0 53 self.target_volts: float = 0 54 self.reset() 55 56 @atexit.register 57 def __atexit__(): 58 """Configure a safe shut down for when the class instance is destroyed.""" 59 self.disable() 60 61 def __call__(self, volts: float, amps: float, ce_switch: bool = True): 62 self.set_profile(volts, amps) 63 Plateset().ce_switch = ce_switch 64 return self 65 66 def __enter__(self): 67 self.enable() 68 return self 69 70 def __exit__(self, exc_type, exc_value, exc_traceback): 71 self.disable() 72 Plateset().ce_switch = False 73 74 def set_profile(self, volts: float, amps: float): 75 """Sets charging profile""" 76 self.target_volts = volts 77 self.target_amps = amps 78 self.resource.write(f":APPL {volts}, {amps}") 79 sleep(1) # The charger needs time to process the previous commands 80 81 def _amps_limit(self, new_amps_limit: float): 82 """Sets output current limit""" 83 self.resource.write(f":CURR:PROT {new_amps_limit}") 84 85 def _volts_limit(self, new_volts_limit: float): 86 """Sets output voltage limit""" 87 self.resource.write(f":VOLT:PROT {new_volts_limit}") 88 89 amps_limit = property(None, _amps_limit) # make this function accessible as a write-only attribute 90 volts_limit = property(None, _volts_limit) # make this function accessible as a write-only attribute 91 92 @property 93 def amps(self) -> float: 94 """Reads the current being sourced""" 95 return float(self.resource.query(":MEAS:CURR?")) 96 97 @amps.setter 98 def amps(self, new_amps: float): 99 """Sets the power supply output current""" 100 self.target_amps = new_amps 101 self.resource.write(f":CURR {new_amps}") 102 103 @property 104 def volts(self) -> float: 105 """Reads the volts being sourced""" 106 return float(self.resource.query(":MEAS:VOLT?")) 107 108 @volts.setter 109 def volts(self, new_volts: float): 110 """Sets the power supply output voltage""" 111 self.target_volts = new_volts 112 self.resource.write(f":VOLT {new_volts}") 113 114 def enable(self): 115 """Enables power supply output""" 116 logger.write_info_to_report("Enabling charger") 117 sleep(1) 118 Plateset().charger_switch = True # Turn on the charger switch 119 sleep(1) 120 self.resource.write(":OUTP:STAT ON") 121 sleep(1) # This instrument needs time to initialize 122 123 def disable(self): 124 """Disables power supply output""" 125 logger.write_info_to_report("Disabling charger") 126 Plateset().charger_switch = False # Turn off the charger switch 127 self.resource.write(":OUTP:STAT OFF") 128 sleep(1) # The charger needs time to process the previous commands 129 130 def reset(self): 131 """Resets the instrument""" 132 self.resource.write("*RST") 133 sleep(3)
Rigol DL711 Power Supply command wrapper.
Charger(resource: hitl_tester.modules.bms_types.SafeResource)
46 def __init__(self, resource: SafeResource): 47 """ 48 Initialize the DL711 wrapper with a specific PyVISA resource. 49 This class does NOT open the resource, you have to open it for yourself! 50 """ 51 self.resource = resource 52 self.target_amps: float = 0 53 self.target_volts: float = 0 54 self.reset() 55 56 @atexit.register 57 def __atexit__(): 58 """Configure a safe shut down for when the class instance is destroyed.""" 59 self.disable()
Initialize the DL711 wrapper with a specific PyVISA resource. This class does NOT open the resource, you have to open it for yourself!
def
set_profile(self, volts: float, amps: float):
74 def set_profile(self, volts: float, amps: float): 75 """Sets charging profile""" 76 self.target_volts = volts 77 self.target_amps = amps 78 self.resource.write(f":APPL {volts}, {amps}") 79 sleep(1) # The charger needs time to process the previous commands
Sets charging profile
amps: float
92 @property 93 def amps(self) -> float: 94 """Reads the current being sourced""" 95 return float(self.resource.query(":MEAS:CURR?"))
Reads the current being sourced
volts: float
103 @property 104 def volts(self) -> float: 105 """Reads the volts being sourced""" 106 return float(self.resource.query(":MEAS:VOLT?"))
Reads the volts being sourced
def
enable(self):
114 def enable(self): 115 """Enables power supply output""" 116 logger.write_info_to_report("Enabling charger") 117 sleep(1) 118 Plateset().charger_switch = True # Turn on the charger switch 119 sleep(1) 120 self.resource.write(":OUTP:STAT ON") 121 sleep(1) # This instrument needs time to initialize
Enables power supply output
def
disable(self):
123 def disable(self): 124 """Disables power supply output""" 125 logger.write_info_to_report("Disabling charger") 126 Plateset().charger_switch = False # Turn off the charger switch 127 self.resource.write(":OUTP:STAT OFF") 128 sleep(1) # The charger needs time to process the previous commands
Disables power supply output