Added T-Deck documentation, parts list, gps install guide, etc. Added MQTT connection script (still working on this)

This commit is contained in:
Dionysus 2024-05-03 13:16:58 -04:00
parent ddb5a4b323
commit f92093d889
Signed by: acidvegas
GPG Key ID: EF4B922DB85DC9DE
3 changed files with 154 additions and 66 deletions

View File

@ -1,32 +1,34 @@
# Meshtastic Firmware Hacks
### Custom Boot Logo & Message
## Prerequisite
- Download & install [PlatformIO](https://platformio.org/platformio-ide)
- `git clone https://github.com/meshtastic/firmware.git`
- `cd firmware && git submodule update --init`
## Customization
###### Custom Boot Logo
- Use [XMB Viewer](https://windows87.github.io/xbm-viewer-converter/) to convert an image to XMB
- The data from this goes in `firmware/src/graphics/img/icon.xbm`
### Custom boot message
###### Custom boot message
- Navigate to `firmware/src/graphics/Screen.cpp`
- Find & replace `const char *title = "meshtastic.org";` with your custom message.
### Custom screen color
###### Custom screen color
- Navigate to `src/graphics/TFTDisplay.cpp`
- Find & replace `#define TFT_MESH COLOR565(0x67, 0xEA, 0x94)` with your custom color.
### Custom alert sound (for T-Deck & devices with a buzzer)
###### Custom alert sound (for T-Deck & devices with a buzzer)
- From the mobile app, click the 3 dots on the top right, and select `Radio configuration`
- Under `Module configuration`, select `External Notification`
- Scroll down & you will see a `Ringtone` option that takes [RTTTL](https://en.wikipedia.org/wiki/Ring_Tone_Text_Transfer_Language) formatted tones.
As far as I know, at the time of writing this, the onyl way to change the Ringtone is from the App...
As far as I know, at the time of writing this, the only way to change the Ringtone is from the App. While this is not a "firmware" related thing, I included it in this file because it was difficult to find this setting...
## Compile & flash firmware
- Select `PlatformIO: Pick Project Environment` & select your board.

23
T-DECK.md Normal file
View File

@ -0,0 +1,23 @@
# LilyGo T-Deck Notes
## Parts
- [T-Deck](https://www.lilygo.cc/products/t-deck)
- [Case](https://www.printables.com/model/741124-lilygo-t-deck-case) *(You can 3D print it yourself, or follow the Etsy link on here to buy one)*
- [Antenna](https://www.amazon.com/dp/B086ZG5WBR)
- [GPS](https://www.amazon.com/dp/B09LQDG1HY) *(There may be a better 15mm option for the case above..)*
- [Battery](https://www.amazon.com/dp/B0BG82T39Y) *(The battery you get depends on the size of the case you order, contact me if you need help)*
**WARNING:** Do not power on the device until the antenna is plugged in! Even to flash the firmware, or for testing, make sure your antenna is plugged in or you can fry the radio!
## GPS Installation
The T-Deck has a grove connector for the GPS. Personally, I do not use a grove connector for mine, I removed the Grove input and soldered directly to the board.
**WARNING**: Be careful taking off the grove! Snip the front points, and then use a soldering iron to loosen the metal on the 4 contact back points. You can VERY easily pull the solder pads right off if you just try to rip the grove connector off without loosening the solder points. If you pull off a solder pad, you're pretty much boned on having a GPS module.
You will see VCC, GND, RX & TX points on both the T-Deck & the GPS. Solder wires to match these points, but switch RX & TX. So do VCC to VCC, GND to GND, and then ensure that RX is soldered to TX, and TX is soldered to RX. It's confusing, I know, but that's China based hardware for you...
## Flashing
Simply plug in the T-Deck via USB and connect to a computer, then visit the [Meshtastic Web Flasher](https://flasher.meshtastic.org) and select your hardware & firmware version. Your device should show up as a serial device on /dev/ttyUSB0 or /dev/ttyAMC0. If you do not see your device, try adding your user to the dialout group. See [SETUP.md](./SETUP.md) for information on how to setup the device once it is flashed with Meshtastic.
## Issues
- Turn off WiFi completely if you plan to use this on-the-go. The device has an ESP32 chip which will always preffer WiFi over Bluetooth, so if you leave the house with this thign, it will constantly keep trying to connect to your WiFi & really degrade the performance of the board.

View File

@ -1,88 +1,151 @@
#!/usr/bin/env python
# Meshtastic MQTT Interface - Developed by Acidvegas in Python (https://git.acid.vegas/meshtastic)
#!/usr/bin/env python3
# Meshtastic MQTT Interface - Developed by acidvegas in Python (https://acid.vegas/meshtastic)
import argparse
import base64
import random
import logging
try:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
from cryptography.hazmat.backends import default_backend
except ImportError:
raise ImportError('cryptography library not found (pip install cryptography)')
raise SystemExit('missing the cryptography module (pip install cryptography)')
try:
from meshtastic import mesh_pb2, mqtt_pb2, portnums_pb2, telemetry_pb2
from meshtastic import mesh_pb2, mqtt_pb2, portnums_pb2, telemetry_pb2
except ImportError:
raise ImportError('meshtastic library not found (pip install meshtastic)')
raise SystemExit('missing the meshtastic module (pip install meshtastic)')
try:
import paho.mqtt.client as mqtt
import paho.mqtt.client as mqtt
except ImportError:
raise ImportError('paho-mqtt library not found (pip install paho-mqtt)')
raise SystemExit('missing the paho-mqtt module (pip install paho-mqtt)')
# MQTT Configuration
MQTT_BROKER = 'localhost'
MQTT_PORT = 1883
MQTT_USERNAME = 'username'
MQTT_PASSWORD = 'password'
MQTT_ROOT_TOPIC = 'msh/US/2/c/'
CHANNEL_KEY = 'channel_key'
def process_message(message_packet, text_payload, is_encrypted):
text = {
'message': text_payload,
'from': getattr(message_packet, 'from'),
'id': getattr(message_packet, 'id'),
'to': getattr(message_packet, 'to')
}
print(text)
def decode_encrypted(message_packet):
'''
Decrypt an encrypted message packet.
:param message_packet: The message packet to decrypt'''
try:
key_bytes = base64.b64decode(key.encode('ascii'))
nonce_packet_id = getattr(message_packet, 'id').to_bytes(8, 'little')
nonce_from_node = getattr(message_packet, 'from').to_bytes(8, 'little')
nonce = nonce_packet_id + nonce_from_node
cipher = Cipher(algorithms.AES(key_bytes), modes.CTR(nonce), backend=default_backend())
decryptor = cipher.decryptor()
decrypted_bytes = decryptor.update(getattr(message_packet, 'encrypted')) + decryptor.finalize()
data = mesh_pb2.Data()
data.ParseFromString(decrypted_bytes)
message_packet.decoded.CopyFrom(data)
if message_packet.decoded.portnum == portnums_pb2.TEXT_MESSAGE_APP:
text_payload = message_packet.decoded.payload.decode('utf-8')
is_encrypted = True
process_message(message_packet, text_payload, is_encrypted)
print(f'{text_payload}')
elif message_packet.decoded.portnum == portnums_pb2.NODEINFO_APP:
info = mesh_pb2.User()
info.ParseFromString(message_packet.decoded.payload)
print(info)
elif message_packet.decoded.portnum == portnums_pb2.POSITION_APP:
pos = mesh_pb2.Position()
pos.ParseFromString(message_packet.decoded.payload)
print(pos)
elif message_packet.decoded.portnum == portnums_pb2.TELEMETRY_APP:
env = telemetry_pb2.Telemetry()
env.ParseFromString(message_packet.decoded.payload)
print(env)
except Exception as e:
logging.error(f'Failed to decrypt message: {str(e)}')
def on_connect(client, userdata, flags, rc, properties):
'''
Callback for when the client receives a CONNACK response from the server.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or user_data_set()
:param flags: Response flags sent by the broker
:param rc: The connection result
:param properties: The properties returned by the broker
'''
'''
Callback for when the client receives a CONNACK response from the server.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or user_data_set()
:param flags: Response flags sent by the broker
:param rc: The connection result
:param properties: The properties returned by the broker
'''
if rc == 0:
print('Connected to MQTT broker')
else:
print(f"Failed to connect to MQTT broker with result code {str(rc)}")
if rc == 0:
print('Connected to MQTT broker')
else:
logging.error(f'Failed to connect to MQTT broker: {rc}')
def on_message(client, userdata, msg):
'''
Callback for when a PUBLISH message is received from the server.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or user_data_set()
:param msg: An instance of MQTTMessage. This is a class with members topic, payload, qos, retain.
'''
'''
Callback for when a message is received from the server.
:param client: The client instance for this callback
:param userdata: The private user data as set in Client() or user_data_set()
:param msg: An instance of MQTTMessage. This is a
'''
service_envelope = mqtt_pb2.ServiceEnvelope()
service_envelope = mqtt_pb2.ServiceEnvelope()
try:
service_envelope.ParseFromString(msg.payload)
# print(service_envelope)
message_packet = service_envelope.packet
# print(message_packet)
except Exception as e:
logging.error(f'Failed to parse message: {str(e)}')
return
try:
service_envelope.ParseFromString(msg.payload)
print(service_envelope)
message_packet = service_envelope.packet
print(message_packet)
except Exception as e:
print(f'error on message: {e}')
else:
if message_packet.HasField('encrypted') and not message_packet.HasField('decoded'): # Do we need to check for both?
pass # Need to finish this
if message_packet.HasField('encrypted') and not message_packet.HasField('decoded'):
decode_encrypted(message_packet)
if __name__ == '__main__':
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.on_connect = on_connect
client.username_pw_set(username=MQTT_USERNAME, password=MQTT_PASSWORD)
client.connect(MQTT_BROKER, MQTT_PORT, 60)
client.on_message = on_message
client.subscribe(MQTT_ROOT_TOPIC, 0) # This is the topic that the Meshtastic device is publishing to
parser = argparse.ArgumentParser(description='Mesh MQTT')
parser.add_argument('--broker', default='mqtt.meshtastic.org', help='MQTT broker address')
parser.add_argument('--port', default=1883, type=int, help='MQTT broker port')
parser.add_argument('--root', default='msh/US/2/c', help='Root topic')
parser.add_argument('--tls', action='store_true', help='Enable TLS/SSL')
parser.add_argument('--username', default='meshdev', help='MQTT username')
parser.add_argument('--password', default='large4cats', help='MQTT password')
parser.add_argument('--key', default='AQ==', help='Encryption key')
args = parser.parse_args()
# Keep-alive loop
while client.loop() == 0:
pass
# Ensure the key is padded and formatted correctly
padded_key = args.key.ljust(len(args.key) + ((4 - (len(args.key) % 4)) % 4), '=')
replaced_key = padded_key.replace('-', '+').replace('_', '/')
key = replaced_key
broadcast_id = 4294967295
# client = mqtt.Client(client_id='', clean_session=True, userdata=None)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
client.on_connect = on_connect
client.username_pw_set(username=args.username, password=args.password)
client.connect(args.broker, args.port, 60)
client.on_message = on_message
client.subscribe(args.root, 0)
while client.loop() == 0:
pass