简体   繁体   中英

How to publish multiple numbers via MQTT?

I'm working on remotecontrolling a watering system via smartphone using MQTT to control the valves connected to a raspberry pi. Up till now, I had the raspberry pi subscribe to multiple topics ('watering/frontLawn', 'watering/backLawn') and interpret the payload as the watering duration. Now I want to add a way to schedule waterings, which requires to additionally send the time, when the watering is supposed to take place. So startTime and duration needs to be send on a specific topic. Something like wateringInfo = [1563532789, 300] # in the form [startTime, duration]

Is there a recommended way of transferring information like this?

So far my only idea was to combine the two numbers:

startTime*1000+duration # assuming duration is maxed at 999

send them and retrieve using:

retrievedStartTime = int(msg.payload) / 1000
retrievedDuration = int(msg.payload) % 1000

This seems like an error prone way of doing things. Is there a different way, maybe even directly transfer the array?

How you pack/serialize data is entirely up to you and will depend on multiple factors including (but not exclusively):

  1. What type of system is producing the data (is it very limited capability sensor)?
  2. What is consuming the data (see above)?
  3. Does the data need to be human readable?
  4. Are you concerned with how big the message is (are you paying by the byte)?

Some sample options include:

  1. JSON/XML These are both mark up languages that allow you to include a huge amount of structure and context along with the values. But they are also human readable.
  2. CSV (comma separated variables) this is human readable, but you need to know what the position of each variable in the list maps to.
  3. Protobuf again this allows you to include structure, but at a binary level so not human readable.
  4. raw fixed width fields, you just say that each value is going to fit into the range of what can be represented by a fixed number of bytes. eg -128 to + 128 (or 0 to 255) can be represented by a single byte and you just predefine the number of bytes for each field and their order. This is basically CSV, but without the separator chars and using the smallest amount of space to pass the information.

There are loads more other options, but they are mainly variations on the 3 described above. Which you pick will depend on the at least the factors listed and how low level you want to get when implementing it.

I suggest using "watering/frontLawn/info" topic and send the message as a string which would be so easily parsed on the other side.

Publisher:

client.publish(topic="watering/frontLawn/info", 
               payload=str(start)+","+str(end), qos=1, retain=False)

Subscriber:

client.subscribe(topic="watering/frontLawn/info", qos=1)

Parsing Part:

info = message.payload.split(",")

Now you have a list as follows:

 info = ["start", "end"]

To get info:

start = int(info[0])
end = int(info[1])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM