Added T-Deck documentation, parts list, gps install guide, etc. Added MQTT connection script (still working on this)
This commit is contained in:
parent
ddb5a4b323
commit
f92093d889
12
FIRMWARE.md
12
FIRMWARE.md
@ -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
23
T-DECK.md
Normal 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.
|
121
meshmqtt.py
121
meshmqtt.py
@ -1,33 +1,82 @@
|
||||
#!/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
|
||||
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
|
||||
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
|
||||
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):
|
||||
@ -43,46 +92,60 @@ def on_connect(client, userdata, flags, rc, properties):
|
||||
|
||||
if rc == 0:
|
||||
print('Connected to MQTT broker')
|
||||
|
||||
else:
|
||||
print(f"Failed to connect to MQTT broker with result code {str(rc)}")
|
||||
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.
|
||||
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 class with members topic, payload, qos, retain.
|
||||
:param msg: An instance of MQTTMessage. This is a
|
||||
'''
|
||||
|
||||
service_envelope = mqtt_pb2.ServiceEnvelope()
|
||||
|
||||
try:
|
||||
service_envelope.ParseFromString(msg.payload)
|
||||
print(service_envelope)
|
||||
|
||||
# print(service_envelope)
|
||||
message_packet = service_envelope.packet
|
||||
print(message_packet)
|
||||
|
||||
# print(message_packet)
|
||||
except Exception as e:
|
||||
print(f'error on message: {e}')
|
||||
logging.error(f'Failed to parse message: {str(e)}')
|
||||
return
|
||||
|
||||
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__':
|
||||
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()
|
||||
|
||||
# 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=MQTT_USERNAME, password=MQTT_PASSWORD)
|
||||
client.connect(MQTT_BROKER, MQTT_PORT, 60)
|
||||
client.username_pw_set(username=args.username, password=args.password)
|
||||
client.connect(args.broker, args.port, 60)
|
||||
client.on_message = on_message
|
||||
client.subscribe(MQTT_ROOT_TOPIC, 0) # This is the topic that the Meshtastic device is publishing to
|
||||
client.subscribe(args.root, 0)
|
||||
|
||||
# Keep-alive loop
|
||||
while client.loop() == 0:
|
||||
pass
|
Loading…
Reference in New Issue
Block a user