def test(self): for _ in range(10): self.write_settings(DCLevel(12, 0.1), True) self.write_settings(DCLevel(14, 0.2)) self.write_settings(DCLevel(16, 0.3)) self.write_settings(DCLevel(10, 0.4)) self.write_settings(output_state=False)
def __read_settings(self) -> Tuple[DCLevel, DCLevel]: """ returns settings obj, measurement obj """ results = cast(STTResponse, self._get_measurement()) self.alarms = AlarmStatusRegister(results.al) self.operations_status = OperationStatusRegister(results.os) self.error_codes = ErrorCodesRegister(results.ps) return DCLevel(results.v_meas, results.i_meas), DCLevel(results.v_set, results.i_set)
def _instrument_debug(self) -> None: self.log_level(logging.DEBUG) self.calculate_connection_state(LightLineV1ConnectionState) self.ramp_up() self.measure(fresh=True) self.write_settings(DCLevel(0., 0.)) tf = time() + 5 while time() < tf: self.measure(fresh=True)
def instruments_setup(self) -> None: self.ps.log_level(self.power_supply_log_level) self.ftdi.log_level(self.ftdi_log_level) self.lm.log_level(self.light_meter_log_level) with self.session_manager() as session: if not LightingStation3LightMeterCalibration.is_up_to_date( session, self.light_meter_calibration_interval_hours): self.ps.write_settings(DCLevel(0, 0), False) self.lm.calibrate() session.make(LightingStation3LightMeterCalibration())
def measure(self, fresh: bool = True): """ note that, even though we send the measure command, rather than the fetch command, the BK appears to be responding with a buffered value updated every 220ms this method returns in ~15ms unless @fresh, in which case it waits for the value to have been updated """ if fresh: self._instrument_delay(self.next_meas - time()) self.next_meas = time() + self.MEASUREMENT_WAIT meas = DCLevel(*list( map(self.read, [self.__Command.GET_VOLT, self.__Command.GET_CURR]))) self.info(meas, f'fresh={fresh}') return meas
class LightLineV1ConnectionState(ConnectionStateCalcType): power_supply_setting = DCLevel(10, .5) @classmethod def calculate(cls, meas: DCLevel) -> 'ConnectionState': if meas.V > 9.: if meas.A < .015: return ConnectionState.UNCONNECTED return ConnectionState.CONNECTED elif meas.A > .45: if meas.V < 2.: if meas.V < .3: return ConnectionState.FAULT_SHORT_CIRCUIT return ConnectionState.FAULT_REVERSED_POLARITY return ConnectionState.CONNECTED return ConnectionState.FAULT_POWER_SUPPLY_ERROR
def string_check(self, param: messages.Param) -> None: self.bk.write_settings(DCLevel(param.v, param.i)) [self.pixie_ch_command(param.ch_mask) for _ in range(20)] sleep(self.CH_SETTLE_WAIT_S) light = self.lm.measure() power = self.bk.measure() dist = light.distance_from(param) dist_pf = dist <= param.color_dist_max fcd_pf = (param.fcd_nom - param.fcd_tol) <= light.fcd <= ( param.fcd_nom + param.fcd_tol) p_pf = (param.p_nom - param.p_tol) <= power.P <= (param.p_nom + param.p_tol) self.pixie_ch_command(0) result = messages.Result(param.row, light.x, light.y, dist, light.fcd, power.P, dist_pf, fcd_pf, p_pf) self.put(result) self.string_results.append(result) sleep(.1)
def set_power_supply_for_programming(self) -> None: self.bk.write_settings(DCLevel(self.PROGRAMMING_V, self.PROGRAMMING_I))
def _lambda_cleanup(self) -> None: self.write_settings(DCLevel(0., 0.), False)
def string_test(self, params: LightingStation3ParamRow, do_dmx: bool = True) -> Union[bool, LightingStation3ResultRow]: read_settings_promise = self.ps.read_settings() # noinspection PyNoneFunctionAssignment dmx_promise = self.ftdi.dmx_control( is_continuous=True, ch_value_d=params.dmx_control_dict ) if do_dmx else None # noinspection PyUnresolvedReferences initial_power_settings = read_settings_promise.resolve() dc_setting_promise = self.ps.ramp_up() if params.ramp else self.ps.write_settings( DCLevel(params.v, params.i), True ) light_measurements: List[LightingStation3LightMeasurement] = [] _duration = params.duration _test_step_k = self.model.step_ids.string_checks[params.id] self.emit(StepStartMessage(k=_test_step_k, minor_text=params.name, max_val=_duration)) _emit = self.emit def consumer(sample: ThermalDropSample) -> None: model = LightingStation3LightMeasurement(pct_drop=sample.pct_drop, te=sample.te) light_measurements.append(_emit(model)) _emit(StepProgressMessage(k=_test_step_k, value=min(_duration, sample.te))) try: # noinspection PyUnresolvedReferences first, last = self.lm.thermal_drop( params.fcd_nom * .05, params.duration, 2., consumer ).resolve() # type: LightMeasurement, LightMeasurement except LightMeterError as e: raise TestFailure(str(e), _test_step_k) dc_setting_promise.resolve() # noinspection PyUnresolvedReferences power_meas = self.ps.measure(fresh=True).resolve() if dmx_promise is not None: # noinspection PyUnresolvedReferences dmx_promise.cancel() # noinspection PyUnresolvedReferences self.ps.write_settings(*initial_power_settings).resolve() percent_drop = last.percent_drop_from(first) cie_dist = last.distance_from(AttrDict(x=params.x_nom, y=params.y_nom)) obj = LightingStation3ResultRow( param_row_id=params.id, x=last.x, y=last.y, fcd=last.fcd, CCT=last.CCT, duv=last.duv, p=power_meas.P, pct_drop=percent_drop, cie_dist=cie_dist, cie_pf=cie_dist <= params.color_dist_max, light_measurements=light_measurements, fcd_pf=test_nom_tol(params.fcd_nom, params.fcd_tol, last.fcd), p_pf=test_nom_tol(params.p_nom, params.p_tol, power_meas.P), pct_drop_pf=percent_drop <= params.pct_drop_max, t=datetime.now(), ) obj.pf = obj.cie_pf and obj.fcd_pf and obj.p_pf and obj.pct_drop_pf self.emit(StepFinishMessage(k=_test_step_k, success=obj.pf)) return self.emit(obj)
def get_settings(self) -> DCLevel: return DCLevel(*self.read(self.__Command.GET_VALUES))
def read_settings(self) -> Tuple[DCLevel, bool]: return DCLevel(*self.read(self.__Command.GET_VALUES)), \ bool(self.read(self.__Command.GET_OUTPUT))
class BKPowerSupply(VISA, _DCPowerSupply): def calculate_knee(self, percent_of_max: float, num_steps: int, top: float, bottom: float, consumer: Callable[[DCKneeUpdate], None]) -> float: raise NotImplementedError # ? W:\Test Data Backup\test\doc\9200_Series_manual.pdf _config = configuration.from_yml(r'instruments\bk_power_supply.yml') display_name = _config.field(str) PATTERN = _config.field(str) MEASUREMENT_WAIT = _config.field(float) COMMAND_EXECUTION_TIMEOUT = _config.field(float) RAMP_STEPS: Tuple[DCLevel, ...] = ( DCLevel(24., 15.), DCLevel(26., 13.8), DCLevel(28., 12.9), DCLevel(30., 12.), DCLevel(32., 11.3), ) # noinspection SpellCheckingInspection class __Command: RESET = '*RST' SETUP = '*ESE 60;*SRE 48;*CLS' IS_DONE = '*OPC? ' SET_VALUES = 'APPL %.6f,%.6f' GET_VALUES = 'APPL?' SET_OUTPUT = 'OUTP %d' GET_OUTPUT = 'OUTP?' GET_VOLT = ':MEAS:VOLT?' GET_CURR = ':MEAS:CURR?' GET_POW = ':MEAS:POW?' next_meas = 0. def _instrument_check(self) -> None: self.read(self.__Command.GET_VOLT) def __command(self, packet: str) -> None: self.write(packet) command_timeout = self.COMMAND_EXECUTION_TIMEOUT + time() while command_timeout > time(): if self.read(self.__Command.IS_DONE): return raise BKPowerSupplyError(f'failed to confirm command {packet}') @proxy.exposed def send_reset(self): return self.__command(self.__Command.RESET) @register.after('_instrument_setup') def _bk_setup(self): self.__command(self.__Command.SETUP) self.next_meas = time() @register.after('_bk_setup') @register.before('_instrument_cleanup') def _bk_cleanup(self) -> None: self.write_settings(DCLevel(0., 0.), False) @proxy.exposed def read_settings(self) -> Tuple[DCLevel, bool]: return DCLevel(*self.read(self.__Command.GET_VALUES)), \ bool(self.read(self.__Command.GET_OUTPUT)) @proxy.exposed def set_settings(self, dc_level: DCLevel) -> None: self.__command(self.__Command.SET_VALUES % (dc_level.V, dc_level.A)) @proxy.exposed def get_settings(self) -> DCLevel: return DCLevel(*self.read(self.__Command.GET_VALUES)) @proxy.exposed def set_output(self, output_state: bool) -> None: self.__command(self.__Command.SET_OUTPUT % int(cast(bool, output_state))) @proxy.exposed def get_output(self) -> bool: return bool(self.read(self.__Command.GET_OUTPUT)) @proxy.exposed def write_settings(self, dc_level: DCLevel = None, output_state: bool = None): if dc_level is None and output_state is None: raise BKPowerSupplyError( 'must call .write_settings() with at least one arg') was_dc_level_correct = (dc_level is None) or (dc_level == self.get_settings()) if was_dc_level_correct: if dc_level is not None: self.info(f'power settings = {dc_level}') else: self.set_settings(dc_level) was_output_state_correct = ( output_state is None) or not (output_state ^ self.get_output()) if was_output_state_correct: if output_state is not None: self.info(f'output state = {output_state}') else: self.set_output(output_state) error_strings = [] if not was_dc_level_correct: if self.get_settings() != dc_level: error_strings.append(dc_level) else: self.info(f'power settings = {dc_level}') if not was_output_state_correct: if self.get_output() ^ cast(bool, output_state): error_strings.append(f'output_enable={output_state}') else: self.info(f'output state = {output_state}') if error_strings: raise BKPowerSupplyError(f'failed to set to ' + ', '.join(error_strings)) else: self.next_meas = time() + (self.MEASUREMENT_WAIT * 1.5) @proxy.exposed def measure(self, fresh: bool = True): """ note that, even though we send the measure command, rather than the fetch command, the BK appears to be responding with a buffered value updated every 220ms this method returns in ~15ms unless @fresh, in which case it waits for the value to have been updated """ if fresh: self._instrument_delay(self.next_meas - time()) self.next_meas = time() + self.MEASUREMENT_WAIT meas = DCLevel(*list( map(self.read, [self.__Command.GET_VOLT, self.__Command.GET_CURR]))) self.info(meas, f'fresh={fresh}') return meas @proxy.exposed def ramp_up(self): [ self.write_settings(step, output_state=True) for step in self.RAMP_STEPS ] @proxy.exposed def calculate_connection_state(self, calc): return _DCPowerSupply.calculate_connection_state(self, calc) @proxy.exposed def off(self): return _DCPowerSupply.off(self) def _instrument_debug(self) -> None: self.log_level(logging.DEBUG) self.calculate_connection_state(LightLineV1ConnectionState) self.ramp_up() self.measure(fresh=True) self.write_settings(DCLevel(0., 0.)) tf = time() + 5 while time() < tf: self.measure(fresh=True)
def off(self) -> None: return self.write_settings(DCLevel(0., 0.), False)