Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 26 additions & 82 deletions nixnet/database/_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
from __future__ import division
from __future__ import print_function

import operator
import typing # NOQA: F401

from nixnet import _cconsts
from nixnet import _errors
from nixnet import _props
from nixnet import constants
from nixnet import types

from nixnet.database import _cluster
from nixnet.database import _collection
Expand Down Expand Up @@ -553,27 +555,21 @@ def mux_subframes(self):
return self._mux_subframes

@property
def pdus(self):
# actually returns typing.Iterable[_pdu.Pdu], but avoiding a circular import
# type: () -> typing.Iterable[typing.Any]
"""list of :any:`Pdu`: Get or set a list that maps existing PDUs to a frame.
def pdu_properties(self):
# type: () -> typing.Iterable[types.PduProperties]
"""list of :any:`PduProperties`: Get or set a list that maps existing PDUs to a frame.

A mapped PDU is transmitted inside the frame payload when the frame is transmitted.
You can map one or more PDUs to a frame and one PDU to multiple frames.

Mapping PDUs to a frame requires setting three frame properties.
All three properties are lists of values:
Mapping PDUs to a frame requires setting pdu_properties with a list of PduProperties tuples.
Each tuple contains the following properties:

* :any:`Frame.pdus`: Set this property first to define
the sequence of values for the other two properties.
* :any:`Frame.pdu_start_bits`: Defines the start bit of the PDU inside the frame.
* :any:`Frame.pdu_update_bits`: Defines the update bit for the PDU inside the frame.
* :any:`PduProperties.pdu`: Defines the sequence of values for the other two properties.
* :any:`PduProperties.start_bit`: Defines the start bit of the PDU inside the frame.
* :any:`PduProperties.update_bit`: Defines the update bit for the PDU inside the frame.
If the update bit is not used, set the value to ``-1``.

Values on the same list position are corresponding.
For example, ``pdus[0]``, ``pdu_start_bits[0]``,
and ``pdu_update_bits[0]`` define the mapping for the first PDU in the frame.

Databases imported from FIBEX prior to version 3.0,
from DBC, NCD, or LDF files have a strong one-to-one relationship between frames and PDUs.
Every frame has exactly one PDU mapped, and every PDU is mapped to exactly one frame.
Expand All @@ -588,74 +584,22 @@ def pdus(self):
you can avoid using PDUs in the database API
and create signals and subframes directly on a frame.
"""
from nixnet.database import _pdu
for handle in _props.get_frame_pdu_refs(self._handle):
yield _pdu.Pdu(handle)

@pdus.setter
def pdus(self, value):
# value is actually typing.Iterable[_pdu.Pdu], but avoiding a circular import
# type: (typing.Iterable[typing.Any]) -> None
handle_list = [pdu._handle for pdu in value]
_props.set_frame_pdu_refs(self._handle, handle_list)

@property
def pdu_start_bits(self):
# type: () -> typing.Iterable[int]
"""list of int: This property defines the start bits of PDUs mapped to a frame.

A mapped PDU is transmitted inside the frame payload when the frame is transmitted.
You can map one or more PDUs to a frame and one PDU to multiple frames.

Mapping PDUs to a frame requires setting of three frame properties.
All three properties are lists of values:

* :any:`Frame.pdus`: Set this property first to define
the sequence of values for the other two properties.
* :any:`Frame.pdu_start_bits`: Defines the start bit of the PDU inside the frame.
* :any:`Frame.pdu_update_bits`: Defines the update bit for the PDU inside the frame.
If the update bit is not used, set the value to ``-1``.

Values on the same list position are corresponding.
For example, ``pdus[0]``, ``pdu_start_bits[0]``,
and ``pdu_update_bits[0]`` define the mapping for the first PDU in the frame.
"""
return _props.get_frame_pdu_start_bits(self._handle)

@pdu_start_bits.setter
def pdu_start_bits(self, value):
# type: (typing.List[int]) -> None
_props.set_frame_pdu_start_bits(self._handle, value)

@property
def pdu_update_bits(self):
# type: () -> typing.Iterable[int]
"""list of int: Get or set the update bits of PDUs mapped to a frame.

If the update bit is not used for the PDU, set the value to -1.
The receiver uses the update bit to determine whether the frame sender has updated data in a particular PDU.
Update bits allow for the decoupling of a signal update from a frame occurrence.
Update bits is an optional PDU property.

Mapping PDUs to a frame requires setting three frame properties.
All three properties are lists of values:

* :any:`Frame.pdus`: Set this property first to define
the sequence of values for the other two properties.
* :any:`Frame.pdu_start_bits`: Defines the start bit of the PDU inside the frame.
* :any:`Frame.pdu_update_bits`: Defines the update bit for the PDU inside the frame.
If the update bit is not used, set the value to ``-1``.

Values on the same list position are corresponding.
For example, ``pdus[0]``, ``pdu_start_bits[0]``,
and ``pdu_update_bits[0]`` define the mapping for the first PDU in the frame.
"""
return _props.get_frame_pdu_update_bits(self._handle)

@pdu_update_bits.setter
def pdu_update_bits(self, value):
# type: (typing.List[int]) -> None
_props.set_frame_pdu_update_bits(self._handle, value)
handles = _props.get_frame_pdu_refs(self._handle)
pdu_tuples = zip(*(handles,
_props.get_frame_pdu_start_bits(self._handle),
_props.get_frame_pdu_update_bits(self._handle)))
for (ref, start_bit, update_bit) in pdu_tuples:
yield types.PduProperties(ref, start_bit, update_bit)

@pdu_properties.setter
def pdu_properties(self, pdus):
# type: (typing.Iterable[types.PduProperties]) -> None
_props.set_frame_pdu_refs(self._handle,
list(map(lambda p: p.pdu._handle, pdus)))
_props.set_frame_pdu_start_bits(self._handle,
list(map(operator.attrgetter('start_bit'), pdus)))
_props.set_frame_pdu_update_bits(self._handle,
list(map(operator.attrgetter('update_bit'), pdus)))

@property
def variable_payload(self):
Expand Down
4 changes: 1 addition & 3 deletions nixnet/database/_pdu.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,7 @@ def frms(self):
A PDU is transmitted within the frames to which it is mapped.

To map a PDU to a frame,
use the :any:`Frame.pdus`,
:any:`Frame.pdu_start_bits`,
and :any:`Frame.pdu_update_bits` properties.
use the :any:`Frame.pdu_properties` property.
You can map one PDU to multiple frames.
"""
for handle in _props.get_pdu_frm_refs(self._handle):
Expand Down
21 changes: 20 additions & 1 deletion nixnet/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
'DelayFrame',
'LogTriggerFrame',
'StartTriggerFrame',
'XnetFrame']
'XnetFrame',
'PduProperties']


DriverVersion_ = collections.namedtuple(
Expand Down Expand Up @@ -153,6 +154,24 @@ class LinComm(LinComm_):
pass


PduProperties_ = collections.namedtuple(
'PDU_PROPERTIES_',
['pdu', 'start_bit', 'update_bit'])


class PduProperties(PduProperties_):
"""Properties that map a PDU onto a frame.

Mapping PDUs to a frame requires setting three frame properties that are combined into this tuple.

Attributes:
pdu (:any:`Pdu`): Defines the sequence of values for the other two properties.
start_bit (int): Defines the start bit of the PDU inside the frame.
update_bit (int): Defines the update bit for the PDU inside the frame.
If the update bit is not used, set the value to ``-1``.
"""


class CanIdentifier(object):
"""CAN frame arbitration identifier.

Expand Down