meshtastic / firmware

Meshtastic device firmware
https://meshtastic.org
GNU General Public License v3.0
3.61k stars 898 forks source link

[Bug]: MQTT JSON does not send JSON POSITION_APP portnum data. (Other portnums work.) #1850

Closed arduionoGP closed 1 year ago

arduionoGP commented 2 years ago

Category

Other

Hardware

T-Beam, Heltec v2.1

Firmware Version

1.3.47.05147c0

Description

MQTT JSON does not send JSON POSITION_APP portnum data. This fails both when a fixed position is set on the MQTT device (lat lon alt) via CLI or when a GPS position is sent by a remote device over radio.

(MQTT JSON properly sends TELEMETRY_APP, NODEINFO_APP, TEXT_MESSAGE_APP)

Below is from the MQQT side.

TELEMETRY_APP msh/2/c/ sent protobuf {"packet":{"from":2130621128,"to":4294967295,"decoded":{"portnum":"TELEMETRY_APP","payload":"DX2QVWMSAA=="},"id":1576523471,"hopLimit":3,"priority":"MIN"},"channelId":"LongFast","gatewayId":"!7efeb2c8"} TELEMETRY_APP msh/2/json {"channel": 0, "from": 2130621128, "id": 1576523471, "payload": {"air_util_tx": 0, "battery_level": 0, "channel_utilization": 0, "voltage": 0}, "sender": "!7efeb2c8", "timestamp": 0, "to": -1, "type": "telemetry"}

POSITION_APP msh/2/c {"packet":{"from":2130621128,"to":4294967295,"decoded":{"portnum":"POSITION_APP","payload":"DVAqzRcV+uKSzBgK","wantResponse":true},"id":1576523473,"hopLimit":3,"priority":"BACKGROUND"},"channelId":"LongFast","gatewayId":"!7efeb2c8"} POSITION_APP msh/2/json NOTHING IS SENT

TEXT_MESSAGE_APP msh/2/c/ {"packet":{"from":2130624652,"to":4294967295,"decoded":{"portnum":"TEXT_MESSAGE_APP","payload":"VGVzdGluZw=="},"id":3442220266,"rxSnr":9.25,"hopLimit":2,"rxRssi":-36},"channelId":"LongFast","gatewayId":"!7efeb2c8"} TEXT_MESSAGE_AMM msh/2/json {"channel": 0, "from": 2130624652, "id": -852747030, "payload": {"text": "Testing"}, "sender": "!7efeb2c8", "timestamp": 0, "to": -1, "type": "text"}

NODEINFO_APP msh/2/c {"packet":{"from":2130621128,"to":4294967295,"decoded":{"portnum":"NODEINFO_APP","payload":"CgkhN2VmZWIyYzgSD01lc2h0YXN0aWMgYjJjOBoEYjJjOCIGlLl+/rLIKAo=","wantResponse":true},"id":845534553,"hopLimit":3,"priority":"BACKGROUND"},"channelId":"LongFast","gatewayId":"!7efeb2c8"} NODEINFO_APP msh/2/json {"channel": 0, "from": 2130621128, "id": 845534553, "payload": {"hardware": 10, "id": "!7efeb2c8", "longname": "Meshtastic b2c8", "shortname": "b2c8"}, "sender": "!7efeb2c8", "timestamp": 0, "to": -1, "type": "nodeinfo"}

Attached log file. log.txt

Relevant log output

19:36:16 85 [Router] handleReceived(REMOTE) (id=0x5747d0a3 Fr0x2c To0x8c, WantAck0, HopLim3 Ch0x0 Portnum=3 WANTRESP rxtime=1666553776 rxSNR=9.5 rxRSSI=1.84143)

19:36:16 85 [Router] Module 'position' wantsPacket=1

19:36:16 85 [Router] Received position from=0x55c7312c, id=0x5747d0a3, portnum=3, payloadlen=18

19:36:16 85 [Router] POSITION node=55c7312c l=18 LAT LON MSL TIME 

19:36:16 85 [Router] updatePosition REMOTE node=0x55c7312c time=1666553779, latI=399332295, lonI=-862857683

19:36:16 85 [Router] Node status update: 3 online, 3 total

19:36:16 85 [Router] Module 'position' considered

19:36:16 85 [Router] Module 'routing' wantsPacket=1

19:36:16 85 [Router] Received routing from=0x55c7312c, id=0x5747d0a3, portnum=3, payloadlen=18

19:36:16 85 [Router] Routing sniffing (id=0x5747d0a3 Fr0x2c To0x8c, WantAck0, HopLim3 Ch0x0 Portnum=3 WANTRESP rxtime=1666553776 rxSNR=9.5 rxRSSI=1.84143)

19:36:16 85 [Router] Rebroadcasting received floodmsg to neighbors (id=0x5747d0a3 Fr0x2c To0x8c, WantAck0, HopLim3 Ch0x0 Portnum=3 WANTRESP rxtime=1666553776 rxSNR=9.5 rxRSSI=1.84143)

19:36:16 85 [Router] Should encrypt MQTT?: 0

19:36:16 85 [Router] publish msh/2/c/LongFast/!7efeb2c8, 87 bytes

19:36:16 85 [Router] serialized json message: {"channel": 0, "from": 1439117612, "id": 1464324259, "payload": {"altitude": 274, "latitude_i": 399332295, "longitude_i": -862857683,

19:36:16 85 [Router] JSON publish message to msh/2/json/LongFast/!7efeb2c8, 260 bytes: {"channel": 0, "from": 1439117612, "id": 1464324259, "payload": {"altitude": 274, "latitude_

19:36:16 85 [Router] Expanding short PSK #1
arduionoGP commented 2 years ago

Interestingly, Heltec V2.1 will reboot after sending via CLI: "meshtastic --setlat 39.93 --setlon -86.28" once the command completes and "Setting device position" is received.

garthvh commented 2 years ago

There is a position packet there, and it has a payload. The packet is being set over MQTT here https://github.com/meshtastic/Meshtastic-device/blob/43c9ab1faabf85a2189f2fac4d9900a0daab8558/src/mqtt/MQTT.cpp#L338

arduionoGP commented 2 years ago

Yes, It seems to get through the "downstreamPacketToJson" routine (gets through the "case" statement and it gets through the "serialized json message" debug statement at the end.)

In the "onSend" section I don't see the DEBUG_MSG in the size calculation (mqtt.ccp code line 238) go by but it does get to the DEBUG "JSON publish message to" at the end of that routine.

Still trying to figure out why I don't see anything come by at the MQTT broker when it gets through most of the MQTT code and the TOPIC seems to be correct in the log. Trying a couple different boards and a different broker tonight.

arduionoGP commented 2 years ago

I wonder if this might be an MQTT QOS issue on the device?

After running awhile, I noticed that the TELEMETRY protobuf mqtt packets ceased to be followed by json mqtt packets. TEXT always seems to be followed by a json packet in my test setup as well as NODEINFO. TELEMETRY sometimes at first.

Here is my test setup and some examples. Debug Setup HeltecNodeInfo HeltecPosition HeltecTelemetry HeltecText

arduionoGP commented 2 years ago

I could find two places where QOS is mentioned in the device code. Both in the MQTT.cpp sendSubscriptions module at 168 and 171. Changed to 2, compiled and uploaded 1.3.48. Verified mqtt broker-listening nodes are set for the same: QOS=2. NODEINFO, TELEMETRY, TEXT broker receives both protobuf and json. POSITION -- the broker side receives a protobuf but no json.

caveman99 commented 2 years ago

maybe the json encode fails silenlty and the send attempt is aborted? QOS shoud not matter here.

arduionoGP commented 2 years ago

I've got it to work with a code modification - (eliminating time/pos_timestamp from the json) but I'm not sure why it does other than the mqtt send of the clear-text packet protobuf never seems to contain time/timestamp.

Commenting out the time and timestamp from the json code - causes it to send to the broker for at least a while:

image

image

??:??:?? 29 [Router] Should encrypt MQTT?: 0 ??:??:?? 29 [Router] publish msh/2/c/LongFast/!7efec08c, 61 bytes ??:??:?? 29 [Router] serialized json message: {"channel": 0, "from": 2130621128, "id": 863322701, "payload": {"altitude": 300, "latitude_i": 399300000, "longitude_i": -862800000}, ??:??:?? 29 [Router] JSON publish message to msh/2/json/LongFast/!7efec08c, 202 bytes: {"channel": 0, "from": 2130621128, "id": 863322701, "payload": {"altitude": 300, "latitude_i ??:??:?? 29 [Router] {"channel": 0, "from": 2130621128, "id": 863322701, "payload": {"altitude": 300,"latitude_i": 399300000, "longitude_i": -862800000}, "sender": "!7efec08c", "timestamp": 0, "to": -1, "type": "position"}Expanding short PSK #1 ??:??:?? 29 [Router] Using AES128 key!

image

arduionoGP commented 2 years ago

Tested with several devices. Pull request sent.

arduionoGP commented 2 years ago

After throwing some more debug statements I think the issue is that there are situations where: "time" and "pos_timestamp" often do not exist in the protobuf made by my t-beam. There is also a situation where "altitude" is not encoded in the protobuf. This last situation happens when fixed lat/long are set by CLI and altitude is not set with GPS turned off. (So three possible situations.)

json11 library looks like it doesn't put in a default value for a key that's not in the decoded protobuf and the json object once created with the library is pretty immutable. It can copied in an expensive operation like: https://www.appsloveworld.com/cplus/100/391/how-to-modify-a-json-object-using-json11-library. The object keys can also be counted after they are made like: .object_items().count(key).

Wondering if the best final solution might be either making space for default values in the protobuf or by sticking in some if statements before building the object.

garthvh commented 2 years ago

You have to specify the inclusion of the pos_timestamp or it will not be in the packet

garthvh commented 2 years ago

AA742E7A-0089-472F-8C88-5A2C91A3E374

garthvh commented 2 years ago

Altitude is in the packet by default but can be turned off

arduionoGP commented 2 years ago

Yes, but the JSON MQTT should work regardless of whether you are using GPS, fixed position, timestamp or not.

With proto3, all those fields are optional. Those that have the default values (like 0) are not encoded into the protobuf - and with the current code this will break when the json j11 library tries to get those fields from the nanodb-decoded protobuf. All the JSON MQTT works except for position_app.

The JSON encoding needs to account for which fields are or are/not present in the protobuf provided to the MQTT routines.

arduionoGP commented 2 years ago

POSITION_APP failing to be broadcast to MQTT broker is not expected behavior when TEXT_MESSAGE_APP, TELEMETRY_APP, and NODEINFO_APP all work.

arduionoGP commented 2 years ago

OK, I give up. Unless both time and pos_timestamp are commented out (as in my pull request) --there is no JSON sent by MQTT, even when I give them dummy acceptable numbers or just comment out one or the other. image image

garthvh commented 1 year ago

JSON library replaced, please re-test after build is released

arduionoGP commented 1 year ago

It's odd. When I first updated and later fresh installed the new 2.0.4.5417671 alpha on two t-beams v1.1, Neither can get a GPS fix when they were working earlier on 2.0.3. I'll look into it tomorrow some more.

arduionoGP commented 1 year ago

Fixed GPS position, newest v2.0.5 on tbeam1.1 with fixed Position set (lat,lon,alt) - does not sent json decoded message to mqtt. It does send cleartext to mqtt correctly with "time" as "undefined". image

arduionoGP commented 1 year ago

V2.0.5.65e8209 on t-beam cannot see any satellites. When downgraded back to 2.0.3 GPS works again. Tried three different hardware units. Unable to test the GPS-JSON situation further because of this. As above, fixed position does not send JSON to MQTT.

arduionoGP commented 1 year ago

V2.0.6 on T-beam is able to see satellites and get position again. Unfortunately, while GPS encoded msh/2/c/ position packets come out, JSON packet do not.

arduionoGP commented 1 year ago

image

arduionoGP commented 1 year ago

Node-info works in json under2.0.6 image

Telemetry_APP does not.

arduionoGP commented 1 year ago

Was looking into other libraries and found this thread-safe one https://arduinojson.org/

garthvh commented 1 year ago

It is huge

arduionoGP commented 1 year ago

v2.0.7 Position spits out correct JSON if I comment out both "time" and "timestamp" in the case section of mqtt.cpp. image.

It will also send out correct JSON if I just comment out "timestamp" image

image

If I leave the entire section as is, no JSON comes out, only msh/2/c/. The problem seems to be with timestamp.

garthvh commented 1 year ago

Timestamp probably works if you enable the position flag, it is not enabled by default.

garthvh commented 1 year ago

You can easily enable it on your node on either android or iOS

arduionoGP commented 1 year ago

These if statements seem to fix it so it works under all position circumstances.

image

arduionoGP commented 1 year ago

Confirmed that TEXT_MESSAGE_APP, TELEMETRY_APP, NODEINFO_APP, POSITION_APP all work with JSON encoding on device -> MQTT with update as above on t-beam