diff --git a/docs/about/contributing.mdx b/docs/about/contributing.mdx index 044ce2bf..cdd1c279 100644 --- a/docs/about/contributing.mdx +++ b/docs/about/contributing.mdx @@ -23,7 +23,7 @@ There are many technologies (and repositories) used in creating the Meshtastic e ### Protocol Buffers -Most communication and interactions happen with protocol buffers. The [Meshtastic Protobuf Definitions](https://github.com/meshtastic/protobufs) repo is where all of the protocol buffer changes happen. See the [Protobuf API Reference](/docs/developers/protobufs/api) for more details. +Most communication and interactions happen with protocol buffers. The [Meshtastic Protobuf Definitions](https://github.com/meshtastic/protobufs) repo is where all of the protocol buffer changes happen. See the [Protobuf API Reference](https://buf.build/meshtastic/protobufs/) for more details. ### Device Firmware @@ -44,10 +44,10 @@ The [firmware](https://github.com/meshtastic/firmware) is where all of the firmw @sachaw has been making tons of progress on the web app and would love help with: -* Saving of preferences -* Better loading state indicators -* Chat scroll lock -* Various module support +- Saving of preferences +- Better loading state indicators +- Chat scroll lock +- Various module support ### Mobile Apps (Device Interface) @@ -59,4 +59,3 @@ There are two phone apps that interact with the Meshtastic devices: ### Documentation This website is in the [Meshtastic](https://github.com/meshtastic/meshtastic) repository. - diff --git a/docs/about/overview/mesh-alg.mdx b/docs/about/overview/mesh-alg.mdx index 5a9336c2..ade2d43d 100644 --- a/docs/about/overview/mesh-alg.mdx +++ b/docs/about/overview/mesh-alg.mdx @@ -25,23 +25,23 @@ This preamble allows receiving radios to synchronize clocks and start framing. W This layer is conventional non-reliable LoRa packet transmission. The transmitted packet has the following representation before encoding for transmission: -| Offset | Length | Type | Usage | -|:------------:|:-----------------------------:|:-------:|:---------------------------------------------------------------------------------------- | -| 0x00 | 1 byte | Integer | syncWord, always `0x2B`. | -| 0x01 | 4 bytes | Integer | Packet header: Destination. The destination's unique NodeID. `0xFFFFFFFF` for broadcast. | -| 0x05 | 4 bytes | Integer | Packet Header: Sender. The sender's unique NodeID. | -| 0x09 | 4 bytes | Integer | Packet Header: The sending node's unique packet ID for this packet. | -| 0x0D | 32 bits | Bits | Packet Header: Flags. See the [header flags](#packet-header-flags) for usage. | -| 0x11 .. 0xFD | Varies, maximum of 237 bytes. | Bytes | Actual packet data. Unused bytes are not transmitted. | -| 0xFE .. 0xFF | 2 Bytes | Bytes | Unused. | +| Offset | Length | Type | Usage | +| :----------: | :---------------------------: | :-----: | :--------------------------------------------------------------------------------------- | +| 0x00 | 1 byte | Integer | syncWord, always `0x2B`. | +| 0x01 | 4 bytes | Integer | Packet header: Destination. The destination's unique NodeID. `0xFFFFFFFF` for broadcast. | +| 0x05 | 4 bytes | Integer | Packet Header: Sender. The sender's unique NodeID. | +| 0x09 | 4 bytes | Integer | Packet Header: The sending node's unique packet ID for this packet. | +| 0x0D | 32 bits | Bits | Packet Header: Flags. See the [header flags](#packet-header-flags) for usage. | +| 0x11 .. 0xFD | Varies, maximum of 237 bytes. | Bytes | Actual packet data. Unused bytes are not transmitted. | +| 0xFE .. 0xFF | 2 Bytes | Bytes | Unused. | #### Packet Header Flags -| Index | # of Bits | Usage | -|:-------:|:---------:|:------------------------------| -| 0 | 3 | HopLimit (see note in Layer 3) | -| 3 | 1 | WantAck | -| 4 .. 32 | 28 | Currently unused | +| Index | # of Bits | Usage | +| :-----: | :-------: | :----------------------------- | +| 0 | 3 | HopLimit (see note in Layer 3) | +| 3 | 1 | WantAck | +| 4 .. 32 | 28 | Currently unused | #### Usage Details @@ -51,7 +51,7 @@ This layer is conventional non-reliable LoRa packet transmission. The transmitte - **Packet Header - Unique ID:** The ID is a large, 32 bit ID to ensure there is enough unique state to protect an encrypted payload from attack. -- **Payload:** An encrypted and packed protobuf encoding of the SubPacket protobuf. Only the SubPacket is encrypted, while headers are not. This allows the option of eventually allowing nodes to route packets without knowing anything about the encrypted payload. For more information, see the [encryption](/docs/overview/encryption) and [protobufs](/docs/developers/protobufs/api) documentation. Any data past the maximum length is truncated. +- **Payload:** An encrypted and packed protobuf encoding of the SubPacket protobuf. Only the SubPacket is encrypted, while headers are not. This allows the option of eventually allowing nodes to route packets without knowing anything about the encrypted payload. For more information, see the [encryption](/docs/overview/encryption) and [Protobuf API Reference](https://buf.build/meshtastic/protobufs/). Any data past the maximum length is truncated. #### Carrier-Sense Multiple Access with Collision Avoidance (CSMA/CA) diff --git a/docs/configuration/module-config/range-test.mdx b/docs/configuration/module-config/range-test.mdx index ef2bdedf..5b8835de 100644 --- a/docs/configuration/module-config/range-test.mdx +++ b/docs/configuration/module-config/range-test.mdx @@ -5,12 +5,12 @@ slug: /settings/moduleconfig/range-test sidebar_label: Range Test --- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; +import Tabs from "@theme/Tabs"; +import TabItem from "@theme/TabItem"; This module allows you to test the range of your Meshtastic nodes. It requires at least two nodes, a sender and a receiver. The receiving node then saves the messages along with the GPS coordinates at which they were received into a .csv file. This .csv file can then be integrated into [Google Earth](https://earth.google.com), [Google Maps - My Maps](https://mymaps.google.com), or any other program capable of processing .csv files. This can enable you to visualize your mesh. -The range test module config options are: Enabled, Save, and Sender. Range Test Module config uses an admin message sending a `ConfigModule.RangeTest` protobuf. +The range test module config options are: Enabled, Save, and Sender. Range Test Module config uses an admin message sending a `ConfigModule.RangeTest` protobuf. ## Range Test Module Config Values @@ -66,8 +66,8 @@ Range Test module config options are available in the python CLI. Example comman ::: -| Setting | Acceptable Values | Default | -| :-----------------------: | :-----------------: | :-----: | +| Setting | Acceptable Values | Default | +| :----------------: | :-----------------: | :-----: | | range_test.enabled | `true`, `false` | `false` | | range_test.save | `true`, `false` | `false` | | range_test.sender | `integer` (Seconds) | `0` | @@ -121,7 +121,7 @@ Be sure to turn off either the module configured as a sender or the device where Also be mindful of your space usage on the file system. It has protections from filling up the space but it's best to delete old range test results. :::note -Leaving this module on can slow down your mesh. Currently, the messages are sent using the same `TEXT_MESSAGE_APP` [port that all other messages](/docs/developers/protobufs/api#portnumsproto) are sent on. +Leaving this module on can slow down your mesh. Currently, the messages are sent using the same `TEXT_MESSAGE_APP` [port that all other messages](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.PortNum) are sent on. ::: ### Accessing your CSV @@ -137,12 +137,10 @@ http://198.168.0.15 | Radio Setting | `range_test.sender` | | :-----------: | :-----------------: | -| Long Slow | 60 | -| Long Alt | 30 | -| Medium | 15 | -| Short Fast | 15 | - - +| Long Slow | 60 | +| Long Alt | 30 | +| Medium | 15 | +| Short Fast | 15 | ## Application Examples diff --git a/docs/configuration/remote-admin.mdx b/docs/configuration/remote-admin.mdx index 238c21c8..898f6c0e 100644 --- a/docs/configuration/remote-admin.mdx +++ b/docs/configuration/remote-admin.mdx @@ -151,7 +151,7 @@ Completed getting preferences For further reading, I recommend starting out with [Meshtastic-python](/docs/software/python/cli/) if you haven't already gone through this (hopefully you have since you are reading this). But for a full reference to the settings you can change, please see: [Settings Overview](/docs/settings) and -[Complete list of user settings in Protobufs](/docs/developers/protobufs/api#radioconfiguserpreferences) +[Complete list of user settings in Protobufs](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.User) ## Areas for future development diff --git a/docs/development/device/error-codes.mdx b/docs/development/device/error-codes.mdx index 0569edac..625609cd 100644 --- a/docs/development/device/error-codes.mdx +++ b/docs/development/device/error-codes.mdx @@ -8,19 +8,19 @@ sidebar_position: 4 The device might report these fault codes on the screen, but it will also be outputted on the device serial output. If you encounter a fault code, please post on the forum and we'll try to help. :::note -This table is derived from the [protobufs](/docs/developers/protobufs/api#criticalerrorcode) +This table is derived from the [protobufs](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.CriticalErrorCode) ::: -| Name | Number | Description | -|:------------------- :|:------:|:----------------------------------------------------------------------------------------------------------------------- | -| TxWatchdog | 1 | A software bug was detected while trying to send LoRa | -| SleepEnterWait | 2 | A software bug was detected on entry to sleep | -| NoRadio | 3 | No LoRa radio hardware could be found | -| Unspecified | 4 | Not normally used | -| UBloxInitFailed | 5 | We failed while configuring a UBlox GPS | -| NoAXP192 | 6 | This board was expected to have a power management chip and it is missing or broken | -| InvalidRadioSetting | 7 | The channel tried to set a radio setting which is not supported by this chipset, radio comms settings are now undefined | -| TransmitFailed | 8 | Radio transmit hardware failure. We sent data to the radio chip, but it did not reply with an interrupt | -| Brownout | 9 | We detected that the main CPU voltage dropped below the minimum acceptable value | -| SX1262Failure | 10 | Selftest of SX1262 radio chip failed | -| RadioSpiBug | 11 | A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug | +| Name | Number | Description | +| :-----------------: | :----: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| TxWatchdog | 1 | A software bug was detected while trying to send LoRa | +| SleepEnterWait | 2 | A software bug was detected on entry to sleep | +| NoRadio | 3 | No LoRa radio hardware could be found | +| Unspecified | 4 | Not normally used | +| UBloxInitFailed | 5 | We failed while configuring a UBlox GPS | +| NoAXP192 | 6 | This board was expected to have a power management chip and it is missing or broken | +| InvalidRadioSetting | 7 | The channel tried to set a radio setting which is not supported by this chipset, radio comms settings are now undefined | +| TransmitFailed | 8 | Radio transmit hardware failure. We sent data to the radio chip, but it did not reply with an interrupt | +| Brownout | 9 | We detected that the main CPU voltage dropped below the minimum acceptable value | +| SX1262Failure | 10 | Selftest of SX1262 radio chip failed | +| RadioSpiBug | 11 | A (likely software but possibly hardware) failure was detected while trying to send packets. If this occurs on your board, please post in the forum so that we can ask you to collect some information to allow fixing this bug | diff --git a/docs/development/firmware/port-numbers.mdx b/docs/development/firmware/port-numbers.mdx index a9cf4888..6afcb940 100644 --- a/docs/development/firmware/port-numbers.mdx +++ b/docs/development/firmware/port-numbers.mdx @@ -6,15 +6,15 @@ sidebar_label: Port Numbers Any new app that runs on the device or via sister apps on phones/PCs should pick and use a unique "portnum" for their applications use. -The current list of port numbers can be found listed in the [protobufs](/docs/developers/protobufs/api#portnumsproto) +The current list of port numbers can be found listed in the [protobufs](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.CriticalErrorCode) ## Assignment PortNums should be assigned by the following ranges: | Portnum | Usage | -|:-------:|:---------------------------------------------------------------------------------------------------------------------- | -| 0-63 | Core Meshtastic use, do not use for third party apps. | +| :-----: | :--------------------------------------------------------------------------------------------------------------------- | +| 0-63 | Core Meshtastic use, do not use for third party apps. | | 64-127 | Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application | | 256-511 | Use one of these portnums for your private applications that you do not want to register publicly | @@ -22,4 +22,4 @@ All other values are reserved. ## Integration -If you are making a new app using Meshtastic, please send a pull request to add your chosen "portnum" to this master table. \ No newline at end of file +If you are making a new app using Meshtastic, please send a pull request to add your chosen "portnum" to this master table. diff --git a/docs/software/mqtt/index.mdx b/docs/software/mqtt/index.mdx index 450d2f83..6e7c8ed1 100644 --- a/docs/software/mqtt/index.mdx +++ b/docs/software/mqtt/index.mdx @@ -102,7 +102,7 @@ If the channelid 'well known'/public it could be decrypted by a web service (if #### Service Envelope -The payload published on mesh/... will always be wrapped in a [ServiceEnvelope protobuf](/docs/developers/protobufs/api#serviceenvelope). +The payload published on mesh/... will always be wrapped in a [ServiceEnvelope protobuf](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.ServiceEnvelope). ServiceEnvelope will include the message, and full information about arrival time, who forwarded it, source channel, source mesh id, etc... @@ -230,13 +230,13 @@ if __name__ == '__main__': Below is a valid JSON envelope for information sent by MQTT to a device for broadcast onto the mesh. - ```json - { - "sender":"whatever you want to be the SENDER", - "type":"sendtext", - "payload": text or a json object go here - } - ``` +```json +{ + "sender":"whatever you want to be the SENDER", + "type":"sendtext", + "payload": text or a json object go here +} +``` Node-RED is a free cross-platform programming tool for wiring together hardware, APIs, and online services developed originally by IBM for IOT. It is widely used for home automation by many non-professional programmers and runs well on Pi's. Node-red has many plug-in modules written by the community. I will use this platform as a practical example on how to interface with the MQTT features of Meshtastic. Everything can be done from GUI's without using command line. @@ -244,11 +244,11 @@ Step one: use http://client.meshtastic.org/ one of the Apple apps or the CLI to Enable and enter network SSID/PSK. Settings--> Device Config--> Network; Save. Set MQTT server address. Settings--> Module Config--> MQTT config; Verify Encryption Enabled is OFF. Turn JSON Output Enabled ON. Save. Go to Channel Editor and set Uplink and Downlink enabled to True. Save. There is currently a bug for setting Uplink and Downlink Saving for the default channel. If you encounter this use the CLI commands: - ``` + +``` meshtastic --ch-index 0 --ch-set uplink_enabled true meshtastic --ch-index 0 --ch-set downlink_enabled true - ``` - +``` Step two: if you don't want to depend on JSON decoding on the device, you can decode the protobuf messages off-device. To do that you will need to get the .proto files from https://github.com/meshtastic/protobufs. They function as a schema and are required for decoding in Node-RED. Save the files where the node-RED application can access them and note the file path of the "mqtt.proto" file. @@ -273,9 +273,11 @@ Forwarding a text message from one device, through a broker, to another broker/d If you want to decode text and position messages without json, it gets complicated: [](/documents/mqtt/DecodeNewest.jpg) If you are interested in my flow for this it is here: - ``` + +``` [{"id":"10fe1b2e9cb3feb2","type":"decode","z":"23dbb1ee.bc2e8e","name":"decode Protobuf","protofile":"a0d4288141f6a629","protoType":"ServiceEnvelope","x":295.5,"y":285,"wires":[["d3e396cf4f0a9608","d08865b41a69d85d","6f592d47b6a2eac4"]]},{"id":"40c9ee66fe7a34cb","type":"function","z":"23dbb1ee.bc2e8e","name":"function get the message as string from TEXT_MESSAGE_APP","func":"msg.payload = msg.payload.packet.decoded.payload;\n\nlet bufferObj = Buffer.from(msg.payload, \"base64\");\nlet decodedString = bufferObj.toString(\"utf8\");\nmsg.payload = decodedString;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":410.5,"y":450,"wires":[["553374591214eaca"]]},{"id":"553374591214eaca","type":"debug","z":"23dbb1ee.bc2e8e","name":"text message out","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":762.5,"y":449,"wires":[]},{"id":"c6afbb9f1665b162","type":"debug","z":"23dbb1ee.bc2e8e","name":"channelId","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":785.5,"y":257,"wires":[]},{"id":"607ef387d5701985","type":"debug","z":"23dbb1ee.bc2e8e","name":"gatewayId","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":792.5,"y":293,"wires":[]},{"id":"d3e396cf4f0a9608","type":"debug","z":"23dbb1ee.bc2e8e","name":"entire payload","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":296.5,"y":247,"wires":[]},{"id":"2339b328bb9bb1d8","type":"comment","z":"23dbb1ee.bc2e8e","name":"Decode all cleartext text and position messages sent by Meshtastic devices into JSON without relying on JSON conversion on the device.","info":"","x":515.5,"y":214,"wires":[]},{"id":"408d796d997bb832","type":"function","z":"23dbb1ee.bc2e8e","name":"function get the nested payload as base64","func":"msg.payload = msg.payload.packet.decoded.payload;\n\nlet bufferObj = Buffer.from(msg.payload, \"base64\");\n//let decodedString = bufferObj.toString(\"hex\");\nmsg.payload = bufferObj;\nmsg.topic=\"\";\n//if you don't zero out the protubufTopic it will try to\n//decode it as part of the mqtt service envelope instead\n//of two-stage decoding\nmsg.protobufType=null;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":349,"y":552,"wires":[["9435a3c605efedb4","1ed6f96c8214d7b3"]]},{"id":"61995c9f8e8266b3","type":"debug","z":"23dbb1ee.bc2e8e","name":"portnum","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":784.5,"y":330,"wires":[]},{"id":"9435a3c605efedb4","type":"debug","z":"23dbb1ee.bc2e8e","name":"nested payload","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":281.5,"y":603,"wires":[]},{"id":"b832775d386f7ac9","type":"mqtt in","z":"23dbb1ee.bc2e8e","name":"","topic":"msh/+/c/#","qos":"2","datatype":"buffer","broker":"37cadac381653b1e","nl":false,"rap":true,"rh":0,"inputs":0,"x":117.5,"y":286,"wires":[["10fe1b2e9cb3feb2"]]},{"id":"d08865b41a69d85d","type":"switch","z":"23dbb1ee.bc2e8e","name":"switch manual decoding nested message based on portum","property":"payload.packet.decoded.portnum","propertyType":"msg","rules":[{"t":"eq","v":"TEXT_MESSAGE_APP","vt":"str"},{"t":"eq","v":"POSITION_APP","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":281.5,"y":505,"wires":[["40c9ee66fe7a34cb"],["408d796d997bb832"]]},{"id":"8abb1bb458af2c4f","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"gatewayId","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1021.5,"y":288,"wires":[[]]},{"id":"1ced0be28eeef0d3","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"latitude","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1026.5,"y":407,"wires":[[]]},{"id":"313fd3cfe6d91850","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"longitude","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1036.5,"y":450,"wires":[["d02e53cdfb565da6"]]},{"id":"33dd43e3c05f826c","type":"geofence","z":"23dbb1ee.bc2e8e","name":"geofence","mode":"circle","inside":"true","rad":69174.91569647488,"points":[],"centre":{"latitude":40.16287050252407,"longitude":-86.60385131835938},"floor":"","ceiling":"","worldmap":true,"outputs":2,"x":1202.5,"y":595,"wires":[[],["4d01eb8f1b31f039"]]},{"id":"d02e53cdfb565da6","type":"function","z":"23dbb1ee.bc2e8e","name":"trigger function to send a mapping point","func":"let lat = parseFloat(flow.get(\"latitude\"));\nlet lon = parseFloat(flow.get(\"longitude\"));\nlat=lat * 0.0000001;\nlon=lon * 0.0000001;\nlet name = flow.get(\"from\")\n\nmsg={\"payload\":{\"name\":name,\n \"lat\":lat,\n \"lon\":lon,\n \"action\":\"send\",\n \"icon\": \"car\",\n \"label\":name\n }}\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1181.5,"y":520,"wires":[["33dd43e3c05f826c","4d01eb8f1b31f039"]]},{"id":"4d01eb8f1b31f039","type":"worldmap","z":"23dbb1ee.bc2e8e","name":"","lat":"40","lon":"-86","zoom":"7","layer":"OSMG","cluster":"","maxage":"","usermenu":"show","layers":"show","panit":"false","panlock":"false","zoomlock":"false","hiderightclick":"false","coords":"none","showgrid":"false","showruler":"false","allowFileDrop":"false","path":"/worldmap","overlist":"DR,CO,RA,DN,HM","maplist":"OSMG,OSMC,EsriC,EsriS,EsriT,EsriDG,UKOS","mapname":"","mapurl":"","mapopt":"","mapwms":false,"x":1206.5,"y":675,"wires":[]},{"id":"1ed6f96c8214d7b3","type":"decode","z":"23dbb1ee.bc2e8e","name":"decode Position Protobuf","protofile":"dbab6472b07929a0","protoType":"Position","x":667.5,"y":548,"wires":[["db1933ba36503bd9","dad9f487318f21d9"]]},{"id":"db1933ba36503bd9","type":"debug","z":"23dbb1ee.bc2e8e","name":"Position decoded","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":673.5,"y":607,"wires":[]},{"id":"dad9f487318f21d9","type":"function","z":"23dbb1ee.bc2e8e","name":"Split","func":"var lat = { payload: msg.payload.latitudeI };\nvar lon = { payload: msg.payload.longitudeI };\nvar alt = { payload: msg.payload.altitude };\nvar tm = { payload: msg.payload.time };\n\nreturn [lat,lon,alt,tm];","outputs":4,"noerr":0,"initialize":"","finalize":"","libs":[],"x":875.5,"y":549,"wires":[["1ced0be28eeef0d3","8bb97f802662976c"],["313fd3cfe6d91850","c8e135f3e542bb1b"],["602fb2020680280c"],["ed424ae3d45dd2ac"]]},{"id":"8bb97f802662976c","type":"debug","z":"23dbb1ee.bc2e8e","name":"lat","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1017.5,"y":583,"wires":[]},{"id":"c8e135f3e542bb1b","type":"debug","z":"23dbb1ee.bc2e8e","name":"lon","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1018.5,"y":618,"wires":[]},{"id":"602fb2020680280c","type":"debug","z":"23dbb1ee.bc2e8e","name":"alt","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1017.5,"y":654,"wires":[]},{"id":"ed424ae3d45dd2ac","type":"debug","z":"23dbb1ee.bc2e8e","name":"time","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1018.5,"y":688,"wires":[]},{"id":"6f592d47b6a2eac4","type":"function","z":"23dbb1ee.bc2e8e","name":"Split Decoded 1","func":"var channelId = { payload: msg.payload.channelId};\nvar gatewayId = { payload: msg.payload.gatewayId};\nvar portnum = { payload: msg.payload.packet.decoded.portnum};\nvar fr= {payload: \"!\" + msg.payload.packet.from.toString(16)};\nvar to = {payload:\"!\"+ msg.payload.packet.to.toString(16)};\n\nreturn [channelId, gatewayId, portnum, fr, to ];","outputs":5,"noerr":0,"initialize":"","finalize":"","libs":[],"x":577.5,"y":294,"wires":[["c6afbb9f1665b162"],["607ef387d5701985","8abb1bb458af2c4f"],["61995c9f8e8266b3"],["fd881fac22422773","a389f9875da672ec"],["cf066ad415df30ae"]]},{"id":"fd881fac22422773","type":"debug","z":"23dbb1ee.bc2e8e","name":"from","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":772.5,"y":365,"wires":[]},{"id":"cf066ad415df30ae","type":"debug","z":"23dbb1ee.bc2e8e","name":"to","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":771.5,"y":399,"wires":[]},{"id":"a389f9875da672ec","type":"change","z":"23dbb1ee.bc2e8e","name":"set flow.from","rules":[{"t":"set","p":"from","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":1012.5,"y":364,"wires":[[]]},{"id":"a0d4288141f6a629","type":"protobuf-file","protopath":"E:\\Meshtastic-protobufs-master\\mqtt.proto","watchFile":true,"keepCase":false},{"id":"37cadac381653b1e","type":"mqtt-broker","name":"","broker":"192.168.2.45","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":"4","keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closeQos":"0","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"dbab6472b07929a0","type":"protobuf-file","protopath":"E:\\Meshtastic-protobufs-master\\mesh.proto","watchFile":true,"keepCase":false}] - ``` +``` + (documents/mqtt/Flow.txt) Node-red can rapidly (minutes vs days) put together some pretty impressive output when paired with meshtastic. Here is the output of that flow geofencing and mapping via mqtt data. @@ -284,23 +286,25 @@ Node-red can rapidly (minutes vs days) put together some pretty impressive outpu Advanced use, such as encoding Position and sending it to a device via MQTT without using JSON can get a little complicated. An example of how it can be done is below. [](/documents/mqtt/EncodingPosition.jpg) The flow is: - ``` + +``` [{"id":"32ca608d9e7c5236","type":"inject","z":"23dbb1ee.bc2e8e","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":96.5,"y":1952,"wires":[["2b536512e8c7aef2"]]},{"id":"20bbd2d1408b8dc5","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"channelId_outbound","pt":"flow","to":"LongFast","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":772,"y":2027,"wires":[[]]},{"id":"c6cb373157be01d6","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"gatewayId_outbound","pt":"flow","to":"\"!55c7312c\"","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":772,"y":2066,"wires":[[]]},{"id":"24199ec7eaf89c1a","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"portnum_outbound","pt":"flow","to":"3","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":774,"y":2106,"wires":[[]]},{"id":"de38ad5ef343623a","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"from_outbound","pt":"flow","to":"1439117612","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":781,"y":2146,"wires":[[]]},{"id":"d435e8abe0852f93","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"to_outbound","pt":"flow","to":"4294967295","tot":"num"}],"action":"","property":"","from":"","to":"","reg":false,"x":790,"y":2188,"wires":[[]]},{"id":"1f8d172708898860","type":"function","z":"23dbb1ee.bc2e8e","name":"Assemble Position protobuf","func":"msg.protobufType=null;\nmsg.payload =\n{\n \"packet\": {\n \"from\": flow.get(\"from_outbound\"),\n \"to\": flow.get(\"to_outbound\"), \n \"decoded\":{\n //how ENUMS are handled here\n //portnum is decoded as string but encoded as number\n //in the encode/decode node-red nodes based on protobuf.js\n \"portnum\": flow.get(\"portnum_outbound\"),\n \"payload\": msg.payload \n } \n },\n\n \"channelId\": flow.get(\"channelId_outbound\"),\n \"gatewayId\": flow.get(\"gatewayId_outbound\"),\n};\nreturn msg;\n//info on how to get json data into protobuf \"bytes\" field\n//https://github.com/protobufjs/protobuf.js/wiki/Changes-in-ProtoBuf.js-3.8","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1086,"y":2019,"wires":[["b8ccf1cfe8bf40a3"]]},{"id":"b8ccf1cfe8bf40a3","type":"encode","z":"23dbb1ee.bc2e8e","name":"","protofile":"a0d4288141f6a629","protoType":"ServiceEnvelope","x":1287,"y":2020,"wires":[["dbc78f035c9c2b56","a002c148f3a06bac"]]},{"id":"03a7e69ca6d471fe","type":"debug","z":"23dbb1ee.bc2e8e","name":"show hex string","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":1319,"y":2180,"wires":[]},{"id":"dbc78f035c9c2b56","type":"function","z":"23dbb1ee.bc2e8e","name":"dump payload as hex string","func":"var hex=Buffer.from(msg.payload,\"hex\");\nmsg.payload=hex.toString(\"hex\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1096,"y":2178,"wires":[["03a7e69ca6d471fe"]]},{"id":"2b536512e8c7aef2","type":"function","z":"23dbb1ee.bc2e8e","name":"Inject lat lon alt","func":"msg.payload={\n \"latitudeI\": 399600000,\n \"longitudeI\": -862600000,\n \"altitude\": 100\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":277.5,"y":1953,"wires":[["9443a9a980e54c75"]]},{"id":"9443a9a980e54c75","type":"encode","z":"23dbb1ee.bc2e8e","name":"encode Position as protobuf","protofile":"dbab6472b07929a0","protoType":"Position","x":506,"y":1953,"wires":[["5c36d3a7f4dca14e"]]},{"id":"5c36d3a7f4dca14e","type":"change","z":"23dbb1ee.bc2e8e","name":"","rules":[{"t":"set","p":"nested_outbound","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":776,"y":1952,"wires":[["20bbd2d1408b8dc5","c6cb373157be01d6","24199ec7eaf89c1a","de38ad5ef343623a","d435e8abe0852f93","04d0c4a5f3485c6f"]]},{"id":"04d0c4a5f3485c6f","type":"function","z":"23dbb1ee.bc2e8e","name":"dump payload as base64 string","func":"var hex=Buffer.from(msg.payload,\"base64\");\nmsg.payload=hex.toString(\"base64\");\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1082,"y":1952,"wires":[["1f8d172708898860"]]},{"id":"a002c148f3a06bac","type":"decode","z":"23dbb1ee.bc2e8e","name":"test decode Protobuf","protofile":"a0d4288141f6a629","protoType":"ServiceEnvelope","x":1249,"y":1860,"wires":[["4b6fc79398d05782"]]},{"id":"4b6fc79398d05782","type":"debug","z":"23dbb1ee.bc2e8e","name":"test entire payload","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1458,"y":1859,"wires":[]},{"id":"a0d4288141f6a629","type":"protobuf-file","protopath":"E:\\Meshtastic-protobufs-master\\mqtt.proto","watchFile":true,"keepCase":false},{"id":"dbab6472b07929a0","type":"protobuf-file","protopath":"E:\\Meshtastic-protobufs-master\\mesh.proto","watchFile":true,"keepCase":false}] - ``` +``` Sending a position to a device for broadcast to the mesh is much easier with JSON. This introduces a new MQTT Service Envelope type: "sendposition". A valid MQTT envelope and message to broadcast lat, lon, altitude looks like this. -```json -{ - "sender": "someSender", - "type": "sendposition", - "payload": { - "latitude_i": 399600000, - "longitude_i": -862600000, - "altitude": 100, - "time": 1670201543 - } -} - ``` +```json +{ + "sender": "someSender", + "type": "sendposition", + "payload": { + "latitude_i": 399600000, + "longitude_i": -862600000, + "altitude": 100, + "time": 1670201543 + } +} +``` + An example of doing this in node-red: [](/documents/mqtt/PosJSON.jpg) diff --git a/docs/software/python-cli/usage.mdx b/docs/software/python-cli/usage.mdx index 56eff6bf..a00001a9 100644 --- a/docs/software/python-cli/usage.mdx +++ b/docs/software/python-cli/usage.mdx @@ -46,7 +46,7 @@ meshtastic --set network.wifi_ssid mywifissid --set network.wifi_psk mywifipsw - ``` :::note -For a full list of preferences which can be set (and their documentation) can be found in the [protobufs](/docs/developers/protobufs/api#radioconfiguserpreferences). +For a full list of preferences which can be set (and their documentation) can be found in the [protobufs](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.User). ::: ### Changing channel settings @@ -54,7 +54,7 @@ For a full list of preferences which can be set (and their documentation) can be The channel settings can also be changed, either by using a standard (shareable) meshtastic URL or you can set particular channel parameter (for advanced users). :::warning -Meshtastic encodes the radio channel and PSK in the channel's URL. All nodes must connect to the channel again by using the URL provided after a change in this section by performing the `--info` switch. +Meshtastic encodes the radio channel and PSK in the channel's URL. All nodes must connect to the channel again by using the URL provided after a change in this section by performing the `--info` switch. ::: ```shell @@ -93,12 +93,12 @@ Writing modified channels to device Toggling `set-ham` changes your device settings in the following ways. -| Setting | `set-ham` Default | Normal Default | -| :----------------------: | :---------------: | :---------------------------------------: | -| `IsLicensed` | `true` | See [User Config - IsLicensed](/docs/settings/config/user#is-licensed-ham) | -| `LongName` | _Your CallSign_ | See [User Config - LongName](/docs/settings/config/user#long-name) | -| `ShortName` | _Abrv CallSign_ | See [User Config - ShortName](/docs/settings/config/user#short-name) | -| `PSK` | `""` | See [Channel Settings - PSK](#changing-the-preshared-key) | +| Setting | `set-ham` Default | Normal Default | +| :----------: | :---------------: | :------------------------------------------------------------------------: | +| `IsLicensed` | `true` | See [User Config - IsLicensed](/docs/settings/config/user#is-licensed-ham) | +| `LongName` | _Your CallSign_ | See [User Config - LongName](/docs/settings/config/user#long-name) | +| `ShortName` | _Abrv CallSign_ | See [User Config - ShortName](/docs/settings/config/user#short-name) | +| `PSK` | `""` | See [Channel Settings - PSK](#changing-the-preshared-key) | ## Changing the preshared key: @@ -130,8 +130,9 @@ This indicates an OS permission problem for access by your user to the USB seria sudo usermod -a -G dialout ``` -If the adding the user to the dialout group does not work, you can use the following command to find out which group to add your user to. +If the adding the user to the dialout group does not work, you can use the following command to find out which group to add your user to. In this example (from Arch Linux) the group was "uucp" + ```shell ❯ ls -al /dev/ttyACM0 crw-rw---- 1 root uucp 166, 0 Jul 20 21:52 /dev/ttyACM0