Example #1
0
 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)
Example #2
0
 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)
Example #3
0
 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)
Example #4
0
 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())
Example #5
0
 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
Example #6
0
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
Example #7
0
 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)
Example #8
0
 def set_power_supply_for_programming(self) -> None:
     self.bk.write_settings(DCLevel(self.PROGRAMMING_V, self.PROGRAMMING_I))
Example #9
0
 def _lambda_cleanup(self) -> None:
     self.write_settings(DCLevel(0., 0.), False)
Example #10
0
    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)
Example #11
0
 def get_settings(self) -> DCLevel:
     return DCLevel(*self.read(self.__Command.GET_VALUES))
Example #12
0
 def read_settings(self) -> Tuple[DCLevel, bool]:
     return DCLevel(*self.read(self.__Command.GET_VALUES)), \
            bool(self.read(self.__Command.GET_OUTPUT))
Example #13
0
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)
Example #14
0
 def off(self) -> None:
     return self.write_settings(DCLevel(0., 0.), False)