[Python] where are the sparkplug_b_pb2.Payload() methods in a Protobuf object?

Discussão em 'Python' iniciado por Stack, Setembro 4, 2025.

  1. Stack

    Stack Membro Participativo

    i am trying to untangle a Python application that uses Pahu MQTT and Protobuf. while i consider myself to be a decent coder, the docs on Protobuf are just not clicking. in particular, i have an on_message function that captures and processes messages from the MQTT broker:

    def on_message(client, userdata, msg):
    tokens = msg.topic.split("/")
    # print('payload: ',msg.payload) #<-- this is encoded spB payload
    if tokens[0] == "spBv1.0" and tokens[1] == myGroupId and tokens[3] == myNodeName:
    if tokens[2] == "NCMD" or tokens[2] == "DCMD":
    print(f'----->> {tokens[2]} payload has arrived <<-----')
    inboundPayload = sparkplug_b_pb2.Payload() #<-- trying to figure this out...
    # this is NOT working. AT ALL.
    # what i can't figure out
    # is why it just dumps out
    # of the loop! no errors,
    # nothing! just *boop*,
    # done, out.
    print('ok. inboundPayload set to sparkplug_b_pb2') # it never gets to here...
    inboundPayload.ParseFromString(msg.payload)
    print('ok. inboundPayload parsed from string') # or here... :(

    for metric in inboundPayload.metrics:
    # blah blah blah processing code goes here... but it never gets this far.


    what i can't figure out is where to find the ParseFromString() method to see what's not working. what's frustrating is that MQTT.fx sees and decodes the payloads just fine. so i know that they are coming through, but this code (which i did not write) isn't delivering the messages to the processing loops that follow. and it's making me feel quite stupid. i'd love to be able to prettyPrint the resulting JSON object so i can better visualize what's coming down the pipe, but that's just not happening here.

    from what i have learned so far, the sparkplug_b_pb2 is literally yarded right out of the documentation, as is the Payload() definition (which is confusing as hell ATM), and pasted into the Python file. the only thread that i've been able to tease out, but leads nowhere, is the Payload 'definition'(?) itself:

    Payload = _reflection.GeneratedProtocolMessageType('Payload', (_message.Message,), ...


    which leads to another rabbit hole _reflection.GeneratedProtocolMessageType which has no information in the docs (that i understand, anyway...). i also tried to find something on GeneratedProtocolMessageType to no avail. all i could find was a reference and a statement that it was 'beyond the scope of [the] tutorial'. :p

    so if anyone out there can help me get my bearings on this, i'd be most grateful. and i apologize for the long post. despite having done coding for years, i've never come across Protobuf or even heard of it until this last two months. welcome to Industrial Control...

    EDIT: i wrapped the section in a try..except block, but to no effect. here's the code:

    if tokens[2] == "NCMD" or tokens[2] == "DCMD":
    try:
    inboundPayload = sparkplug_b_pb2.Payload()
    inboundPayload.ParseFromString(msg.payload)
    print('payload: ', payload)
    except Exception as ex:
    print('cannot parse: ', str(ex.message), str(ex.args))


    EDIT 2: digging ever deeper, apparently the methods for Python are built at runtime. to that end, i tried running dir(sparkplug_b_pb2) and it barfed out an is not defined error. o_O i'm not sure what to do with this or where to go from here. for a 20yr old protocol, i am stunned at how bad the docs are for those new to the protocol. there's a lot of high-level code-fu going on here. i'm sure it would be smoother if i weren't working with an embedded system.

    Continue reading...

Compartilhe esta Página