This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author eryksun
Recipients eryksun, martin.panter, zeero
Date 2015-08-15.12:55:44
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1439643345.26.0.508788911271.issue24859@psf.upfronthosting.co.za>
In-reply-to
Content
It seems you want a BigEndianStructure:

    from ctypes import *

    class SAEJ1939MsgId(BigEndianStructure):

        _fields_ = (('reserved',           c_uint8, 3),
                    ('priority',           c_uint8, 3),
                    ('extended_data_page', c_uint8, 1),
                    ('data_page',          c_uint8, 1),
                    ('pdu_format',         c_uint8),
                    ('pdu_specific',       c_uint8),
                    ('source_address',     c_uint8))
        
        def __init__(self, *args, pgn=0, **kwds):
            super().__init__(*args, **kwds)
            if pgn > 0:
                self.pgn = pgn

        def __int__(self):
            return int.from_bytes(self, 'big')

        @property
        def pgn(self):
            """pgn is an 18-bit number consisting of EDP, DP, PF, and PS"""
            return (int(self) >> 8) & 0x3FFFF

        @pgn.setter
        def pgn(self, value):
            value |= self.priority << 18
            view = (c_char * 3).from_buffer(self)
            view[:] = value.to_bytes(3, 'big')

        @classmethod
        def from_bytes(cls, msg_id):
            return cls.from_buffer_copy(msg_id)

        @classmethod
        def from_integer(cls, msg_id):
            msg_id_bytes = msg_id.to_bytes(sizeof(cls), 'big')
            return cls.from_buffer_copy(msg_id_bytes)

Example:

    >>> a = SAEJ1939MsgId(priority=7, source_address=3)
    >>> hex(int(a))
    '0x1c000003'

    >>> b = SAEJ1939MsgId(pgn=0xf004, priority=7, source_address=3)
    >>> hex(int(b))
    '0x1cf00403'
    >>> b.priority
    7
    >>> b.pdu_format
    240
    >>> b.pdu_specific
    4
    >>> b.source_address
    3

    >>> c = SAEJ1939MsgId.from_integer(int(b))
    >>> hex(int(c))
    '0x1cf00403'
History
Date User Action Args
2015-08-15 12:55:45eryksunsetrecipients: + eryksun, martin.panter, zeero
2015-08-15 12:55:45eryksunsetmessageid: <1439643345.26.0.508788911271.issue24859@psf.upfronthosting.co.za>
2015-08-15 12:55:45eryksunlinkissue24859 messages
2015-08-15 12:55:44eryksuncreate