Beispiel #1
0
class EnergyMonitor(COMCUPluginBase, Ui_EnergyMonitor):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletEnergyMonitor, *args)

        self.setupUi(self)

        self.energy_monitor = self.device
        self.cbe_get_energy_data = CallbackEmulator(self.energy_monitor.get_energy_data,
                                                    None,
                                                    self.cb_energy_data,
                                                    self.increase_error_count)
        self.cbe_get_transformer_status = CallbackEmulator(self.energy_monitor.get_transformer_status,
                                                           None,
                                                           self.cb_transformer_status,
                                                           self.increase_error_count)

        plots_waveform_v = [('Waveform V', Qt.red, None, None)]
        self.plot_widget_waveform_v = PlotWidget('Voltage [V]', plots_waveform_v, clear_button=None, x_diff=768*ENERGY_MONITOR_MS_PER_TICK, x_scale_title_text='Time [ms]', key=None, x_scale_visible=False)

        plots_waveform_a = [('Waveform A', Qt.red, None, None)]
        self.plot_widget_waveform_a = PlotWidget('Current [A]', plots_waveform_a, clear_button=None, x_diff=768*ENERGY_MONITOR_MS_PER_TICK, x_scale_title_text='Time [ms]', key=None)

        self.plot_widget_waveform_v.add_y_scale_sibling(self.plot_widget_waveform_a)
        self.plot_widget_waveform_a.add_y_scale_sibling(self.plot_widget_waveform_v)

        # try to make the actual curve area equal in height by fiddling with the
        # minimum-height and the stretch factors
        self.plot_widget_waveform_v.setMinimumHeight(194)
        self.plot_widget_waveform_a.setMinimumHeight(250)
        self.layout_graph.insertWidget(0, self.plot_widget_waveform_v, 86)
        self.layout_graph.addWidget(self.plot_widget_waveform_a, 100)

        self.x_data = [x * ENERGY_MONITOR_MS_PER_TICK for x in list(range(768))]

        self.button_energy.clicked.connect(self.button_energy_clicked)
        self.button_transformer_settings.clicked.connect(self.button_transformer_settings_clicked)

        self.voltage_connected = True
        self.current_connected = True

        self.running = False

    def button_energy_clicked(self):
        self.energy_monitor.reset_energy()

    def button_transformer_settings_clicked(self):
        voltage_ratio = int(self.spinbox_voltage_ratio.value()*100)
        current_ratio = int(self.spinbox_current_ratio.value()*100)
        self.energy_monitor.set_transformer_calibration(voltage_ratio, current_ratio, 0)

    def cb_waveform_error(self):
        self.increase_error_count()

        if self.running:
            async_call(self.energy_monitor.get_waveform, None, self.cb_waveform, self.cb_waveform_error, delay=0.5)

    def cb_waveform(self, waveform):
        y_data_v = [x*0.1 for x in waveform[::2]]
        y_data_a = [x*0.01 for x in waveform[1::2]]
        self.plot_widget_waveform_v.set_data(0, self.x_data, y_data_v)
        self.plot_widget_waveform_a.set_data(0, self.x_data, y_data_a)

        if self.running:
            async_call(self.energy_monitor.get_waveform, None, self.cb_waveform, self.cb_waveform_error, delay=0.5)

    def cb_energy_data(self, data):
        if self.voltage_connected:
            self.label_voltage.setText('{0:.2f}'.format(data.voltage / 100))
        else:
            self.label_voltage.setText('NC')
        if self.current_connected:
            self.label_current.setText('{0:.2f}'.format(data.current / 100))
        else:
            self.label_current.setText('NC')

        self.label_energy.setText('{0:.2f}'.format(data.energy / 100))
        self.label_real_power.setText('{0:.2f}'.format(data.real_power / 100))
        self.label_apparent_power.setText('{0:.2f}'.format(data.apparent_power / 100))
        self.label_reactive_power.setText('{0:.2f}'.format(data.reactive_power / 100))
        self.label_power_factor.setText('{0:.2f}'.format((data.power_factor // 10) / 100))
        self.label_frequency.setText('{0:.2f}'.format(data.frequency / 100))

    def cb_transformer_status(self, status):
        self.voltage_connected = status.voltage_transformer_connected
        self.current_connected = status.current_transformer_connected

        if not self.voltage_connected:
            self.label_voltage.setText('NC')

        if not self.current_connected:
            self.label_current.setText('NC')

    def cb_transformer_calibration(self, cal):
        self.spinbox_voltage_ratio.setValue(cal.voltage_ratio/100.0)
        self.spinbox_current_ratio.setValue(cal.current_ratio/100.0)

    def start(self):
        self.running = True

        async_call(self.energy_monitor.get_transformer_calibration, None, self.cb_transformer_calibration, self.increase_error_count)
        async_call(self.energy_monitor.get_waveform, None, self.cb_waveform, self.cb_waveform_error)

        self.cbe_get_energy_data.set_period(200)
        self.cbe_get_transformer_status.set_period(200)

    def stop(self):
        self.running = False
        self.cbe_get_energy_data.set_period(0)
        self.cbe_get_transformer_status.set_period(0)

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletEnergyMonitor.DEVICE_IDENTIFIER
Beispiel #2
0
class SoundPressureLevel(COMCUPluginBase, Ui_SoundPressureLevel):
    qtcb_spectrum = pyqtSignal(object)

    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletSoundPressureLevel, *args)

        self.setupUi(self)

        self.sound_pressure_level = self.device
        self.cbe_get_decibel = CallbackEmulator(self,
                                                self.sound_pressure_level.get_decibel,
                                                None,
                                                self.cb_decibel,
                                                self.increase_error_count)

        self.qtcb_spectrum.connect(self.cb_spectrum)

        self.thermo = TuningThermo()

        plots_spectrum = [('Spectrum', Qt.red, None, '{} °C'.format)]
        self.plot_widget_spectrum = PlotWidget('Value [dB]', plots_spectrum, clear_button=None,
                                               x_diff=20480, x_scale_title_text='Frequency [Hz]',
                                               x_scale_skip_last_tick=False, key=None, y_resolution=0.1,
                                               y_scale_shrinkable=False)
        self.plot_widget_spectrum.set_x_scale(512*40//5, 1)

        self.combo_fft_size.currentIndexChanged.connect(self.config_changed)
        self.combo_weighting.currentIndexChanged.connect(self.config_changed)

        self.layout_graph.addWidget(self.plot_widget_spectrum)
        self.layout_decibel.insertWidget(3, self.thermo)

        self.last_spectrum_length = 512

        self.last_y_data = [0]*512

    def get_spectrum_decrement(self):
        index = self.combo_fft_size.currentIndex()

        if index == 0:
            return 0.5
        elif index == 1:
            return 1
        elif index == 2:
            return 2
        elif index == 3:
            return 4

    def config_changed(self, _):
        self.last_y_data = [0]*512
        self.sound_pressure_level.set_configuration(self.combo_fft_size.currentIndex(), self.combo_weighting.currentIndex())

    def cb_decibel(self, db):
        self.label_decibel.setText("{:.1f}".format(db/10.0))
        self.thermo.set_value(db)

    def cb_spectrum(self, spectrum):
        try:
            length = len(spectrum)
        except:
            return

        if length == 0:
            return

        num = 20480 // length

        x_data = list(range(0, num * length, num))
        y_data = list(map(lambda x: 20 * math.log10(max(1, x / math.sqrt(2))), spectrum))

        if self.checkbox_decay.isChecked():
            for i in range(len(y_data)):
                if y_data[i] > self.last_y_data[i]:
                    self.last_y_data[i] = y_data[i]
                else:
                    self.last_y_data[i] -= self.get_spectrum_decrement()

                    if y_data[i] > self.last_y_data[i]:
                        self.last_y_data[i] = y_data[i]

            self.plot_widget_spectrum.set_data(0, x_data, self.last_y_data)
        else:
            self.plot_widget_spectrum.set_data(0, x_data, y_data)

    def get_configuration_async(self, config):
        self.combo_fft_size.blockSignals(True)
        self.combo_fft_size.setCurrentIndex(config.fft_size)
        self.combo_fft_size.blockSignals(False)

        self.combo_weighting.blockSignals(True)
        self.combo_weighting.setCurrentIndex(config.weighting)
        self.combo_weighting.blockSignals(False)

    def start(self):
        self.sound_pressure_level.register_callback(self.sound_pressure_level.CALLBACK_SPECTRUM, self.qtcb_spectrum.emit)

        async_call(self.sound_pressure_level.get_configuration, None, self.get_configuration_async, self.increase_error_count)
        async_call(self.sound_pressure_level.set_spectrum_callback_configuration, 1, None, self.increase_error_count)

        self.cbe_get_decibel.set_period(50)

    def stop(self):
        self.sound_pressure_level.register_callback(self.sound_pressure_level.CALLBACK_SPECTRUM, None)

        async_call(self.sound_pressure_level.set_spectrum_callback_configuration, 0, None, self.increase_error_count)

        self.cbe_get_decibel.set_period(0)

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletSoundPressureLevel.DEVICE_IDENTIFIER
Beispiel #3
0
class EnergyMonitor(COMCUPluginBase, Ui_EnergyMonitor):
    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletEnergyMonitor, *args)

        self.setupUi(self)

        self.energy_monitor = self.device
        self.cbe_get_energy_data = CallbackEmulator(self,
                                                    self.energy_monitor.get_energy_data,
                                                    None,
                                                    self.cb_energy_data,
                                                    self.increase_error_count)
        self.cbe_get_transformer_status = CallbackEmulator(self,
                                                           self.energy_monitor.get_transformer_status,
                                                           None,
                                                           self.cb_transformer_status,
                                                           self.increase_error_count)

        plots_waveform_v = [('Waveform V', Qt.red, None, None)]
        self.plot_widget_waveform_v = PlotWidget('Voltage [V]', plots_waveform_v, clear_button=None, x_diff=768*ENERGY_MONITOR_MS_PER_TICK, x_scale_title_text='Time [ms]', key=None, x_scale_visible=False)

        plots_waveform_a = [('Waveform A', Qt.red, None, None)]
        self.plot_widget_waveform_a = PlotWidget('Current [A]', plots_waveform_a, clear_button=None, x_diff=768*ENERGY_MONITOR_MS_PER_TICK, x_scale_title_text='Time [ms]', key=None)

        self.plot_widget_waveform_v.add_y_scale_sibling(self.plot_widget_waveform_a)
        self.plot_widget_waveform_a.add_y_scale_sibling(self.plot_widget_waveform_v)

        # try to make the actual curve area equal in height by fiddling with the
        # minimum-height and the stretch factors
        self.plot_widget_waveform_v.setMinimumHeight(194)
        self.plot_widget_waveform_a.setMinimumHeight(250)
        self.layout_graph.insertWidget(0, self.plot_widget_waveform_v, 86)
        self.layout_graph.addWidget(self.plot_widget_waveform_a, 100)

        self.x_data = [x * ENERGY_MONITOR_MS_PER_TICK for x in list(range(768))]

        self.button_energy.clicked.connect(self.button_energy_clicked)
        self.button_transformer_settings.clicked.connect(self.button_transformer_settings_clicked)

        self.voltage_connected = True
        self.current_connected = True

        self.running = False

    def button_energy_clicked(self):
        self.energy_monitor.reset_energy()

    def button_transformer_settings_clicked(self):
        voltage_ratio = int(self.spinbox_voltage_ratio.value()*100)
        current_ratio = int(self.spinbox_current_ratio.value()*100)
        self.energy_monitor.set_transformer_calibration(voltage_ratio, current_ratio, 0)

    def cb_waveform_error(self):
        self.increase_error_count()

        if self.running:
            async_call(self.energy_monitor.get_waveform, None, self.cb_waveform, self.cb_waveform_error, delay=0.5)

    def cb_waveform(self, waveform):
        y_data_v = [x*0.1 for x in waveform[::2]]
        y_data_a = [x*0.01 for x in waveform[1::2]]
        self.plot_widget_waveform_v.set_data(0, self.x_data, y_data_v)
        self.plot_widget_waveform_a.set_data(0, self.x_data, y_data_a)

        if self.running:
            async_call(self.energy_monitor.get_waveform, None, self.cb_waveform, self.cb_waveform_error, delay=0.5)

    def cb_energy_data(self, data):
        if self.voltage_connected:
            if self.label_voltage.text() == NOT_CONNECTED:
                self.label_voltage.maximum_size_hint = None

            self.label_voltage.setText('{0:.2f}'.format(data.voltage / 100))
        else:
            self.label_voltage.setText(NOT_CONNECTED)

        if self.current_connected:
            if self.label_current.text() == NOT_CONNECTED:
                self.label_current.maximum_size_hint = None

            self.label_current.setText('{0:.2f}'.format(data.current / 100))
        else:
            self.label_current.setText(NOT_CONNECTED)

        self.label_energy.setText('{0:.2f}'.format(data.energy / 100))
        self.label_real_power.setText('{0:.2f}'.format(data.real_power / 100))
        self.label_apparent_power.setText('{0:.2f}'.format(data.apparent_power / 100))
        self.label_reactive_power.setText('{0:.2f}'.format(data.reactive_power / 100))
        self.label_power_factor.setText('{0:.2f}'.format((data.power_factor // 10) / 100))
        self.label_frequency.setText('{0:.2f}'.format(data.frequency / 100))

    def cb_transformer_status(self, status):
        self.voltage_connected = status.voltage_transformer_connected
        self.current_connected = status.current_transformer_connected

        if not self.voltage_connected:
            self.label_voltage.setText(NOT_CONNECTED)

        if not self.current_connected:
            self.label_current.setText(NOT_CONNECTED)

    def cb_transformer_calibration(self, cal):
        self.spinbox_voltage_ratio.setValue(cal.voltage_ratio/100.0)
        self.spinbox_current_ratio.setValue(cal.current_ratio/100.0)

    def start(self):
        self.running = True

        async_call(self.energy_monitor.get_transformer_calibration, None, self.cb_transformer_calibration, self.increase_error_count)
        async_call(self.energy_monitor.get_waveform, None, self.cb_waveform, self.cb_waveform_error)

        self.cbe_get_energy_data.set_period(200)
        self.cbe_get_transformer_status.set_period(200)

    def stop(self):
        self.running = False
        self.cbe_get_energy_data.set_period(0)
        self.cbe_get_transformer_status.set_period(0)

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletEnergyMonitor.DEVICE_IDENTIFIER
class SoundPressureLevel(COMCUPluginBase, Ui_SoundPressureLevel):
    qtcb_spectrum = pyqtSignal(object)

    def __init__(self, *args):
        COMCUPluginBase.__init__(self, BrickletSoundPressureLevel, *args)

        self.setupUi(self)

        self.sound_pressure_level = self.device
        self.cbe_get_decibel = CallbackEmulator(self.sound_pressure_level.get_decibel,
                                                None,
                                                self.cb_decibel,
                                                self.increase_error_count)

        self.qtcb_spectrum.connect(self.cb_spectrum)

        self.thermo = TuningThermo()

        plots_spectrum = [('Spectrum', Qt.red, None, '{} °C'.format)]
        self.plot_widget_spectrum = PlotWidget('Value [dB]', plots_spectrum, clear_button=None,
                                               x_diff=20480, x_scale_title_text='Frequency [Hz]',
                                               x_scale_skip_last_tick=False, key=None, y_resolution=0.1,
                                               y_scale_shrinkable=False)
        self.plot_widget_spectrum.set_x_scale(512*40//5, 1)

        self.combo_fft_size.currentIndexChanged.connect(self.config_changed)
        self.combo_weighting.currentIndexChanged.connect(self.config_changed)

        self.layout_graph.addWidget(self.plot_widget_spectrum)
        self.layout_decibel.insertWidget(3, self.thermo)

        self.last_spectrum_length = 512

        self.last_y_data = [0]*512

    def get_spectrum_decrement(self):
        index = self.combo_fft_size.currentIndex()

        if index == 0:
            return 0.5
        elif index == 1:
            return 1
        elif index == 2:
            return 2
        elif index == 3:
            return 4

    def config_changed(self, _):
        self.last_y_data = [0]*512
        self.sound_pressure_level.set_configuration(self.combo_fft_size.currentIndex(), self.combo_weighting.currentIndex())

    def cb_decibel(self, db):
        self.label_decibel.setText("{:.1f}".format(db/10.0))
        self.thermo.set_value(db)

    def cb_spectrum(self, spectrum):
        length = len(spectrum)
        num = 20480 // length

        x_data = list(range(0, num * length, num))
        y_data = list(map(lambda x: 20 * math.log10(max(1, x / math.sqrt(2))), spectrum))

        if self.checkbox_decay.isChecked():
            for i in range(len(y_data)):
                if y_data[i] > self.last_y_data[i]:
                    self.last_y_data[i] = y_data[i]
                else:
                    self.last_y_data[i] -= self.get_spectrum_decrement()

                    if y_data[i] > self.last_y_data[i]:
                        self.last_y_data[i] = y_data[i]

            self.plot_widget_spectrum.set_data(0, x_data, self.last_y_data)
        else:
            self.plot_widget_spectrum.set_data(0, x_data, y_data)

    def get_configuration_async(self, config):
        self.combo_fft_size.blockSignals(True)
        self.combo_fft_size.setCurrentIndex(config.fft_size)
        self.combo_fft_size.blockSignals(False)

        self.combo_weighting.blockSignals(True)
        self.combo_weighting.setCurrentIndex(config.weighting)
        self.combo_weighting.blockSignals(False)

    def start(self):
        self.sound_pressure_level.register_callback(self.sound_pressure_level.CALLBACK_SPECTRUM, self.qtcb_spectrum.emit)

        async_call(self.sound_pressure_level.get_configuration, None, self.get_configuration_async, self.increase_error_count)
        async_call(self.sound_pressure_level.set_spectrum_callback_configuration, 1, None, self.increase_error_count)

        self.cbe_get_decibel.set_period(50)

    def stop(self):
        self.sound_pressure_level.register_callback(self.sound_pressure_level.CALLBACK_SPECTRUM, None)

        async_call(self.sound_pressure_level.set_spectrum_callback_configuration, 0, None, self.increase_error_count)

        self.cbe_get_decibel.set_period(0)

    def destroy(self):
        pass

    @staticmethod
    def has_device_identifier(device_identifier):
        return device_identifier == BrickletSoundPressureLevel.DEVICE_IDENTIFIER