示例#1
0
    def create_channels(self):
        """
        This method invokes `create_channels` from the super classes and adds
        the `state_open_channel` and `state_close_channel` to the widget along
        with a reset for the state and interlock_connected variables.
        """
        super(OpenCloseStateMixin, self).create_channels()
        if not self._open_suffix or not self._close_suffix:
            return

        self._open_connected = False
        self._close_connected = False
        self._state_open = False
        self._state_close = False
        self._state = "INVALID"

        self.state_open_channel = PyDMChannel(
            address="{}{}".format(self._channels_prefix, self._open_suffix),
            connection_slot=partial(self.state_connection_changed, "OPEN"),
            value_slot=partial(self.state_value_changed, "OPEN"))
        self.state_open_channel.connect()

        self.state_close_channel = PyDMChannel(
            address="{}{}".format(self._channels_prefix, self._close_suffix),
            connection_slot=partial(self.state_connection_changed, "CLOSE"),
            value_slot=partial(self.state_value_changed, "CLOSE"))
        self.state_close_channel.connect()
示例#2
0
文件: led.py 项目: lnls-sirius/hla
    def set_channels(self, new_channels):
        if not new_channels:
            self.setEnabled(False)
        else:
            self.setEnabled(True)

        # Check which channel can be removed
        address2pop = list()
        for address in self._address2channel.keys():
            if address not in new_channels:
                address2pop.append(address)
            else:
                new_channels.remove(address)

        # Remove channels
        for address in address2pop:
            self._address2channel[address].disconnect()
            self._address2channel.pop(address)
            self._address2conn.pop(address)

        # Add new channels
        for address in new_channels:
            self._address2conn[address] = False
            channel = PyDMChannel(address=address,
                                  connection_slot=self.connection_changed)
            channel.connect()
            self._address2channel[address] = channel

        self._channels = list(self._address2channel.values())

        self._update_state()
示例#3
0
 def __init__(self, channel=None, *args, **kwargs):
     super(VisibilityEmbedded, self).__init__(*args, **kwargs)
     self.setVisible(False)
     self._connected = None
     self.channel = None
     if channel:
         self.channel = PyDMChannel(channel,
                                    connection_slot=self.connection_changed)
     self.destroyed.connect(functools.partial(clear_channel, channel))
示例#4
0
    def __init__(self, parent=None, macros=None, **kwargs):
        super().__init__(parent=parent, macros=macros, ui_filename=COMPLETE_UI)
        self.setup_icons()

        self.btnErr.filenames = [ERR_MAIN]
        self.btnWarn.filenames = [WARN_MAIN]

        self.btnSysHistory.filenames = [ALARM_MAIN]
        self.btnSysHistory.base_macros = {'P': macros['P'], 'T': 'Sys'}
        self.btnModHistory.filenames = [ALARM_MAIN]
        self.btnModHistory.base_macros = {'P': macros['P'], 'T': 'Mod'}

        # Warning Groups
        self.ch_mod_std_warn_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Mod-StdWarnGroup-Mon',
            value_slot=self.get_mod_std_warn_report)
        self.ch_mod_std_warn_report.connect()

        self.ch_sys_std_warn_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Sys-StdWarnGroup-Mon',
            value_slot=self.get_sys_std_warn_report)
        self.ch_sys_std_warn_report.connect()

        self.ch_mod_ext_warn_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Mod-ExtWarnGroup-Mon',
            value_slot=self.get_mod_ext_warn_report)
        self.ch_mod_ext_warn_report.connect()

        self.ch_sys_ext_warn_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Sys-ExtWarnGroup-Mon',
            value_slot=self.get_sys_ext_warn_report)
        self.ch_sys_ext_warn_report.connect()

        # Error Groups
        self.ch_mod_std_error_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Mod-StdErrGroup-Mon',
            value_slot=self.get_mod_std_error_report)
        self.ch_mod_std_error_report.connect()

        self.ch_sys_std_error_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Sys-StdErrGroup-Mon',
            value_slot=self.get_sys_std_error_report)
        self.ch_sys_std_error_report.connect()

        self.ch_mod_ext_error_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Mod-ExtErrGroup-Mon',
            value_slot=self.get_mod_ext_error_report)
        self.ch_mod_std_error_report.connect()

        self.ch_sys_ext_error_report = PyDMChannel(
            address='ca://' + macros['P'] + ':Sys-ExtErrGroup-Mon',
            value_slot=self.get_sys_ext_error_report)
        self.ch_sys_ext_error_report.connect()
示例#5
0
    def setup_energy_range_channel(self):
        prefix = self.config.get('line_arbiter_prefix')

        ch_macros = dict(PREFIX=prefix)
        ch = Template(
            'ca://${PREFIX}BeamParamCntl:ReqBP:PhotonEnergyRanges').safe_substitute(**ch_macros)
        self.energy_channel = PyDMChannel(
            ch,
            value_slot=self.energy_range_changed,
            value_signal=self.energy_range_signal
        )
        self.energy_channel.connect()
示例#6
0
 def channels(self):
     """Define slots and signals mappings for the epics channel."""
     if self._channels is None:
         self._channels = [
             PyDMChannel(
                 address=self.channel,
                 connection_slot=lambda conn: self.connectionChanged(conn),
                 value_slot=lambda val: self.valueChanged(val))
         ]
         # waveform_slot=lambda wvfrm: self.waveformChanged(wvfrm),
         # count_slot=lambda count: self.countChanged(count))]
     return self._channels
示例#7
0
    def __init__(self, parent=None, macros=None, **kwargs):
        super().__init__(parent=parent, macros=macros, ui_filename=TREE_32_UI)

        self.isSystem = macros.get("D", "Sys") == "Sys"
        self.isWarn = macros.get("T", "Warn") == "Warn"

        # Warning Groups
        self.ch_mod_warn_report = PyDMChannel(
            address="ca://" + macros["P"] + ":ModWarnGroup-Mon",
            value_slot=self.get_mod_warn_report,
        )

        self.ch_sys_warn_report = PyDMChannel(
            address="ca://" + macros["P"] + ":SysWarnGroup-Mon",
            value_slot=self.get_sys_warn_report,
        )

        # Error Groups
        self.ch_mod_error_report = PyDMChannel(
            address="ca://" + macros["P"] + ":ModErrGroup-Mon",
            value_slot=self.get_mod_error_report,
        )

        self.ch_sys_error_report = PyDMChannel(
            address="ca://" + macros["P"] + ":SysErrGroup-Mon",
            value_slot=self.get_sys_error_report,
        )

        if self.isSystem:
            if self.isWarn:
                self.ch_sys_warn_report.connect()
            else:
                self.ch_sys_error_report.connect()
        else:
            if self.isWarn:
                self.ch_mod_warn_report.connect()
            else:
                self.ch_mod_error_report.connect()
示例#8
0
 def connect_data(self):
     """
     Responsible for the steps required for processing live data. This includes creating 
     and connecting to the PyDM channel, and showing the proper UI widgets. 
     """
     if (self.macro_dict is not None) and ("DEVICE" in self.macro_dict):
         self.epics = PyDMChannel(
             address="ca://" + self.macro_dict["DEVICE"] +
             ":ARR1:ArrayData",
             value_slot=self.live_data,
             connection_slot=self.connect_data_settings)
         self.epics.connect()
     self.show_exposure()
     return
示例#9
0
    def _setup_channels(self):
        if not self._prefix or not self._segment:
            return

        for entry, pv_format in UndulatorWidget.CHANNELS.items():
            pv = pv_format.format(prefix=self.prefix, segment=self.segment)
            conn_cb = functools.partial(self.conn_cb, entry)
            val_cb = functools.partial(self.value_cb, entry)
            ch = PyDMChannel(pv, value_slot=val_cb, connection_slot=conn_cb)
            self._channels[entry] = ch
            self._values[entry] = None
            self._connections[entry] = False

        for _, ch in self._channels.items():
            ch.connect()
示例#10
0
 def _link_moving(self, signal, widget):
     """Link the positioner moving indicator with the ui element."""
     if signal is None:
         widget.hide()
         return False
     widget.show()
     # Additional handling for updating self.moving
     if self._moving_channel is not None:
         self._moving_channel.disconnect()
     chname = utils.channel_from_signal(signal)
     self._moving_channel = PyDMChannel(
         address=chname,
         value_slot=self._set_moving,
     )
     self._moving_channel.connect()
     return True
示例#11
0
文件: led.py 项目: lnls-sirius/hla
    def set_channels2values(self, new_channels2values):
        """Set channels2values."""
        self._address2values = _dcopy(new_channels2values)

        if not new_channels2values:
            self.setEnabled(False)
        else:
            self.setEnabled(True)

        # Check which channel can be removed
        address2pop = list()
        for address in self._address2channel.keys():
            if address not in new_channels2values.keys():
                address2pop.append(address)

        # Remove channels
        for address in address2pop:
            self._address2channel[address].disconnect()
            self._address2channel.pop(address)
            self._address2status.pop(address)
            self._address2conn.pop(address)
            self._address2currvals.pop(address)

        # Add new channels
        for address, value in new_channels2values.items():
            if address not in self._address2channel.keys():
                self._address2conn[address] = False
                self._address2status[address] = 'UNDEF'
                self._address2currvals[address] = 'UNDEF'
                channel = PyDMChannel(address=address,
                                      connection_slot=self.connection_changed,
                                      value_slot=self.value_changed)
                channel.connect()
                self._address2channel[address] = channel
            self._address2values[address] = value

        self._channels = list(self._address2channel.values())

        # redo comparisions
        for ad, des in self._address2values.items():
            self._address2status[ad] = self._check_status(
                ad, des, self._address2currvals[ad])

        self._update_statuses()
示例#12
0
    def setup_alarm_config(self, device):
        """
        Add a device to the alarm summary.

        This will pick PVs based on the device kind and the configured kind
        level, configuring the PyDMChannels to update our alarm state and
        color when we get updates from our PVs.
        """
        sigs = get_all_signals_from_device(
            device, filter_by=KIND_FILTERS[self._kind_level])
        channel_addrs = [channel_from_signal(sig) for sig in sigs]
        for sig in sigs:
            if not isinstance(sig, EpicsSignalBase):
                register_signal(sig)
        channels = [
            PyDMChannel(
                address=addr,
                connection_slot=partial(self.update_connection, addr=addr),
                severity_slot=partial(self.update_severity, addr=addr),
            ) for addr in channel_addrs
        ]

        for ch, sig in zip(channels, sigs):
            info = SignalInfo(
                address=ch.address,
                channel=ch,
                signal_name=sig.dotted_name,
                connected=False,
                severity=AlarmLevel.INVALID,
            )
            self.signal_info[ch.address] = info
            self.device_info[device.name].append(info)
            ch.connect()

        all_channels = self.channels()
        if all_channels:
            logger.debug(
                f'Finished setup of alarm config for device {device.name} on '
                f'alarm widget with channel {all_channels[0]}.')
        else:
            logger.warning(
                f'Tried to set up alarm config for device {device.name}, but '
                'did not configure any channels! Check your kindLevel!')
示例#13
0
    def _setup_channels(self):
        if not self._prefix:
            return

        pvs = {
            'first': 'ca://{prefix}PE:UND:FirstSegment_RBV',
            'last': 'ca://{prefix}PE:UND:LastSegment_RBV'
        }

        for entry, pv_format in pvs.items():
            pv = pv_format.format(prefix=self.prefix)
            conn_cb = functools.partial(self.conn_cb, entry)
            val_cb = functools.partial(self.value_cb, entry == 'first')
            ch = PyDMChannel(pv, value_slot=val_cb, connection_slot=conn_cb)
            self._channels[entry] = ch
            self._connections[entry] = False

        for _, ch in self._channels.items():
            ch.connect()
示例#14
0
 def __init__(self,
              store_type,
              data_type,
              default,
              channel=None,
              parent=None):
     super().__init__(parent)
     self.store_type = store_type
     self.data_type = data_type
     self.setText(str(default))
     self.channel = channel
     self.connected = False
     if channel is not None:
         self.pydm_channel = PyDMChannel(
             channel,
             value_slot=self.update_value,
             connection_slot=self.update_connection,
         )
         self.pydm_channel.connect()
示例#15
0
    def create_channels(self):
        """
        This method invokes `create_channels` from the super classes and adds
        the `state_channel` to the widget along with a reset for the
        state and state_connected variables.
        """
        super(StateMixin, self).create_channels()
        if not self._state_suffix:
            return

        self._state_connected = False
        self._state = ""

        self.state_channel = PyDMChannel(
            address="{}{}".format(self._channels_prefix, self._state_suffix),
            connection_slot=self.state_connection_changed,
            value_slot=self.state_value_changed,
            enum_strings_slot=self.state_enum_changed)
        self.state_channel.connect()
示例#16
0
    def create_channels(self):
        """
        This method invokes `create_channels` from the super classes and adds
        the `interlock_channel` to the widget along with a reset for the
        interlocked and interlock_connected variables.
        """
        super(InterlockMixin, self).create_channels()
        if not self._interlock_suffix:
            return

        self._interlocked = True
        self._interlock_connected = False

        self.interlock_channel = PyDMChannel(
            address="{}{}".format(self._channels_prefix,
                                  self._interlock_suffix),
            connection_slot=self.interlock_connection_changed,
            value_slot=self.interlock_value_changed)
        self.interlock_channel.connect()
示例#17
0
    def yAxisChannel(self, value):
        """
        The channel address in use for the time axis.

        Parameters
        ----------
        value : str
            Channel address
        """
        if self._yaxischannel != value:
            # Disconnect old channel
            if self._yaxischannel:
                self._yaxischannel.disconnect()
            # Create and connect new channel
            self._yaxischannel = PyDMChannel(
                address=value,
                connection_slot=self.yaxis_connection_state_changed,
                value_slot=self.yaxis_value_changed,
                severity_slot=self.alarmSeverityChanged)
            self._channels[2] = self._yaxischannel
            self._yaxischannel.connect()
示例#18
0
    def xAxisChannel(self, value):
        """
        The channel address in use for the x-axis of image.

        Parameters
        ----------
        value : str
            Channel address
        """
        if self._xaxischannel != value:
            # Disconnect old channel
            if self._xaxischannel:
                self._xaxischannel.disconnect()
            # Create and connect new channel
            self._xaxischannel = PyDMChannel(
                address=value,
                connection_slot=self.connectionStateChanged,
                value_slot=self.xaxis_value_changed,
                severity_slot=self.alarmSeverityChanged)
            self._channels[1] = self._xaxischannel
            self._xaxischannel.connect()
示例#19
0
    def imageChannel(self, value):
        """
        The channel address in use for the image data .

        Parameters
        ----------
        value : str
            Channel address
        """
        if self._imagechannel != value:
            # Disconnect old channel
            if self._imagechannel:
                self._imagechannel.disconnect()
            # Create and connect new channel
            self._imagechannel = PyDMChannel(
                address=value,
                connection_slot=self.image_connection_state_changed,
                value_slot=self.image_value_changed,
                severity_slot=self.alarmSeverityChanged)
            self._channels[0] = self._imagechannel
            self._imagechannel.connect()
示例#20
0
    def ROIHeightChannel(self, value):
        """
        Return the channel address in use for the image ROI height.

        Parameters
        ----------
        value : str
            Channel address

        """
        if self._roiheightchannel != value:
            # Disconnect old channel
            if self._roiheightchannel:
                self._roiheightchannel.disconnect()
            # Create and connect new channel
            self._roiheightchannel = PyDMChannel(
                address=value,
                connection_slot=self.roiheight_connection_state_changed,
                value_slot=self.roiheight_value_changed,
                severity_slot=self.alarmSeverityChanged)
            self._channels[6] = self._roiheightchannel
            self._roiheightchannel.connect()
示例#21
0
 def __init__(self,
              header: str,
              default: Optional[Any] = None,
              channel: Optional[str] = None,
              deadband: float = 0.0,
              parent: Optional[QtWidgets.QWidget] = None):
     super().__init__(parent)
     self.header = header
     self.update_value(default)
     self.channel = channel
     self.deadband = deadband
     if channel is None:
         self.update_connection(True)
         self.pydm_channel = None
     else:
         self.update_connection(False)
         self.pydm_channel = PyDMChannel(
             channel,
             value_slot=self.update_value,
             connection_slot=self.update_connection,
         )
         self.pydm_channel.connect()
示例#22
0
 def channel(self, value):
     if self._channel != value:
         # Remove old connection
         if self._channels:
             for channel in self._channels:
                 if hasattr(channel, 'disconnect'):
                     channel.disconnect()
                 if channel in self.signal_info:
                     del self.signal_info[channel]
             self._channels.clear()
         # Load new channel
         self._channel = str(value)
         if 'happi://' in self._channel:
             channel = HappiChannel(
                 address=self._channel,
                 tx_slot=self._tx,
             )
         else:
             channel = PyDMChannel(
                 address=self._channel,
                 connection_slot=partial(self.update_connection,
                                         addr=self._channel),
                 severity_slot=partial(self.update_severity,
                                       addr=self._channel),
             )
             self.signal_info[self._channel] = SignalInfo(
                 address=self._channel,
                 channel=channel,
                 signal_name='',
                 connected=False,
                 severity=AlarmLevel.INVALID,
             )
         self._channels = [channel]
         # Connect the channel to the HappiPlugin
         if hasattr(channel, 'connect'):
             channel.connect()
示例#23
0
 def channels(self):
     return [
         PyDMChannel(address=self.image_channel,
                     waveform_slot=self.new_image_received)
     ]
示例#24
0
 def channels(self):
     """Used by PyDmApplication to set the model channel."""
     if isinstance(self.model, PyDMBarGraphModel):
         return self.model.channels()
     return [PyDMChannel()]
示例#25
0
    def __init__(self, parent=None, args=None, macros=None):
        super(
            MCADisplay,
            self).__init__(
            parent=parent,
            args=args,
            macros=macros)
        # Debug Logger
        self.logger = logging.getLogger('mca_logger')
        self.separator = "\n" + ("-" * 20) + "\n"

        self.num_ROI = 9
        self.ROI = []
        self.start = []
        self.end = []
        self.counts = []
        self.lines = []
        self.set_ROI_widgets()
        cli_args = self.parse_args(args)

        self.energy, self.element = build_dic(cli_args)

        self.waveform.plotItem.scene().sigMouseMoved.connect(self.mouse_moved)
        self.waveform.setXLabels(["Energy (eV)"])
        self.waveform.setYLabels(["Count"])

        # Add Channels
        self.waveform.addChannel(None, None, name="Full", color="white")
        color_list = ["red", "green", "blue"]
        for wave in range(self.num_ROI):
            name = f"ROI{wave+1}"
            color = color_list[wave % len(color_list)]
            self.waveform.addChannel(
                None, None, name=name, color=color, lineWidth=2)

        # TODO: Is 18 just double the number of ROI's?
        for wave in range(18):
            name = f"Line{wave+1:02d}"
            self.waveform.addChannel(
                None,
                None,
                name=name,
                color="white",
                lineWidth=2,
                lineStyle=Qt.DashLine)

        self.curve = self.waveform._curves[0]
        self.croi = self.waveform._curves[1:10]
        self.line = self.waveform._curves[10:28]

        if (macros is not None) and ("FIT" in macros):
            if (macros["FIT"].lower() == "cauchy"):
                self.fitc = "Cauchy"
            else:
                self.fitc = "Gaussian"
        else:
            self.fitc = "Gaussian"

        if (macros is not None) and ("DEVICE" in macros):
            self.dataSource.addItem("Live EPICS")

            # TODO: Other file uses macros["DEVICE"]+":RAW:ArrayData"
            epics = PyDMChannel(address="ca://" +
                                macros["DEVICE"] + ":ARR1:ArrayData",
                                value_slot=self.live_data)
            epics.connect()

            self.show_exposure()
        else:
            self.show_mca()

        self.dataSource.addItem("Playback")
        self.dataSource.setCurrentIndex(0)
        self.dataSource.currentIndexChanged.connect(self.change_source)

        self.openFile   .clicked           .connect(self.open_file)
        self.previousMCA.clicked           .connect(self.previous_mca)
        self.nextMCA    .clicked           .connect(self.next_mca)
        self.fullView   .clicked           .connect(self.full_view)

        self.previousMCA.setEnabled(False)
        self.nextMCA    .setEnabled(False)

        self.record = []
        self.record_i = 0
示例#26
0
    def sector_change_connect(self):
        self.tab = TAB[self.tabWidget.currentIndex()]
        self.sector_change_disconnect()

        channels = []
        self.board_sensors = {}

        logger.info("Area {}; Sector {}".format(self.tab, self.sector.value()))

        try:
            info_request = requests.get(
                self.url, verify=False, params={"type": "mbtemp"}, timeout=5
            )
        except Exception:
            QtWidgets.QMessageBox.warning(
                self, "Warning", "Impossible connect to {}".format(self.url)
            )
            logger.warning("Impossible connect to {}".format(self.url))
            sys.exit()
        dev = info_request.json()

        if self.tab in ["RF", "TB", "TS", "LA", "PA"]:
            self.sector.setEnabled(False)

        elif self.tab == "BO":
            self.sector.setSingleStep(2)
            self.sector.setEnabled(True)
            self.sector.setMaximum(19)

            if self.sector.value() % 2 == 0:
                self.sector.setValue(1)

            sectorFrom = 2 + (self.sector.value() // 2) * 5
            sectorTo = 7 + (self.sector.value() // 2) * 5

            for x, y in enumerate(range(sectorFrom, sectorTo)):
                if y != 51:
                    getattr(self, "BO_Sec_{}".format(x + 1)).setText(
                        "Booster Sector: {}".format(y)
                    )
                else:
                    self.BO_Sec_5.setText("Booster Sector: 1")
            self.setBOImage(sectorFrom)
        else:
            self.sector.setSingleStep(1)
            self.sector.setEnabled(True)
            self.sector.setMaximum(20)

        for ip in DEVICES_IP[self.tab]:  # dict -> {MBTemp:[CH1,CH2...]}
            for board in dev[ip[0].format(self.sector.value())][ip[1][0] : ip[1][1]]:
                for enabled in range(1, 9):
                    channels.append(board["channels"]["CH{}".format(enabled)]["prefix"])
                self.board_sensors[board["prefix"]] = channels
                channels = []

        for mbtemp in self.board_sensors:
            for coef in ["Alpha", "LinearCoef-Mon", "AngularCoef-Mon"]:
                slot = partial(
                    self.update_mbtemp,
                    pvname=mbtemp,
                    coef=coef,
                    sector=self.sector.value(),
                )
                mb = PyDMChannel(
                    address="ca://{}:{}".format(mbtemp, coef),
                    value_slot=slot,
                    connection_slot=slot,
                )
                self.addr.append(mb)
                mb.connect()

            for number, pv in enumerate(self.board_sensors[mbtemp]):
                slot = partial(
                    self.update_channel,
                    name_pv=pv,
                    mbtemp_name=mbtemp,
                    mbtemp_ch=number + 1,
                )
                temp = PyDMChannel(
                    address="ca://" + pv, value_slot=slot, connection_slot=slot
                )
                self.addr.append(temp)
                temp.connect()
示例#27
0
    def setup_plc_ioc_status(self):
        ffs = self.config.get('fastfaults')
        if not ffs:
            return
        if self.plc_ioc_container is None:
            return

        for ff in ffs:
            prefix = ff.get('prefix')
            ffo_start = ff.get('ffo_start')
            ffo_end = ff.get('ffo_end')
            ff_start = ff.get('ff_start')
            ff_end = ff.get('ff_end')

            ffos_zfill = len(str(ffo_end)) + 1
            ffs_zfill = len(str(ff_end)) + 1
            entries = itertools.product(range(ffo_start, ffo_end + 1),
                                        range(ff_start, ff_end + 1))

            plc_name = prefix.strip(':')
            plc_macros = dict(P=prefix)
            # get the heartbeat of the IOC to
            ico_heart_ch = Template('ca://${P}HEARTBEAT').safe_substitute(
                **plc_macros)
            # the get PLC process cycle count
            plc_task_info_1 = Template(
                'ca://${P}TaskInfo:1:CycleCount').safe_substitute(**plc_macros)
            plc_task_info_2 = Template(
                'ca://${P}TaskInfo:2:CycleCount').safe_substitute(**plc_macros)
            plc_task_info_3 = Template(
                'ca://${P}TaskInfo:3:CycleCount').safe_substitute(**plc_macros)

            label_name = QtWidgets.QLabel(str(plc_name))
            label_online = QtWidgets.QLabel()
            label_in_use = QtWidgets.QLabel()
            label_alarmed = QtWidgets.QLabel()
            label_heartbeat = PyDMLabel(init_channel=ico_heart_ch)
            label_plc_task_info_1 = PyDMLabel(init_channel=plc_task_info_1)
            label_plc_task_info_2 = PyDMLabel(init_channel=plc_task_info_2)
            label_plc_task_info_3 = PyDMLabel(init_channel=plc_task_info_3)

            # if alarm of plc_task_info_1 == INVALID => plc down
            # if the count does not update and alarm == NO_ALARM =>
            # plc online but stopped
            self.plc_status_ch = PyDMChannel(
                plc_task_info_1,
                severity_slot=functools.partial(
                    self.plc_cycle_count_severity_changed, plc_name))
            self.plc_status_ch.connect()

            # if we can get the plc_cycle_count the PLC should be ON, if not OFF
            # if we get the plc_cycle_count and the .SERV is INVALID, the PLC is OFF
            plc_status_indicator = PyDMBitIndicator(circle=True)
            plc_status_indicator.setColor(self._off_color)
            # TODO - maybe add the case where PLC On but stopped

            # total initial number of ffs to initialize the dictionaries with
            # num_ffo * num_ff
            all_ffos = ((ffo_end - ffo_start) + 1) * (ff_end - ff_start + 1)
            self.ffs_count_map[plc_name] = {
                'online': [False] * all_ffos,
                'in_use': [False] * all_ffos,
                'alarmed': [False] * all_ffos,
                'plc_status': False
            }
            self.ffs_label_map[plc_name] = {
                'online': label_online,
                'in_use': label_in_use,
                'alarmed': label_alarmed,
                'plc_status': plc_status_indicator
            }

            count = 0
            for _ffo, _ff in entries:
                s_ffo = str(_ffo).zfill(ffos_zfill)
                s_ff = str(_ff).zfill(ffs_zfill)
                ch_macros = dict(index=count, P=prefix, FFO=s_ffo, FF=s_ff)

                ch = Template('ca://${P}FFO:${FFO}:FF:${FF}:Info:InUse_RBV'
                              ).safe_substitute(**ch_macros)
                channel = PyDMChannel(
                    ch,
                    connection_slot=functools.partial(
                        self.ffo_connection_callback, plc_name, count),
                    value_slot=functools.partial(self.ffo_value_changed,
                                                 plc_name, count),
                    severity_slot=functools.partial(self.ffo_severity_changed,
                                                    plc_name, count))
                # should not be adding a new connection because this address
                # already exists in the connections,
                # instead should just add a listener
                channel.connect()
                count += 1

            widget = QtWidgets.QWidget()
            widget_layout = QtWidgets.QHBoxLayout()

            # this is the same width as the labels in the plc_ioc_header
            max_width = 150
            min_width = 130
            widget_list = [
                label_name, label_online, label_in_use, label_alarmed,
                label_heartbeat, label_plc_task_info_1, label_plc_task_info_2,
                label_plc_task_info_3, plc_status_indicator
            ]
            widget.setLayout(widget_layout)

            # set minimum height of the widget
            widget.setMinimumHeight(40)
            self.setup_widget_size(max_width=max_width,
                                   min_width=min_width,
                                   widget_list=widget_list)
            widget.layout().addWidget(label_name)
            widget.layout().addWidget(label_online)
            widget.layout().addWidget(label_in_use)
            widget.layout().addWidget(label_alarmed)
            widget.layout().addWidget(label_heartbeat)
            widget.layout().addWidget(label_plc_task_info_1)
            widget.layout().addWidget(label_plc_task_info_2)
            widget.layout().addWidget(label_plc_task_info_3)
            widget.layout().addWidget(plc_status_indicator)

            self.plc_ioc_container.layout().addWidget(widget)
            vertical_spacer = (QtWidgets.QSpacerItem(
                20, 20, QtWidgets.QSizePolicy.Preferred,
                QtWidgets.QSizePolicy.Maximum))
            self.plc_ioc_container.layout().addItem(vertical_spacer)
        b_vertical_spacer = (QtWidgets.QSpacerItem(
            20, 20, QtWidgets.QSizePolicy.Preferred,
            QtWidgets.QSizePolicy.Expanding))
        self.plc_ioc_container.layout().addItem(b_vertical_spacer)
        self.plc_ioc_container.setSizePolicy(QtWidgets.QSizePolicy.Maximum,
                                             QtWidgets.QSizePolicy.Preferred)
示例#28
0
    def __init__(self,
                 parent=None,
                 macros=None,
                 args=None,
                 average="Gamma Detectors"):
        super().__init__(parent=parent,
                         args=args,
                         macros=macros,
                         ui_filename=OVERVIEW_UI)
        self.setWindowTitle("Overview of Time Bases")
        self.alpha = [0, 0, 0, 0, 0]  # Initially doesn't show none graph
        self.average = average
        self.groups = ["{:0>2d}".format(sec) for sec in range(1, 21)]
        self.x = numpy.arange(len(self.groups))
        self.width = 0.185

        self.dict_pvs_tb = {}
        self.dict_macro_gamma = {}

        self.gamma_1 = [0] * 20
        self.gamma_2 = [0] * 20
        self.gamma_3 = [0] * 20
        self.gamma_4 = [0] * 20
        self.gamma_5 = [0] * 20

        self.fig, self.ax = plt.subplots(figsize=(12, 8))  #
        self.fig.canvas.set_window_title("Overview")  #
        self.fig.subplots_adjust(left=0.05, bottom=0.08, right=0.95,
                                 top=0.95)  # Adjustments of graphics
        plt.subplots_adjust(left=0.1)  #

        self.fig.text(0.03, 0.25, "Control of\n Graphic", ha="center")
        self.ani = FuncAnimation(fig=self.fig,
                                 func=self.animate,
                                 interval=10000)
        self.animate()
        self.checkButtons_setting()
        plt.show()

        if self.average == "Gamma Detectors":  # If user chose 'Counting - Overview'
            for PV in range(1, 21):
                for s_sec in range(2):
                    self.dict_pvs_tb["valueTB{}{}".format(
                        PV, counters[s_sec]
                    )] = "ca://SI-{:0>2d}{}:CO-Counter:TimeBase-SP".format(
                        PV, counters[s_sec])
                if PV != 20:
                    self.dict_pvs_tb["valueTB{}M1".format(
                        PV
                    )] = "ca://SI-{:0>2d}M1:CO-Counter:TimeBase-SP".format(PV +
                                                                           1)
                else:
                    self.dict_pvs_tb["valueTB{}M1".format(
                        PV)] = "ca://SI-01M1:CO-Counter:TimeBase-SP"

            for location in range(1, 21):
                for s_sec in range(len(Det_Location)):
                    self.dict_macro_gamma["DET{}".format(
                        s_sec)] = "SI-{:0>2d}{}:CO-Gamma".format(
                            location, Det_Location[s_sec])
                    if s_sec < 3:
                        self.dict_macro_gamma["TimeBase{}".format(
                            s_sec)] = "{}".format(
                                self.dict_pvs_tb["valueTB{}{}".format(
                                    location, counters[s_sec])])

                    a = PyDMChannel(
                        address="ca://SI-{:0>2d}{}:CO-Gamma:Count-Mon".format(
                            location, Det_Location[s_sec]),
                        value_slot=partial(self.plot,
                                           location=location,
                                           det=s_sec),
                    )  # Connect to Counting PVs
                    a.connect()

                self.disp = PyDMEmbeddedDisplay(
                    parent=self)  # Creates the window of Time Bases
                PyDMApplication.instance().close_widget_connections(self.disp)
                self.disp.macros = json.dumps(self.dict_macro_gamma)
                self.disp.filename = LAYOUT_OVERVIEW_UI
                self.disp.setMinimumWidth(300)
                self.disp.setMinimumHeight(140)
                self.verticalLayout.addWidget(self.disp)

                PyDMApplication.instance().establish_widget_connections(
                    self.disp)
        else:  # If user chose some Average
            for location in range(1, 21):
                for s_sec in range(len(Det_Location)):
                    a = PyDMChannel(
                        address="ca://SI-{:0>2d}{}:CO-Gamma:{}-Mon".format(
                            location, Det_Location[s_sec], self.average),
                        value_slot=partial(self.plot,
                                           location=location,
                                           det=s_sec),
                    )  # Connect to Averages PVs
                    a.connect()
示例#29
0
    def initializeCamera(self, new_camera):
        new_camera = str(new_camera)
        self._color_map_limit_sliders_need_config = True
        self.times = np.zeros(10)
        self.old_timestamp = 0
        self.image_width = 0  # current width (width of ROI)
        self.image_max_width = 0  # full width.  Only used to reset ROI to full.
        self.image_max_height = 0  # full height.  Only used to reset ROI to full.
        self.image_data = np.zeros(0)
        self._average_counter = 0
        self._average_buffer = np.ndarray(0)
        self._needs_auto_range = True
        self.imageChannel = self.cameras[new_camera]["image"]
        self.widthChannel = self.cameras[new_camera][
            "roi_width"] or self.cameras[new_camera]["max_width"]
        self.maxWidthChannel = self.cameras[new_camera]["max_width"]
        self.maxHeightChannel = self.cameras[new_camera]["max_height"]
        self.roiXChannel = self.cameras[new_camera]["roi_x"]
        self.roiYChannel = self.cameras[new_camera]["roi_y"]
        self.roiWidthChannel = self.cameras[new_camera]["roi_width"]
        self.roiHeightChannel = self.cameras[new_camera]["roi_height"]

        self._channels = [
            PyDMChannel(address=self.imageChannel,
                        connection_slot=self.connectionStateChanged,
                        value_slot=self.receiveImageWaveform,
                        severity_slot=self.alarmSeverityChanged),
            PyDMChannel(address=self.widthChannel,
                        value_slot=self.receiveImageWidth),
            PyDMChannel(address=self.maxWidthChannel,
                        value_slot=self.receiveMaxWidth),
            PyDMChannel(address=self.maxHeightChannel,
                        value_slot=self.receiveMaxHeight)
        ]
        if self.roiXChannel and self.roiYChannel and self.roiWidthChannel and self.roiHeightChannel:
            self._channels.extend([
                PyDMChannel(address=self.roiXChannel,
                            value_slot=self.receiveRoiX,
                            value_signal=self.roi_x_signal,
                            write_access_slot=self.roiWriteAccessChanged),
                PyDMChannel(address=self.roiYChannel,
                            value_slot=self.receiveRoiY,
                            value_signal=self.roi_y_signal),
                PyDMChannel(address=self.roiWidthChannel,
                            value_slot=self.receiveRoiWidth,
                            value_signal=self.roi_w_signal),
                PyDMChannel(address=self.roiHeightChannel,
                            value_slot=self.receiveRoiHeight,
                            value_signal=self.roi_h_signal)
            ])
            self.ui.roiXLineEdit.setEnabled(True)
            self.ui.roiYLineEdit.setEnabled(True)
            self.ui.roiWLineEdit.setEnabled(True)
            self.ui.roiHLineEdit.setEnabled(True)
        else:
            self.ui.roiXLineEdit.clear()
            self.ui.roiXLineEdit.setEnabled(False)
            self.ui.roiYLineEdit.clear()
            self.ui.roiYLineEdit.setEnabled(False)
            self.ui.roiWLineEdit.clear()
            self.ui.roiWLineEdit.setEnabled(False)
            self.ui.roiHLineEdit.clear()
            self.ui.roiHLineEdit.setEnabled(False)