meshtastic

- Unnamed repository; edit this file 'description' to name the repository.
git clone git://git.acid.vegas/-c.git
Log | Files | Refs | Archive | README | LICENSE

commit aca1e287038f7ca3a550ba7771635332de5a7648
Author: acidvegas <acid.vegas@acid.vegas>
Date: Thu, 25 Apr 2024 13:22:05 -0400

Initial commit

Diffstat:
ALICENSE | 15+++++++++++++++
AREADME.md | 11+++++++++++
Ameshtastic_serial.py | 139+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

3 files changed, 165 insertions(+), 0 deletions(-)

diff --git a/LICENSE b/LICENSE
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2024, acidvegas <acid.vegas@acid.vegas>
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.md b/README.md
@@ -0,0 +1,10 @@
+# Meshtastic
+> Experiments with Meshtastic, MQTT, Lora, & more....
+
+## WORK-IN-PROGRESS
+
+Here I will be just throw up random bits of code I write as I experiment more with these Meshtastic devices. Currently using a Lilygo T-Deck & a Heltec Lora v3 for testing.
+
+___
+
+###### Mirrors for this repository: [acid.vegas](https://git.acid.vegas/meshtastic) • [SuperNETs](https://git.supernets.org/acidvegas/meshtastic) • [GitHub](https://github.com/acidvegas/meshtastic) • [GitLab](https://gitlab.com/acidvegas/meshtastic) • [Codeberg](https://codeberg.org/acidvegas/meshtastic)
+\ No newline at end of file
diff --git a/meshtastic_serial.py b/meshtastic_serial.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python
+# Meshtastic Serial Interface - Developed by Acidvegas in Python (https://git.acid.vegas)
+
+import argparse
+import logging
+import os
+import time
+
+try:
+	import meshtastic
+	from meshtastic.serial_interface import SerialInterface
+	from meshtastic.util             import findPorts
+except ImportError:
+	raise ImportError('meshtastic library not found (pip install meshtastic)')
+
+try:
+	from pubsub import pub
+except ImportError:
+	raise ImportError('pubsub library not found (pip install pypubsub)') # Confirm this Pypi package name...
+
+
+# Global variables
+node_long_names = {}
+
+# Initialize logging
+logging.basicConfig(level=logging.INFO, format='%(asctime)s | %(levelname)9s | %(funcName)s | %(message)s')
+
+
+def now():
+	'''Returns the current date and time in a formatted string'''
+
+	return time.strftime('%Y-%m-%d %H:%M:%S')
+
+
+def on_connect(interface, topic=pub.AUTO_TOPIC):
+	'''
+	Callback function for connection established
+
+	:param interface: Meshtastic interface
+	:param topic:     PubSub topic
+	'''
+
+	logging.info('Connection established')
+
+
+def on_disconnect(interface, topic=pub.AUTO_TOPIC):
+	'''
+	Callback function for connection lost
+
+	:param interface: Meshtastic interface
+	:param topic:     PubSub topic
+	'''
+
+	logging.error('Connection lost')
+
+
+def on_packet(packet: dict):
+	'''
+	Callback function for received packets
+
+	:param packet: Packet received
+	'''
+
+	if packet['decoded']['portnum'] == 'TEXT_MESSAGE_APP':
+		sender_id = str(packet['from'])
+		message = packet['decoded']['payload'].decode('utf-8')
+
+		# Message from self
+		if sender_id == str(interface.myInfo.my_node_num):
+			print(f'{now()} {node_long_names[sender_id]}: {message}')
+
+		# Message from others
+		if sender_id in node_long_names:
+			print(f'{now()} {node_long_names[sender_id]}: {message}')
+
+		# Unknown message (maybe trigger for rescanning the nodes if we dont find the sender in the list)
+		else:
+			print(f'{now()} UNK: {message}')
+
+
+def on_node(interface, topic=pub.AUTO_TOPIC):
+	'''
+	Callback function for node updates
+
+	:param interface: Meshtastic interface
+	:param topic:     PubSub topic
+	'''
+
+	if not interface.nodes:
+		logging.warning('No nodes found')
+		return
+
+	for node in interface.nodes.values():
+		short = node['user']['shortName']
+		long  = node['user']['longName'].encode('ascii', 'ignore').decode().rstrip()
+		num   = str(node['num'])
+		id    = node['user']['id']
+		mac   = node['user']['macaddr']
+		hw    = node['user']['hwModel']
+
+		node_long_names[num] = long # we store the node updates in a dictionary so we can parse the names of who sent incomming messages
+
+
+
+if __name__ == '__main__':
+	parser = argparse.ArgumentParser(description='Meshtastic Interface')
+	parser.add_argument('--serial', default='/dev/ttyACM0', help='Use serial interface')
+	args = parser.parse_args()
+
+	# Check if the serial device exists
+	if available_devices := findPorts():
+		if not os.path.exists(args.serial) or not args.serial in available_devices:
+			raise SystemExit(f'Invalid serial device: {args.serial} (Available: {available_devices})')
+	else:
+		raise SystemExit('No serial devices found')
+
+	# Initialize the Meshtastic interface
+	interface = SerialInterface(args.serial)
+
+	# Create the Meshtastic callback subscriptions
+	pub.subscribe(on_connect,    'meshtastic.connection.established')
+	pub.subscribe(on_disconnect, 'meshtastic.connection.lost')
+	pub.subscribe(on_node,       'meshtastic.node.updated')
+	pub.subscribe(on_packet,     'meshtastic.receive')
+
+	# The meshtastic.receive topics can be broken down further:
+	# pub.subscribe(on_text,      'meshtastic.receive.text')
+	# pub.subscribe(on_position,  'meshtastic.receive.position')
+	# pub.subscribe(on_user,      'meshtastic.receive.user')
+	# pub.subscribe(on_data,      'meshtastic.receive.data.portnum')
+
+	# Keep-alive loop
+	try:
+		while True:
+			time.sleep(60)
+	except KeyboardInterrupt:
+		pass
+	finally:
+		interface.close()