Elixir client for Meshtastic devices. Connects over TCP to send and receive mesh network messages using Protobuf.
Add to your mix.exs:
def deps do
[
{:meshtastic_client, "~> 0.1.0"}
]
endThen run mix deps.get to install.
# Connect to your device
{:ok, conn} = MeshtasticClient.connect(type: :tcp, host: "192.168.1.100")
# Subscribe to incoming messages
MeshtasticClient.subscribe(conn)
# Send a message to the mesh
MeshtasticClient.send_text(conn, "Hello from Elixir!")
# Collect messages
messages = MeshtasticClient.collect_messages(timeout: 5000)
IO.inspect(messages)See the examples/ directory for more usage patterns.
Note
Protobuf client is generated automatically but not all features are available on the Elixir client
This library uses Meshtastic's protobuf definitions. You'll need protoc installed to generate the Elixir modules:
# Fedora/RHEL
sudo dnf install protobuf-compiler protobuf-devel
# Ubuntu/Debian
sudo apt-get install protobuf-compiler protobuf-devel
# macOS
brew install protobufInstall the Elixir protobuf plugin:
mix escript.install hex protobuf 0.14.0The protobuf files are in priv/protos/. Generate modules using the Mix task:
mix protobuf.genTo regenerate all modules from scratch:
mix protobuf.gen --cleanMost Meshtastic devices expose TCP on port 4403:
{:ok, conn} = MeshtasticClient.connect(
type: :tcp,
host: "192.168.1.100",
port: 4403 # default
)Not implemented yet.
# Broadcast to all nodes
MeshtasticClient.send_text(conn, "Hello mesh!")
# Send to specific node
MeshtasticClient.send_text(conn, "Direct message", to: 0x12345678, want_ack: true)
# Send on channel 1
MeshtasticClient.send_text(conn, "Channel message", channel: 1)MeshtasticClient.send_position(conn,
latitude: 37.7749,
longitude: -122.4194,
altitude: 15
)Two approaches: collect or stream.
Gather messages for a set time:
MeshtasticClient.subscribe(conn)
messages = MeshtasticClient.collect_messages(timeout: 5000, count: 10)
Enum.each(messages, &IO.inspect/1)Handle messages as they arrive:
MeshtasticClient.subscribe(conn)
receive do
{:meshtastic_message, %{payload_variant: {:packet, packet}}} ->
IO.puts("Got packet: #{inspect(packet)}")
endRequest configuration and node details:
# Triggers config response messages
MeshtasticClient.get_config(conn)
# Same as get_config
MeshtasticClient.get_node_info(conn)These functions send requests; responses arrive as messages you receive via subscription.
MeshtasticClient- Public APIMeshtasticClient.Connection- TCP connection manager (GenServer)MeshtasticClient.Message- Message encoding/framingMeshtastic.*- Generated protobuf structs (mesh.proto, config.proto, etc.)
When you receive messages, check the payload_variant field:
case message.payload_variant do
{:my_info, info} -> # Device node info
{:node_info, node} -> # Other node discovered
{:packet, packet} -> # Mesh packet (text, telemetry, etc.)
{:config, config} -> # Device config
{:channel, channel} -> # Channel settings
_ -> # Other message types
end