KBUS Python bindings for Messages¶
KBUS lightweight message system.
Message¶
-
class
kbus.
Message
(name, data=None, to=None, from_=None, orig_from=None, final_to=None, in_reply_to=None, flags=None, id=None)¶ Bases:
object
A wrapper for a KBUS message
A Message can be created in a variety of ways. Perhaps most obviously:
>>> msg = Message('$.Fred') >>> msg Message('$.Fred')
>>> msg = Message('$.Fred', '1234') >>> msg Message('$.Fred', data='1234')
>>> msg = Message('$.Fred', '12345678') >>> msg Message('$.Fred', data='12345678')
>>> msg1 = Message('$.Fred', data='1234') >>> msg1 Message('$.Fred', data='1234')
A
Message
can be constructed from another message directly:>>> msg2 = Message.from_message(msg1) >>> msg2 == msg1 True
or from the tuple returned by
extract()
:>>> msg3 = Message.from_sequence(msg1.extract()) >>> msg3 == msg1 True
or from an equivalent list:
>>> msg3 = Message.from_sequence(list(msg1.extract())) >>> msg3 == msg1 True
or one can use a “string” – for instance, as returned by the
Ksock.read()
method:>>> msg_as_string = msg1.to_bytes() >>> msg4 = Message.from_bytes(msg_as_string) >>> msg4 == msg1 True
Some testing is made on the first argument - a printable string must start with
$.
(KBUS itself will make a more stringent test when the message is sent):>>> Message('Fred') Traceback (most recent call last): ... ValueError: Message name "Fred" does not start "$."
and a data “string” must be plausible - that is, long enough for the minimal message header:
>>> Message.from_bytes(msg_as_string[:8]) Traceback (most recent call last): ... ValueError: Cannot form entire message from string "Kbus\x00\x00\x00\x00" of length 8
and starting with a message start guard:
>>> Message.from_bytes('1234'+msg_as_string) Traceback (most recent call last): ... ValueError: Cannot form entire message from string "1234Kbus..1234subK" which does not start with message start guard
When constructing a message from another message, one may override particular values (but not the name):
>>> msg5 = Message.from_message(msg1, to=9, in_reply_to=MessageId(0, 3)) >>> msg5 Message('$.Fred', data='1234', to=9L, in_reply_to=MessageId(0, 3))
>>> msg5a = Message.from_message(msg1, to=9, in_reply_to=MessageId(0, 3)) >>> msg5a == msg5 True
However, whilst it is possible to set (for instance) to back to 0 by this method:
>>> msg6 = Message.from_message(msg5, to=0) >>> msg6 Message('$.Fred', data='1234', in_reply_to=MessageId(0, 3))
(and the same for any of the integer fields), it is not possible to set any of the message id fields to None:
>>> msg6 = Message.from_message(msg5, in_reply_to=None) >>> msg6 Message('$.Fred', data='1234', to=9L, in_reply_to=MessageId(0, 3))
If you need to do that, go via the
extract()
method:>>> (id, in_reply_to, to, from_, orig_from, final_to, flags, name, data) = msg5.extract() >>> msg6 = Message(name, data, to, from_, None, None, flags, id) >>> msg6 Message('$.Fred', data='1234', to=9L)
For convenience, the parts of a Message may be retrieved as properties:
>>> print msg1.id None >>> msg1.name '$.Fred' >>> msg1.to 0L >>> msg1.from_ 0L >>> print msg1.in_reply_to None >>> msg1.flags 0L >>> msg1.data '1234'
Message ids are objects if set:
>>> msg1 = Message('$.Fred', data='1234', id=MessageId(0, 33)) >>> msg1 Message('$.Fred', data='1234', id=MessageId(0, 33)) >>> msg1.id MessageId(0, 33)
The arguments to Message() are:
arg – this is the initial argument, and is a message name (a string that starts
$.
), a Message, or a string representing an “entire” message.If arg is a message name, or another Message then the keyword arguments may be used (for another Message, they override the values in that Message). If arg is a message-as-a-string, any keyword arguments will be ignored.
data is data for the Message, either
None
or a Python string.to is the Ksock id for the destination, for use in replies or in stateful messaging. Normally it should be left 0.
from_ is the Ksock id of the sender. Normally this should be left 0, as it is assigned by KBUS.
if in_reply_to is non-zero, then it is the Ksock id to which the reply shall go (taken from the from_ field in the original message). Setting in_reply_to non-zero indicates that the Message is a reply. See also the Reply class, and especially the reply_to function, which makes constructing replies simpler.
flags can be used to set the flags for the message. If all that is wanted is to set the
Message.WANT_A_REPLY
flag, it is simpler to use theRequest
class to construct the message.id may be used to set the message id, although unless the network_id field is set, KBUS will ignore this and set the id internally (this can be useful when constructing a message to compare received messages against).
Our internal values are:
- msg, which is the actual message datastructure.
Note
Message data is always held as the appropriate C datastructure (via ctypes), mainly to try to minimise copying of data in and out of that form. A “pointy” or “entire” form is used as appropriate.
The message fields (inside msg) are readable directly (as properties of
Message
), but are not directly writable. Setter methods (set_urgent()
andset_want_reply()
) are provided for those which are likely to be sensible to alter in normal use.If you need to alter the Message contents, beyond use of the setter methods, then you will need to do so via the internal msg datastructure, with a clear understanding of the KBUS datastructure. If you need an example of doing this, see the Limpet codebase (which changes the id, orig_from and final_to fields, not something normal code should need or want to do).
-
ALL_OR_FAIL
= 512L¶
-
ALL_OR_WAIT
= 256L¶
-
END_GUARD
= 1264743795¶
-
START_GUARD
= 1937072715¶
-
SYNTHETIC
= 4L¶
-
URGENT
= 8L¶
-
WANT_A_REPLY
= 1L¶
-
WANT_YOU_TO_REPLY
= 2L¶
-
cast
()¶ Return (a copy of) ourselves as an appropriate subclass of
Message
.Reading from a
Ksock
returns aMessage
, whatever the actual message type. Normally, this is OK, but sometimes it would be nice to have an actual message of the correct class.
-
data
¶ Returns the payload of this KBUS message as a Python string, or None if it is not present.
-
equivalent
(other)¶ Returns true if the two messages are mostly the same.
For purposes of this comparison, we ignore id, flags, in_reply_to and from_.
-
extract
()¶ Return our parts as a tuple.
The values are returned in something approximating the order within the message itself:
(id, in_reply_to, to, from_, orig_from, final_to, flags, name, data)This is not the same order as the keyword arguments to
Message()
.
-
flags
¶ The flags field of the message header.
-
from_
¶ The from field of the message header.
-
static
from_bytes
(arg)¶ Construct a
Message
from bytes, as read byKsock.read_data()
.For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Message.from_bytes(msg1.to_bytes()) >>> msg2 Message('$.Fred', data='12345678')
-
static
from_message
(msg, data=None, to=None, from_=None, orig_from=None, final_to=None, in_reply_to=None, flags=None, id=None)¶ Construct a
Message
from another message.All the values in the old message, except the name, may be changed by specifying new values in the argument list.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Message.from_message(msg1, flags=1) >>> msg2 Message('$.Fred', data='12345678', flags=0x00000001)
-
static
from_sequence
(seq, data=None, to=None, from_=None, orig_from=None, final_to=None, in_reply_to=None, flags=None, id=None)¶ Construct a
Message
from a sequence, as returned by extract.All the values in the old message, except the name, may be changed by specifying new values in the argument list.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Message.from_sequence(msg1.extract(), flags=1) >>> msg2 Message('$.Fred', data='12345678', flags=0x00000001)
-
id
¶ The id field of the message header.
-
in_reply_to
¶ The in_reply_to field of the message header.
-
is_reply
()¶ A convenience method - are we a Reply?
-
is_request
()¶ A convenience method - are we a Request?
-
is_stateful_request
()¶ A convenience method - are we a Stateful Request?
-
is_synthetic
()¶ Return
True
if this is a synthetic message - one generated by KBUS.
-
is_urgent
()¶ Return
True
if this is an urgent message.
-
name
¶ The name field of the message header. Any padding bytes are removed.
-
set_urgent
(value=True)¶ Set or unset the ‘urgent message’ flag.
-
set_want_reply
(value=True)¶ Set or unset the ‘we want a reply’ flag.
-
to
¶ The to field of the message header.
-
to_bytes
()¶ Return the message as a string.
This returns the entirety of the message as a Python string.
In order to do this, it first coerces the mesage to an “entire” message (so that we don’t have any dangling “pointers” to the name or data).
See the
total_length()
method for how to determine the “correct” length of this string.
-
total_length
()¶ Return the total length of this message.
A Message may be held in one of two ways:
- “pointy” - this is a message header, with references to the message name and data.
- “entire” - this is a message header with the message name and data (and an extra end guard) appended to it.
Message construction may produce either of these (although construction of a message from a string will always produce an “entire” message). Reading a message from a
Ksock
returns an “entire” message string.The actual “pointy” or “entire” message data is held in the msg value of the
Message
instance.The
to_bytes()
method returns the data for an “entire” message. In certain circumstances (typically, on a 64-byte system) the actual length of data returned byto_bytes()
may be slightly too long (due to extra padding at the end).This method calculates the correct length of the equivalent “entire” message for this Message, without any such padding. If you want to write the data returned by
to_bytes()
into aKsock
, only use the number of bytes indicated by this method.
-
wants_us_to_reply
()¶ Return
True
if we (specifically us) are should reply to this message.
Announcement¶
-
class
kbus.
Announcement
(name, data=None, to=None, from_=None, flags=None, id=None)¶ Bases:
kbus.messages.Message
A “plain” message, needing no reply
This is intended to be a convenient way of constructing a message that is just aimed at any listeners.
It’s also a terminological convenience - all of the “message” things are clearly messages, so we need a special name for “plain” messages... There’s an argument for just factory functions to create these things, but a class feels a little cleaner to me.
An Announcement can be created in a variety of ways. Perhaps most obviously:
>>> ann1 = Announcement('$.Fred', data='1234') >>> ann1 Announcement('$.Fred', data='1234')
Since Announcement is a “plain” Message, we expect to be able to use the normal ways of instantiating a Message for an Announcement.
So, an Announcement can be constructed from another message directly:
>>> ann2 = Announcement.from_message(ann1) >>> ann2 == ann1 True
>>> msg = Announcement.from_message(ann1) >>> ann2a = Announcement.from_message(msg) >>> ann2 == ann2a True
Since it’s an Announcement, there’s no in_reply_to argument
>>> fail = Announcement('$.Fred', in_reply_to=None) Traceback (most recent call last): ... TypeError: __init__() got an unexpected keyword argument 'in_reply_to'
and the in_reply_to value in Message objects is ignored:
>>> msg = Message('$.Fred', data='1234', in_reply_to=MessageId(1, 2)) >>> ann = Announcement.from_message(msg) >>> ann Announcement('$.Fred', data='1234') >>> print ann.in_reply_to None
or from the
extract()
tuple - again, reply_to will be ignored:>>> ann3 = Announcement.from_sequence(ann1.extract()) >>> ann3 == ann1 True
or from an equivalent list (and as above for reply_to):
>>> ann3 = Announcement.from_sequence(list(ann1.extract())) >>> ann3 == ann1 True
Or one can use the same thing represented as a string:
>>> ann_as_string = ann1.to_bytes() >>> ann4 = Announcement.from_bytes(ann_as_string) >>> ann4 == ann1 True
For convenience, the parts of an Announcement may be retrieved as properties:
>>> print ann1.id None >>> ann1.name '$.Fred' >>> ann1.to 0L >>> ann1.from_ 0L >>> print ann1.in_reply_to # always expected to be None None >>> ann1.flags 0L >>> ann1.data '1234'
Note that:
- An Announcement message is such because it is not a message of another type. There is nothing else special about it.
-
static
from_bytes
(arg)¶ Construct an Announcement from bytes, as read by
Ksock.read_data()
.For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Announcement.from_bytes(msg1.to_bytes()) >>> msg2 Announcement('$.Fred', data='12345678')
-
static
from_message
(msg, data=None, to=None, from_=None, flags=None, id=None)¶ Construct an Announcement from another message.
The optional arguments allow changing the named fields in the new Announcement.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Announcement.from_message(msg1, flags=1) >>> msg2 Announcement('$.Fred', data='12345678', flags=0x00000001)
-
static
from_sequence
(seq, data=None, to=None, from_=None, flags=None, id=None)¶ Construct an Announcement from a sequence, as returned by
extract()
.The optional arguments allow changing the named fields in the new Announcement.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Announcement.from_sequence(msg1.extract(), flags=1) >>> msg2 Announcement('$.Fred', data='12345678', flags=0x00000001)
-
set_want_reply
(value=True)¶ Announcements are not Requests.
Request and stateful_request¶
-
class
kbus.
Request
(name, data=None, to=None, from_=None, final_to=None, flags=None, id=None)¶ Bases:
kbus.messages.Message
A message that wants a reply.
This is intended to be a convenient way of constructing a message that wants a reply.
It doesn’t take an in_reply_to initialisation argument:
>>> fail = Request('$.Fred', in_reply_to=None) Traceback (most recent call last): ... TypeError: __init__() got an unexpected keyword argument 'in_reply_to'
And it automatically sets the
WANT_A_REPLY
flag, but otherwise it behaves just like a Message.For instance, consider:
>>> msg = Message('$.Fred', data='1234', flags=Message.WANT_A_REPLY) >>> msg Message('$.Fred', data='1234', flags=0x00000001) >>> req = Request('$.Fred', data='1234') >>> req Request('$.Fred', data='1234', flags=0x00000001) >>> req == msg True
If it is given a to argument, then it is a Stateful Request - it will be an error if it cannot be delivered to that particular Replier (for instance, if the Replier had unbound and someone else had bound as Replier for this message name).
>>> req = Request('$.Fred', data='1234', to=1234) >>> req Request('$.Fred', data='1234', to=1234L, flags=0x00000001)
A Stateful Request may also need to supply a final_to argument, if the original Replier is over a (Limpet) network. This should be taken from an earlier Reply from that Replier – see the convenience function stateful_request(). However, it can be done by hand:
>>> req = Request('$.Fred', data='1234', to=1234, final_to=OrigFrom(12, 23), flags=0x00000001) >>> req Request('$.Fred', data='1234', to=1234L, final_to=OrigFrom(12, 23), flags=0x00000001)
Note that:
- A request message is a request just because it has the
Message.WANT_A_REPLY
flag set. There is nothing else special about it. - A stateful request message is then a request that has its to flag set.
-
static
from_bytes
(arg)¶ Construct a Request from bytes, as read by
Ksock.read_data()
.For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Request.from_bytes(msg1.to_bytes()) >>> msg2 Request('$.Fred', data='12345678', flags=0x00000001)
-
static
from_message
(msg, data=None, to=None, from_=None, final_to=None, flags=None, id=None)¶ Construct a Request from another message.
The optional arguments allow changing the named fields in the new Request.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Request.from_message(msg1, flags=2) >>> msg2 Request('$.Fred', data='12345678', flags=0x00000003)
-
static
from_sequence
(seq, data=None, to=None, from_=None, final_to=None, flags=None, id=None)¶ Construct a Request from a sequence, as returned by
extract()
.The optional arguments allow changing the named fields in the new Request.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Request.from_sequence(msg1.extract(), flags=2) >>> msg2 Request('$.Fred', data='12345678', flags=0x00000003)
- A request message is a request just because it has the
-
kbus.
stateful_request
(earlier_msg, name, data=None, from_=None, flags=None, id=None)¶ Construct a stateful Request, based on an earlier
Reply
or statefulRequest
.This is intended to be the normal way of constructing a stateful request.
earlier_msg is either:
an earlier Reply, whose from_ field will be used as the new Request’s to field, and whose orig_from field will be used as the new Request’s final_to field.
Remember, a Reply is a message whose in_reply_to field is set.
an earlier Stateful Request, whose to and orig_from fields will be copied to the new Request.
Remember, a Stateful Request is a message with the
Message.WANT_A_REPLY
flag set (a Request), and whose to field is set (which is to a specific Replier).
The rest of the arguments are the same as for
Request()
, except that the to and orig_from initialiser arguments are missing.For instance, in the normal (single network) case:
>>> reply = Reply('$.Fred', to=27, from_=39, in_reply_to=MessageId(0, 132)) >>> reply Reply('$.Fred', to=27L, from_=39L, in_reply_to=MessageId(0, 132)) >>> request = stateful_request(reply, '$.SomethingElse') >>> request Request('$.SomethingElse', to=39L, flags=0x00000001)
or, with a Reply that has come from far away:
>>> reply = Reply('$.Fred', to=27, from_=39, in_reply_to=MessageId(0, 132), orig_from=OrigFrom(19,23)) >>> reply Reply('$.Fred', to=27L, from_=39L, orig_from=OrigFrom(19, 23), in_reply_to=MessageId(0, 132)) >>> request = stateful_request(reply, '$.SomethingElse') >>> request Request('$.SomethingElse', to=39L, final_to=OrigFrom(19, 23), flags=0x00000001)
or, reusing our stateful Request:
>>> request = stateful_request(request, '$.Again', data='Aha!') >>> request Request('$.Again', data='Aha!', to=39L, final_to=OrigFrom(19, 23), flags=0x00000001)
Reply and reply_to¶
-
class
kbus.
Reply
(name, data=None, to=None, from_=None, orig_from=None, in_reply_to=None, flags=None, id=None)¶ Bases:
kbus.messages.Message
A reply message.
(Note that the constructor for this class does not flip fields (such as id and in_reply_to, or from_ and to) when building the Reply - if you want that behaviour (and you probably do), use thereply_to()
function.)Thus Reply can be used as, for instance:
>>> direct = Reply('$.Fred', to=27, in_reply_to=MessageId(0, 132)) >>> direct Reply('$.Fred', to=27L, in_reply_to=MessageId(0, 132)) >>> reply = Reply.from_message(direct) >>> direct == reply True
Since a Reply is a Message with its in_reply_to set, this must be provided:
>>> msg = Message('$.Fred', data='1234', from_=27, to=99, id=MessageId(0, 132), flags=Message.WANT_A_REPLY) >>> msg Message('$.Fred', data='1234', to=99L, from_=27L, flags=0x00000001, id=MessageId(0, 132)) >>> reply = Reply.from_message(msg) Traceback (most recent call last): ... ValueError: A Reply must specify in_reply_to
>>> reply = Reply.from_message(msg, in_reply_to=MessageId(0, 5)) >>> reply Reply('$.Fred', data='1234', to=99L, from_=27L, in_reply_to=MessageId(0, 5), flags=0x00000001, id=MessageId(0, 132))
When Limpet networks are in use, it may be necessary to construct a Reply with its orig_from field set (this should only really be done by a Limpet itself, though):
>>> reply = Reply.from_message(msg, in_reply_to=MessageId(0, 5), orig_from=OrigFrom(23, 92)) >>> reply Reply('$.Fred', data='1234', to=99L, from_=27L, orig_from=OrigFrom(23, 92), in_reply_to=MessageId(0, 5), flags=0x00000001, id=MessageId(0, 132))
It’s also possible to construct a Reply in most of the other ways a
Message
can be constructed. For instance:>>> rep2 = Reply.from_bytes(direct.to_bytes()) >>> rep2 == direct True >>> rep4 = Reply.from_sequence(direct.extract()) >>> rep4 == direct True
-
static
from_bytes
(arg)¶ Construct a Message from bytes, as read by
Ksock.read_data()
.in_reply_to must be set in the message data.
For instance:
>>> msg1 = Message('$.Fred', '12345678', in_reply_to=MessageId(0,5)) >>> msg1 Message('$.Fred', data='12345678', in_reply_to=MessageId(0, 5)) >>> msg2 = Message.from_bytes(msg1.to_bytes()) >>> msg2 Message('$.Fred', data='12345678', in_reply_to=MessageId(0, 5))
-
static
from_message
(msg, data=None, to=None, from_=None, orig_from=None, in_reply_to=None, flags=None, id=None)¶ Construct a Message from another message.
All the values in the old message, except the name, may be changed by specifying new values in the argument list.
in_reply_to must be specified explicitly, if it is not present in the old/template message.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Reply.from_message(msg1, flags=2, in_reply_to=MessageId(0,5)) >>> msg2 Reply('$.Fred', data='12345678', in_reply_to=MessageId(0, 5), flags=0x00000002)
-
static
from_sequence
(seq, data=None, to=None, from_=None, orig_from=None, in_reply_to=None, flags=None, id=None)¶ Construct a Message from a sequence, as returned by
extract()
.All the values in the old message, except the name, may be changed by specifying new values in the argument list.
in_reply_to must be specified explicitly, if it is not present in the sequence.
For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Reply.from_sequence(msg1.extract(), flags=2, in_reply_to=MessageId(0,5)) >>> msg2 Reply('$.Fred', data='12345678', in_reply_to=MessageId(0, 5), flags=0x00000002)
-
static
-
kbus.
reply_to
(original, data=None, flags=0)¶ Return a
Reply
to the givenMessage
.This is intended to be the normal way of constructing a reply message.
For instance:
>>> msg = Message('$.Fred', data='1234', from_=27, to=99, id=MessageId(0, 132), flags=Message.WANT_A_REPLY|Message.WANT_YOU_TO_REPLY) >>> msg Message('$.Fred', data='1234', to=99L, from_=27L, flags=0x00000003, id=MessageId(0, 132)) >>> reply = reply_to(msg) >>> reply Reply('$.Fred', to=27L, in_reply_to=MessageId(0, 132))
Note that:
- The message we’re constructing a reply to must be a message that wants
a reply. Specifically, this means that it must have the
Message.WANT_A_REPLY
flag set, and also theMessage.WANT_YOU_TO_REPLY
flag. This last is because anyone listening to a Request will “see” theMessage.WANT_A_REPLY
flag, but only the (single) replier will receive the message withMessage.WANT_YOU_TO_REPLY
set. - A reply message is a reply because it has the in_reply_to field set. This indicates the message id of the original message, the one we’re replying to.
- As normal, the Reply’s own message id is unset - KBUS will set this, as for any message.
- We give a specific to value, the id of the
Ksock
that sent the original message, and thus the from value in the original message. - We keep the same message name, but don’t copy the original message’s data. If we want to send data in a reply message, it will be our own data.
The other arguments available are flags (allowing the setting of flags such as
Message.ALL_OR_WAIT
, for instance), and data, allowing reply data to be added:>>> rep4 = reply_to(msg, flags=Message.ALL_OR_WAIT, data='1234') >>> rep4 Reply('$.Fred', data='1234', to=27L, in_reply_to=MessageId(0, 132), flags=0x00000100)
- The message we’re constructing a reply to must be a message that wants
a reply. Specifically, this means that it must have the
MessageId¶
-
class
kbus.
MessageId
¶ Bases:
_ctypes.Structure
A wrapper around a message id.
>>> a = MessageId(1, 2) >>> a MessageId(1, 2) >>> a < MessageId(2, 2) and a < MessageId(1, 3) True >>> a == MessageId(1, 2) True >>> a > MessageId(0, 2) and a > MessageId(1, 1) True
We support addition in a limited manner:
>>> a + 3 MessageId(1, 5)
simply to make it convenient to generate unique message ids. This returns a new MessageId - it doesn’t amend the existing one.
-
network_id
¶ Structure/Union member
-
serial_num
¶ Structure/Union member
-
Status¶
-
class
kbus.
Status
(original)¶ Bases:
kbus.messages.Message
A status message, from KBUS.
This is provided as a sugar-coating around the messages KBUS sends us. As such, it is not expected that a normal user would want to construct one, and the initialisation mechanisms are correspondingly more restrictive.
For instance:
>>> msg = Message('$.KBUS.Dummy', from_=27, to=99, in_reply_to=MessageId(0, 132)) >>> msg Message('$.KBUS.Dummy', to=99L, from_=27L, in_reply_to=MessageId(0, 132)) >>> status = Status.from_bytes(msg.to_bytes()) >>> status Status('$.KBUS.Dummy', to=99L, from_=27L, in_reply_to=MessageId(0, 132))
At the moment it is not possible to construct a Status message in any other way - it is assumed to be strictly for “wrapping” a message read (as bytes) from KBUS. Thus:
>>> msg = Status('$.Fred') Traceback (most recent call last): ... NotImplementedError: Use the Status.from_bytes() method to construct a Status
Note that:
- A status message is such because it is a (sort of)
Reply
, with the message name starting with$.KBUS.
.
-
static
from_bytes
(arg)¶ Construct a Status from bytes, as read by
Ksock.read_data()
.For instance:
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Status.from_bytes(msg1.to_bytes()) >>> msg2 Status('$.Fred', data='12345678')
-
static
from_message
(msg, data=None, to=None, from_=None, orig_from=None, final_to=None, in_reply_to=None, flags=None, id=None)¶ It is not meaningful to create a Status from another Message.
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Status.from_message(msg1, in_reply_to=MessageId(0,5)) Traceback (most recent call last): ... NotImplementedError: Status does not support the from_message() static method
-
static
from_sequence
(seq, data=None, to=None, from_=None, orig_from=None, final_to=None, in_reply_to=None, flags=None, id=None)¶ It is not meaningful to create a Status from a sequence.
>>> msg1 = Message('$.Fred', '12345678') >>> msg1 Message('$.Fred', data='12345678') >>> msg2 = Status.from_sequence(msg1.extract()) Traceback (most recent call last): ... NotImplementedError: Status does not support the from_sequence() static method
- A status message is such because it is a (sort of)
OrigFrom¶
-
class
kbus.
OrigFrom
¶ Bases:
_ctypes.Structure
A wrapper to the underlying C struct kbus_orig_from type. This is the type of
Message.orig_from
andMessage.final_to
.>>> a = OrigFrom(1, 2) >>> a OrigFrom(1, 2) >>> a < OrigFrom(2, 2) and a < OrigFrom(1, 3) True >>> a == OrigFrom(1, 2) True >>> a > OrigFrom(0, 2) and a > OrigFrom(1, 1) True
-
local_id
¶ Structure/Union member
-
network_id
¶ Structure/Union member
-