Source code for nixnet.database._cluster

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import typing  # NOQA: F401

from nixnet import _cconsts
from nixnet import _errors
from nixnet import _funcs
from nixnet import _props
from nixnet import constants

from nixnet.database import _collection
from nixnet.database import _database_object
from nixnet.database import _dbc_attributes
from nixnet.database import _find_object
from nixnet.database import _signal


[docs]class Cluster(_database_object.DatabaseObject): """Database cluster""" def __init__( self, **kwargs # type: int ): # type: (...) -> None if not kwargs or '_handle' not in kwargs: raise TypeError() self._handle = kwargs['_handle'] self._dbc_attributes = None # type: typing.Optional[_dbc_attributes.DbcAttributeCollection] from nixnet.database import _ecu from nixnet.database import _frame from nixnet.database import _lin_sched from nixnet.database import _pdu self._ecus = _collection.DbCollection( self._handle, constants.ObjectClass.ECU, _cconsts.NX_PROP_CLST_ECU_REFS, _ecu.Ecu) self._frames = _collection.DbCollection( self._handle, constants.ObjectClass.FRAME, _cconsts.NX_PROP_CLST_FRM_REFS, _frame.Frame) self._lin_sched = _collection.DbCollection( self._handle, constants.ObjectClass.LIN_SCHED, _cconsts.NX_PROP_CLST_LIN_SCHEDULES, _lin_sched.LinSched) self._pdus = _collection.DbCollection( self._handle, constants.ObjectClass.PDU, _cconsts.NX_PROP_CLST_PDU_REFS, _pdu.Pdu) def __eq__(self, other): if isinstance(other, self.__class__): return self._handle == other._handle else: return NotImplemented def __ne__(self, other): result = self.__eq__(other) if result is NotImplemented: return result else: return not result def __hash__(self): return hash(self._handle) def __repr__(self): return '{}(handle={})'.format(type(self).__name__, self._handle)
[docs] def check_config_status(self): # type: () -> None """Check this cluster's configuration status. By default, incorrectly configured clusters in the database are not returned from :any:`Database.clusters` because they cannot be used in the bus communication. You can change this behavior by setting :any:`Database.show_invalid_from_open` to `True`. When a cluster configuration status becomes invalid after the database is opened, the cluster still is returned from :any:`Database.clusters` even if :any:`Database.show_invalid_from_open` is `False`. Raises: :any:`XnetError`: The cluster is incorrectly configured. """ status_code = _props.get_cluster_config_status(self._handle) _errors.check_for_error(status_code)
[docs] def export(self, db_filepath): # type: (typing.Text) -> None """Exports this cluster to a CANdb++ or LIN database file format. A CAN cluster is exported as a CANdb++ database file (.dbc). A LIN cluster is exported as a LIN database file (.ldf). If the target file exists, it is overwritten. Exporting a cluster is not supported under Real-Time (RT). Args: db_filepath(str): Contains the pathname to the database file. """ _funcs.nxdb_save_database(self._handle, db_filepath)
[docs] def find( self, object_class, # type: typing.Type[_database_object.DatabaseObject] object_name, # type: typing.Text ): # type: (...) -> _database_object.DatabaseObject """Finds an object in the database. This function finds a database object relative to this parent object. This object may be a grandparent or great-grandparent. If this object is a direct parent (for example, :any:`Frame<_frame.Frame>` for :any:`Signal<_signal.Signal>`), the ``object_name`` to search for can be short, and the search proceeds quickly. If this object is not a direct parent (for example, :any:`Database` for :any:`Signal<_signal.Signal>`), the ``object_name`` to search for must be qualified such that it is unique within the scope of this object. For example, if the class of this object is :any:`Cluster`, and ``object_class`` is :any:`Signal<_signal.Signal>`, you can specify ``object_name`` of ``mySignal``, assuming that signal name is unique to the cluster. If not, you must include the :any:`Frame<_frame.Frame>` name as a prefix, such as ``myFrameA.mySignal``. NI-XNET supports the following subclasses of ``DatabaseObject`` as arguments for ``object_class``: * :any:`nixnet.database.Cluster<Cluster>` * :any:`nixnet.database.Frame<_frame.Frame>` * :any:`nixnet.database.Pdu<Pdu>` * :any:`nixnet.database.Signal<_signal.Signal>` * :any:`nixnet.database.SubFrame<SubFrame>` * :any:`nixnet.database.Ecu<Ecu>` * :any:`nixnet.database.LinSched<LinSched>` * :any:`nixnet.database.LinSchedEntry<LinSchedEntry>` Args: object_class(``DatabaseObject``): The class of the object to find. object_name(str): The name of the object to find. Returns: An instance of the found object. Raises: ValueError: Unsupported value provided for argument ``object_class``. :any:`XnetError`: The object is not found. """ return _find_object.find_object(self._handle, object_class, object_name)
[docs] def merge( self, source_obj, copy_mode, prefix, wait_for_complete): # type: (typing.Any, constants.Merge, typing.Text, bool) -> int """Merges database objects and related subobjects from the source to this cluster. The source can be any of the following objects: * :any:`Frame<_frame.Frame>` * :any:`Pdu` * :any:`Ecu` * :any:`LinSched` * :any:`Cluster` All listed objects must have unique names in the cluster. They are referenced here as objects, as opposed to child objects (for example, a signal is a child of a frame). If the source object name is not used in the target cluster, this function copies the source objects with the child objects to the target. If an object with the same name exists in this cluster, you can avoid name collisions by specifying the prefix to be added to the name. If an object with the same name exists in this cluster, the merge behavior depends on the ``copy_mode`` input. **Example** Target frame F1(v1) has signals S1 and S2(v1). Source frame F1(v2) has signals S2(v2) and S3. (v1) and (v2) are two versions of one object with same name, but with different properties. * Result when ``copy_mode`` is ``COPY_USE_SOURCE``: F1(v2), S2(v2), S3. * Result when ``copy_mode`` is ``COPY_USE_TARGET``: F1(v1), S1, S2(v1). * Result when ``copy_mode`` is ``MERGE_USE_SOURCE``: F1(v2), S1, S2(v2), S3. * Result when ``copy_mode`` is ``MERGE_USE_TARGET``: F1(v1), S1, S2(v1), S3. If the source object is a cluster, this function copies all contained PDUs, ECUs, and LIN schedules with their child objects to this cluster. Depending on the number of contained objects in the source and destination clusters, the execution can take a longer time. If ``wait_for_complete`` is ``True``, this function waits until the merging process gets completed. If the execution completes without errors, ``perecent_complete`` returns ``100``. If ``wait_for_complete`` is ``False``, the function returns quickly, and ``perecent_complete`` returns values less than ``100``. You must call :any:`Cluster.merge` repeatedly until ``perecent_complete`` returns ``100``. You can use the time between calls to perform asynchronous tasks. Args: source_obj(object): The object to be merged into this cluster. copy_mode(:any:`Merge`): Defines the merging behavior if this cluster already contains an object with the same name. prefix(str): The prefix to be added to the source object name if an object with the same name and type exists in this cluster. wait_for_complete(bool): Determines whether the function returns directly or waits until the entire transmission is completed. Returns: int: A value which indicates the merging progress as a percentage. ``100`` indicates completion. """ return _funcs.nxdb_merge(self._handle, source_obj._handle, copy_mode.value, prefix, wait_for_complete)
@property def baud_rate(self): # type: (...) -> int """int: Get or set the buad rate all custer nodes use. This baud rate represents the rate from the database, so it is read-only from the session. Use a session interface property (for example, :any:`Interface.baud_rate`) to override the database baud rate with an application-specific baud rate. **CAN** For CAN, this rate can be 33333, 40000, 50000, 62500, 80000, 83333, 100000, 125000, 160000, 200000, 250000, 400000, 500000, 800000, or 1000000. Some transceivers may support only a subset of these values. **LIN** For LIN, this rate can be 2400-20000 inclusive. If you need values other than these, use the custom settings as described in :any:`Interface.baud_rate`. """ return _props.get_cluster_baud_rate64(self._handle) @baud_rate.setter def baud_rate(self, value): # type: (int) -> None _props.set_cluster_baud_rate64(self._handle, value) @property def comment(self): # type: () -> typing.Text """str: Get or set a comment describing the cluster object. A comment is a string containing up to 65535 characters. """ return _props.get_cluster_comment(self._handle) @comment.setter def comment(self, value): # type: (typing.Text) -> None _props.set_cluster_comment(self._handle, value) @property def database_ref(self): # type: () -> int # todo: return a Database object here handle = _props.get_cluster_database_ref(self._handle) return handle @property def dbc_attributes(self): # type: () -> _dbc_attributes.DbcAttributeCollection """:any:`DbcAttributeCollection`: Access the cluster's DBC attributes.""" if self._dbc_attributes is None: self._dbc_attributes = _dbc_attributes.DbcAttributeCollection(self._handle) return self._dbc_attributes @property def ecus(self): # type: () -> _collection.DbCollection """:any:`DbCollection`: Returns a collection of :any:`Ecu` objects in this cluster. An ECU is assigned to a cluster when the ECU object is created. You cannot change this assignment afterwards. """ return self._ecus @property def frames(self): # type: () -> _collection.DbCollection """:any:`DbCollection`: Returns a collection of :any:`Frame<_frame.Frame>` objects in this cluster. A frame is assigned to a cluster when the frame object is created. You cannot change this assignment afterwards. """ return self._frames @property def name(self): # type: () -> typing.Text """str: Get or set the name of the cluster object. Lowercase letters, uppercase letters, numbers, and the underscore (_) are valid characters for the short name. The space ( ), period (.), and other special characters are not supported within the name. The short name must begin with a letter (uppercase or lowercase) or underscore, and not a number. The short name is limited to 128 characters. If you use a FIBEX file, the short name comes from the file. If you use a CANdb (.dbc), LDF (.ldf), or NI-CAN (.ncd) file, no cluster name is stored in the file, so NI-XNET uses the name Cluster. If you create the cluster yourself, the name that you provide is used. A cluster name must be unique for all clusters in a database. This short name does not include qualifiers to ensure that it is unique, such as the database name. It is for display purposes. """ return _props.get_cluster_name(self._handle) @name.setter def name(self, value): # type: (typing.Text) -> None _props.set_cluster_name(self._handle, value) @property def pdus(self): # type: () -> _collection.DbCollection """:any:`DbCollection`: Returns a collection of :any:`Pdu<_pdu.Pdu>` objects in this cluster. A PDU is assigned to a cluster when the PDU object is created. You cannot change this assignment afterwards. """ return self._pdus @property def pdus_reqd(self): # type: () -> bool """bool: Returns whether using :any:`PDUs<Pdu>` in the database API is required for this cluster. If this property returns ``False``, it is safe to use signals as child objects of a frame without PDUs. This behavior is compatible with NI-XNET 1.1 or earlier. Clusters from .dbc, .ncd, or FIBEX 2 files always return ``False`` for this property, so using PDUs from those files is not required. If this property returns ``True``, the cluster contains PDU configuration, which requires reading the PDUs as frame child objects and then signals as PDU child objects, as shown in the following figure. Internally, the database always uses PDUs, but shows the same signal objects also as children of a frame. .. image:: pdusrequired.gif | For this property to return ``False``, the following conditions must be fulfilled for all frames in the cluster: * Only one PDU is mapped to the frame. * This PDU is not mapped to other frames. * The PDU Start Bit in the frame is 0. * The PDU Update Bit is not used. If the conditions are not fulfilled for a given frame, signals from the frame are still returned, but reading the property returns a warning. """ return _props.get_cluster_pdus_reqd(self._handle) @property def protocol(self): # type: () -> constants.Protocol """:any:`Protocol`: Get or set the cluster protocol.""" return constants.Protocol(_props.get_cluster_protocol(self._handle)) @protocol.setter def protocol(self, value): # type: (constants.Protocol) -> None _props.set_cluster_protocol(self._handle, value.value) @property def sigs(self): # type: () -> typing.Iterable[_signal.Signal] """list of :any:`Signal<_signal.Signal>`: Returns a list of all :any:`Signal<_signal.Signal>` objects in this cluster.""" # NOQA: E501 for handle in _props.get_cluster_sig_refs(self._handle): yield _signal.Signal(_handle=handle) @property def can_io_mode(self): # type: () -> constants.CanIoMode """:any:`CanIoMode`: Get or set the CAN I/O Mode of the cluster.""" return constants.CanIoMode(_props.get_cluster_can_io_mode(self._handle)) @can_io_mode.setter def can_io_mode(self, value): # type: (constants.CanIoMode) -> None _props.set_cluster_can_io_mode(self._handle, value.value) @property def can_fd_baud_rate(self): # type: () -> int """int: Get or set the fast data baud rate when :any:`Cluster.can_io_mode` is ``CanIoMode.CAN_FD_BRS``. Refer to the :any:`CanIoMode` for a description of ``CanIoMode.CAN_FD_BRS``. Use a session interface property (for example, :any:`Interface.can_fd_baud_rate`) to override the database fast baud rate with an application-specific fast baud rate. NI-XNET CAN hardware currently accepts the following numeric baud rates: 200000, 250000, 400000, 500000, 800000, 1000000, 1250000, 1600000, 2000000, 2500000, 4000000, 5000000, and 8000000. Some transceivers may support only a subset of these values. If you need values other than these, use the custom settings as described in :any:`Interface.can_fd_baud_rate`. """ return _props.get_cluster_can_fd_baud_rate64(self._handle) @can_fd_baud_rate.setter def can_fd_baud_rate(self, value): # type: (int) -> None _props.set_cluster_can_fd_baud_rate64(self._handle, value) @property def flex_ray_act_pt_off(self): return _props.get_cluster_flex_ray_act_pt_off(self._handle) @flex_ray_act_pt_off.setter def flex_ray_act_pt_off(self, value): _props.set_cluster_flex_ray_act_pt_off(self._handle, value) @property def flex_ray_cas_rx_l_max(self): return _props.get_cluster_flex_ray_cas_rx_l_max(self._handle) @flex_ray_cas_rx_l_max.setter def flex_ray_cas_rx_l_max(self, value): _props.set_cluster_flex_ray_cas_rx_l_max(self._handle, value) @property def flex_ray_channels(self): return _props.get_cluster_flex_ray_channels(self._handle) @flex_ray_channels.setter def flex_ray_channels(self, value): _props.set_cluster_flex_ray_channels(self._handle, value) @property def flex_ray_clst_drift_dmp(self): return _props.get_cluster_flex_ray_clst_drift_dmp(self._handle) @flex_ray_clst_drift_dmp.setter def flex_ray_clst_drift_dmp(self, value): _props.set_cluster_flex_ray_clst_drift_dmp(self._handle, value) @property def flex_ray_cold_st_ats(self): return _props.get_cluster_flex_ray_cold_st_ats(self._handle) @flex_ray_cold_st_ats.setter def flex_ray_cold_st_ats(self, value): _props.set_cluster_flex_ray_cold_st_ats(self._handle, value) @property def flex_ray_cycle(self): return _props.get_cluster_flex_ray_cycle(self._handle) @flex_ray_cycle.setter def flex_ray_cycle(self, value): _props.set_cluster_flex_ray_cycle(self._handle, value) @property def flex_ray_dyn_seg_start(self): return _props.get_cluster_flex_ray_dyn_seg_start(self._handle) @property def flex_ray_dyn_slot_idl_ph(self): return _props.get_cluster_flex_ray_dyn_slot_idl_ph(self._handle) @flex_ray_dyn_slot_idl_ph.setter def flex_ray_dyn_slot_idl_ph(self, value): _props.set_cluster_flex_ray_dyn_slot_idl_ph(self._handle, value) @property def flex_ray_latest_usable_dyn(self): return _props.get_cluster_flex_ray_latest_usable_dyn(self._handle) @property def flex_ray_latest_guar_dyn(self): return _props.get_cluster_flex_ray_latest_guar_dyn(self._handle) @property def flex_ray_lis_noise(self): return _props.get_cluster_flex_ray_lis_noise(self._handle) @flex_ray_lis_noise.setter def flex_ray_lis_noise(self, value): _props.set_cluster_flex_ray_lis_noise(self._handle, value) @property def flex_ray_macro_per_cycle(self): return _props.get_cluster_flex_ray_macro_per_cycle(self._handle) @flex_ray_macro_per_cycle.setter def flex_ray_macro_per_cycle(self, value): _props.set_cluster_flex_ray_macro_per_cycle(self._handle, value) @property def flex_ray_macrotick(self): return _props.get_cluster_flex_ray_macrotick(self._handle) @property def flex_ray_max_wo_clk_cor_fat(self): return _props.get_cluster_flex_ray_max_wo_clk_cor_fat(self._handle) @flex_ray_max_wo_clk_cor_fat.setter def flex_ray_max_wo_clk_cor_fat(self, value): _props.set_cluster_flex_ray_max_wo_clk_cor_fat(self._handle, value) @property def flex_ray_max_wo_clk_cor_pas(self): return _props.get_cluster_flex_ray_max_wo_clk_cor_pas(self._handle) @flex_ray_max_wo_clk_cor_pas.setter def flex_ray_max_wo_clk_cor_pas(self, value): _props.set_cluster_flex_ray_max_wo_clk_cor_pas(self._handle, value) @property def flex_ray_minislot_act_pt(self): return _props.get_cluster_flex_ray_minislot_act_pt(self._handle) @flex_ray_minislot_act_pt.setter def flex_ray_minislot_act_pt(self, value): _props.set_cluster_flex_ray_minislot_act_pt(self._handle, value) @property def flex_ray_minislot(self): return _props.get_cluster_flex_ray_minislot(self._handle) @flex_ray_minislot.setter def flex_ray_minislot(self, value): _props.set_cluster_flex_ray_minislot(self._handle, value) @property def flex_ray_nm_vec_len(self): return _props.get_cluster_flex_ray_nm_vec_len(self._handle) @flex_ray_nm_vec_len.setter def flex_ray_nm_vec_len(self, value): _props.set_cluster_flex_ray_nm_vec_len(self._handle, value) @property def flex_ray_nit(self): return _props.get_cluster_flex_ray_nit(self._handle) @flex_ray_nit.setter def flex_ray_nit(self, value): _props.set_cluster_flex_ray_nit(self._handle, value) @property def flex_ray_nit_start(self): return _props.get_cluster_flex_ray_nit_start(self._handle) @property def flex_ray_num_minislt(self): return _props.get_cluster_flex_ray_num_minislt(self._handle) @flex_ray_num_minislt.setter def flex_ray_num_minislt(self, value): _props.set_cluster_flex_ray_num_minislt(self._handle, value) @property def flex_ray_num_stat_slt(self): return _props.get_cluster_flex_ray_num_stat_slt(self._handle) @flex_ray_num_stat_slt.setter def flex_ray_num_stat_slt(self, value): _props.set_cluster_flex_ray_num_stat_slt(self._handle, value) @property def flex_ray_off_cor_st(self): return _props.get_cluster_flex_ray_off_cor_st(self._handle) @flex_ray_off_cor_st.setter def flex_ray_off_cor_st(self, value): _props.set_cluster_flex_ray_off_cor_st(self._handle, value) @property def flex_ray_payld_len_dyn_max(self): return _props.get_cluster_flex_ray_payld_len_dyn_max(self._handle) @flex_ray_payld_len_dyn_max.setter def flex_ray_payld_len_dyn_max(self, value): _props.set_cluster_flex_ray_payld_len_dyn_max(self._handle, value) @property def flex_ray_payld_len_max(self): return _props.get_cluster_flex_ray_payld_len_max(self._handle) @property def flex_ray_payld_len_st(self): return _props.get_cluster_flex_ray_payld_len_st(self._handle) @flex_ray_payld_len_st.setter def flex_ray_payld_len_st(self, value): _props.set_cluster_flex_ray_payld_len_st(self._handle, value) @property def flex_ray_stat_slot(self): return _props.get_cluster_flex_ray_stat_slot(self._handle) @flex_ray_stat_slot.setter def flex_ray_stat_slot(self, value): _props.set_cluster_flex_ray_stat_slot(self._handle, value) @property def flex_ray_sym_win(self): return _props.get_cluster_flex_ray_sym_win(self._handle) @flex_ray_sym_win.setter def flex_ray_sym_win(self, value): _props.set_cluster_flex_ray_sym_win(self._handle, value) @property def flex_ray_sym_win_start(self): return _props.get_cluster_flex_ray_sym_win_start(self._handle) @property def flex_ray_sync_node_max(self): return _props.get_cluster_flex_ray_sync_node_max(self._handle) @flex_ray_sync_node_max.setter def flex_ray_sync_node_max(self, value): _props.set_cluster_flex_ray_sync_node_max(self._handle, value) @property def flex_ray_tss_tx(self): return _props.get_cluster_flex_ray_tss_tx(self._handle) @flex_ray_tss_tx.setter def flex_ray_tss_tx(self, value): _props.set_cluster_flex_ray_tss_tx(self._handle, value) @property def flex_ray_wake_sym_rx_idl(self): return _props.get_cluster_flex_ray_wake_sym_rx_idl(self._handle) @flex_ray_wake_sym_rx_idl.setter def flex_ray_wake_sym_rx_idl(self, value): _props.set_cluster_flex_ray_wake_sym_rx_idl(self._handle, value) @property def flex_ray_wake_sym_rx_low(self): return _props.get_cluster_flex_ray_wake_sym_rx_low(self._handle) @flex_ray_wake_sym_rx_low.setter def flex_ray_wake_sym_rx_low(self, value): _props.set_cluster_flex_ray_wake_sym_rx_low(self._handle, value) @property def flex_ray_wake_sym_rx_win(self): return _props.get_cluster_flex_ray_wake_sym_rx_win(self._handle) @flex_ray_wake_sym_rx_win.setter def flex_ray_wake_sym_rx_win(self, value): _props.set_cluster_flex_ray_wake_sym_rx_win(self._handle, value) @property def flex_ray_wake_sym_tx_idl(self): return _props.get_cluster_flex_ray_wake_sym_tx_idl(self._handle) @flex_ray_wake_sym_tx_idl.setter def flex_ray_wake_sym_tx_idl(self, value): _props.set_cluster_flex_ray_wake_sym_tx_idl(self._handle, value) @property def flex_ray_wake_sym_tx_low(self): return _props.get_cluster_flex_ray_wake_sym_tx_low(self._handle) @flex_ray_wake_sym_tx_low.setter def flex_ray_wake_sym_tx_low(self, value): _props.set_cluster_flex_ray_wake_sym_tx_low(self._handle, value) @property def flex_ray_use_wakeup(self): return _props.get_cluster_flex_ray_use_wakeup(self._handle) @flex_ray_use_wakeup.setter def flex_ray_use_wakeup(self, value): _props.set_cluster_flex_ray_use_wakeup(self._handle, value) @property def lin_schedules(self): # type: () -> _collection.DbCollection """:any:`DbCollection`: Returns a collection of :any:`LinSched` defined in this cluster. You assign a LIN schedule to a cluster when you create the LIN schedule object. You cannot change this assignment afterwards. The schedules in this collection are sorted alphabetically by schedule name. """ return self._lin_sched @property def lin_tick(self): # type: () -> float """float: Returns the relative time between LIN ticks (relative f64 in seconds). The :any:`LinSchedEntry.delay` property must be a multiple of this tick. This tick is referred to as the "timebase" in the LIN specification. The :any:`Ecu.lin_master` property defines the Tick property in this cluster. You cannot use the Tick property when there is no LIN Master property defined in this cluster. """ return _props.get_cluster_lin_tick(self._handle) @lin_tick.setter def lin_tick(self, value): # type: (float) -> None _props.set_cluster_lin_tick(self._handle, value) @property def flex_ray_alw_pass_act(self): return _props.get_cluster_flex_ray_alw_pass_act(self._handle) @flex_ray_alw_pass_act.setter def flex_ray_alw_pass_act(self, value): _props.set_cluster_flex_ray_alw_pass_act(self._handle, value) @property def application_protocol(self): # type: () -> constants.AppProtocol """:any:`AppProtocol`: Get or set the application protocol.""" return constants.AppProtocol(_props.get_cluster_application_protocol(self._handle)) @application_protocol.setter def application_protocol(self, value): # type: (constants.AppProtocol) -> None _props.set_cluster_application_protocol(self._handle, value.value) @property def can_fd_iso_mode(self): # type: () -> constants.CanFdIsoMode """:any:`CanFdIsoMode`: Returns the mode of a CAN FD cluster. The default is ``CanFdIsoMode.ISO``. You define the value in a dialog box that appears when you define an alias for the database. """ return constants.CanFdIsoMode(_props.get_cluster_can_fd_iso_mode(self._handle))