Started parsing all meshtastic events for better logging, added more firmware hacks for heartbeat and for display RAM/PSRAM usage
This commit is contained in:
parent
7d10d4e64c
commit
e2bac7efde
@ -29,6 +29,8 @@ The goal here is to create simple & clean modules to interface with the hardware
|
|||||||
- Documentation on MQTT bridging for high availability
|
- Documentation on MQTT bridging for high availability
|
||||||
- Bridge for IRC to allow channel messages to relay over Meshtastic & all Meshtastic events to relay into IRC. *(IRC to Meshtastic will require a command like `!mesh <message here>` to avoid overloading the traffic over LoRa)*
|
- Bridge for IRC to allow channel messages to relay over Meshtastic & all Meshtastic events to relay into IRC. *(IRC to Meshtastic will require a command like `!mesh <message here>` to avoid overloading the traffic over LoRa)*
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
- [Meshtastic PortNum List](https://buf.build/meshtastic/protobufs/docs/main:meshtastic#meshtastic.PortNum)
|
||||||
___
|
___
|
||||||
|
|
||||||
###### 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)
|
###### 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)
|
@ -32,6 +32,35 @@ You can use the provided [icon.xbm](../assets/icon.xbm) for a rad GTA:SA fist to
|
|||||||
|
|
||||||
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...
|
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...
|
||||||
|
|
||||||
|
###### Display RAM/PSRAM Usage
|
||||||
|
Look for these lines:
|
||||||
|
```cpp
|
||||||
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 2, "SSID: " + String(wifiName));
|
||||||
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 3, "http://meshtastic.local");
|
||||||
|
```
|
||||||
|
|
||||||
|
And place the follow code AFTER the above lines:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Display memory usage using the MemGet class
|
||||||
|
uint32_t freeHeap = memGet.getFreeHeap();
|
||||||
|
uint32_t totalHeap = memGet.getHeapSize();
|
||||||
|
uint32_t usedHeap = totalHeap - freeHeap;
|
||||||
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 4, "Heap: " + String(usedHeap / 1024) + "/" + String(totalHeap / 1024) + " KB");
|
||||||
|
|
||||||
|
// Display PSRAM usage using the MemGet class
|
||||||
|
uint32_t freePsram = memGet.getFreePsram();
|
||||||
|
uint32_t totalPsram = memGet.getPsramSize();
|
||||||
|
uint32_t usedPsram = totalPsram - freePsram;
|
||||||
|
display->drawString(x, y + FONT_HEIGHT_SMALL * 5, "PSRAM: " + String(usedPsram / 1024) + "/" + String(totalPsram / 1024) + " KB");
|
||||||
|
```
|
||||||
|
|
||||||
|
###### Heartbeat for redraw
|
||||||
|
- Uncomment the line that says: `#define SHOW_REDRAWS`
|
||||||
|
|
||||||
|
This will show a little 1x1 pixel on the top left corner anytime the screen is redraw.
|
||||||
|
|
||||||
|
|
||||||
## Compile & flash firmware
|
## Compile & flash firmware
|
||||||
- Select `PlatformIO: Pick Project Environment` & select your board.
|
- Select `PlatformIO: Pick Project Environment` & select your board.
|
||||||
- Run `PLatformIO: Build` to compile the firmware.
|
- Run `PLatformIO: Build` to compile the firmware.
|
||||||
|
99
meshmqtt.py
99
meshmqtt.py
@ -26,11 +26,21 @@ except ImportError:
|
|||||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %I:%M:%S')
|
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %I:%M:%S')
|
||||||
|
|
||||||
|
|
||||||
|
def clean_dict(dictionary: dict) -> dict:
|
||||||
|
'''
|
||||||
|
Remove empty fields from a dictionary.
|
||||||
|
|
||||||
|
:param dictionary: The dictionary to remove empty fields from
|
||||||
|
'''
|
||||||
|
|
||||||
|
return {key: value for key, value in dictionary.items() if value}
|
||||||
|
|
||||||
|
|
||||||
class MeshtasticMQTT(object):
|
class MeshtasticMQTT(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
'''Initialize the Meshtastic MQTT client'''
|
'''Initialize the Meshtastic MQTT client'''
|
||||||
|
|
||||||
self.broadcast_id = 4294967295
|
self.broadcast_id = 4294967295 # Our channel ID
|
||||||
self.key = None
|
self.key = None
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +158,18 @@ class MeshtasticMQTT(object):
|
|||||||
if message_packet.HasField('encrypted') and not message_packet.HasField('decoded'):
|
if message_packet.HasField('encrypted') and not message_packet.HasField('decoded'):
|
||||||
message_packet = self.decrypt_message_packet(message_packet)
|
message_packet = self.decrypt_message_packet(message_packet)
|
||||||
|
|
||||||
|
text = {
|
||||||
|
'from' : getattr(message_packet, 'from'),
|
||||||
|
'to' : getattr(message_packet, 'to'),
|
||||||
|
'channel' : getattr(message_packet, 'channel'),
|
||||||
|
'id' : getattr(message_packet, 'id'),
|
||||||
|
'rx_time' : getattr(message_packet, 'rx_time'),
|
||||||
|
'hop_limit' : getattr(message_packet, 'hop_limit'),
|
||||||
|
'priority' : getattr(message_packet, 'priority'),
|
||||||
|
'hop_start' : getattr(message_packet, 'hop_start')
|
||||||
|
}
|
||||||
|
logging.info(text)
|
||||||
|
|
||||||
if message_packet.decoded.portnum == portnums_pb2.UNKNOWN_APP:
|
if message_packet.decoded.portnum == portnums_pb2.UNKNOWN_APP:
|
||||||
logging.warning('Received an unknown app message:')
|
logging.warning('Received an unknown app message:')
|
||||||
logging.info(message_packet)
|
logging.info(message_packet)
|
||||||
@ -172,14 +194,40 @@ class MeshtasticMQTT(object):
|
|||||||
elif message_packet.decoded.portnum == portnums_pb2.POSITION_APP:
|
elif message_packet.decoded.portnum == portnums_pb2.POSITION_APP:
|
||||||
data = mesh_pb2.Position()
|
data = mesh_pb2.Position()
|
||||||
data.ParseFromString(message_packet.decoded.payload)
|
data.ParseFromString(message_packet.decoded.payload)
|
||||||
|
|
||||||
|
data_dict = {key: value for key, value in data}
|
||||||
|
print(data_dict)
|
||||||
|
|
||||||
logging.info('Received position:')
|
logging.info('Received position:')
|
||||||
logging.info(data)
|
loc = {
|
||||||
|
'lattitude' : getattr(data, 'latitude_i') / 1e7,
|
||||||
|
'longitude' : getattr(data, 'longitude_i') / 1e7,
|
||||||
|
'altitude' : getattr(data, 'altitude') / 1000,
|
||||||
|
'location_source' : getattr(data, 'location_source'),
|
||||||
|
'altitude_source' : getattr(data, 'altitude_source'),
|
||||||
|
'pdop' : getattr(data, 'PDOP'),
|
||||||
|
'hdop' : getattr(data, 'HDOP'),
|
||||||
|
'vdop' : getattr(data, 'VDOP'),
|
||||||
|
'gps_accuracy' : getattr(data, 'gps_accuracy'),
|
||||||
|
'ground_speed' : getattr(data, 'ground_speed'),
|
||||||
|
'ground_track' : getattr(data, 'ground_track'),
|
||||||
|
'fix_quality' : getattr(data, 'fix_quality'),
|
||||||
|
'fix_type' : getattr(data, 'fix_type'),
|
||||||
|
'sats_in_view' : getattr(data, 'sats_in_view'),
|
||||||
|
'sensor_id' : getattr(data, 'sensor_id'),
|
||||||
|
'next_update' : getattr(data, 'next_update'),
|
||||||
|
'seq_number' : getattr(data, 'seq_number'),
|
||||||
|
'precision_bits' : getattr(data, 'precision_bits')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (loc := clean_dict(loc)):
|
||||||
|
logging.info(loc)
|
||||||
|
|
||||||
elif message_packet.decoded.portnum == portnums_pb2.NODEINFO_APP:
|
elif message_packet.decoded.portnum == portnums_pb2.NODEINFO_APP:
|
||||||
data = mesh_pb2.NodeInfo()
|
data = mesh_pb2.NodeInfo()
|
||||||
data.ParseFromString(message_packet.decoded.payload)
|
#data.ParseFromString(message_packet.decoded.payload)
|
||||||
logging.info('Received node info:')
|
logging.info('Received node info:')
|
||||||
logging.info(data)
|
logging.info(message_packet)
|
||||||
|
|
||||||
elif message_packet.decoded.portnum == portnums_pb2.ROUTING_APP:
|
elif message_packet.decoded.portnum == portnums_pb2.ROUTING_APP:
|
||||||
data = mesh_pb2.Routing()
|
data = mesh_pb2.Routing()
|
||||||
@ -242,10 +290,9 @@ class MeshtasticMQTT(object):
|
|||||||
logging.info(data)
|
logging.info(data)
|
||||||
|
|
||||||
elif message_packet.decoded.portnum == portnums_pb2.STORE_FORWARD_APP:
|
elif message_packet.decoded.portnum == portnums_pb2.STORE_FORWARD_APP:
|
||||||
data = mesh_pb2.StoreForward()
|
|
||||||
data.ParseFromString(message_packet.decoded.payload)
|
|
||||||
logging.info('Received store and forward:')
|
logging.info('Received store and forward:')
|
||||||
logging.info(data)
|
logging.info(message_packet)
|
||||||
|
logging.info(message_packet.decoded.payload)
|
||||||
|
|
||||||
elif message_packet.decoded.portnum == portnums_pb2.RANGE_TEST_APP:
|
elif message_packet.decoded.portnum == portnums_pb2.RANGE_TEST_APP:
|
||||||
data = mesh_pb2.RangeTest()
|
data = mesh_pb2.RangeTest()
|
||||||
@ -257,7 +304,34 @@ class MeshtasticMQTT(object):
|
|||||||
data = telemetry_pb2.Telemetry()
|
data = telemetry_pb2.Telemetry()
|
||||||
data.ParseFromString(message_packet.decoded.payload)
|
data.ParseFromString(message_packet.decoded.payload)
|
||||||
logging.info('Received telemetry:')
|
logging.info('Received telemetry:')
|
||||||
logging.info(data)
|
|
||||||
|
data_dict = {key: value for key, value in data}
|
||||||
|
print(data_dict)
|
||||||
|
|
||||||
|
if getattr(data, 'device_metrics'):
|
||||||
|
text = {
|
||||||
|
'battery_level' : getattr(data.device_metrics, 'battery_level'),
|
||||||
|
'voltage' : getattr(data.device_metrics, 'voltage'),
|
||||||
|
'channel_utilization' : getattr(data.device_metrics, 'channel_utilization'),
|
||||||
|
'air_util_tx' : getattr(data.device_metrics, 'air_util_tx'),
|
||||||
|
'uptime_seconds' : getattr(data.device_metrics, 'uptime_seconds')
|
||||||
|
}
|
||||||
|
if (text := clean_dict(text)):
|
||||||
|
logging.info(text)
|
||||||
|
|
||||||
|
if getattr(data, 'environment_metrics'):
|
||||||
|
env_metrics = {
|
||||||
|
'barometric_pressure' : getattr(data.environment_metrics, 'barometric_pressure'),
|
||||||
|
'current' : getattr(data.environment_metrics, 'current'),
|
||||||
|
'distance' : getattr(data.environment_metrics, 'distance'),
|
||||||
|
'gas_resistance' : getattr(data.environment_metrics, 'gas_resistance'),
|
||||||
|
'iaq' : getattr(data.environment_metrics, 'iaq'),
|
||||||
|
'relative_humidity' : getattr(data.environment_metrics, 'relative_humidity'),
|
||||||
|
'temperature' : getattr(data.environment_metrics, 'temperature'),
|
||||||
|
'voltage' : getattr(data.environment_metrics, 'voltage')
|
||||||
|
}
|
||||||
|
if (env_metrics := clean_dict(env_metrics)):
|
||||||
|
logging.info(env_metrics)
|
||||||
|
|
||||||
elif message_packet.decoded.portnum == portnums_pb2.ZPS_APP:
|
elif message_packet.decoded.portnum == portnums_pb2.ZPS_APP:
|
||||||
data = mesh_pb2.Zps()
|
data = mesh_pb2.Zps()
|
||||||
@ -281,7 +355,13 @@ class MeshtasticMQTT(object):
|
|||||||
neighborInfo = mesh_pb2.NeighborInfo()
|
neighborInfo = mesh_pb2.NeighborInfo()
|
||||||
neighborInfo.ParseFromString(message_packet.decoded.payload)
|
neighborInfo.ParseFromString(message_packet.decoded.payload)
|
||||||
logging.info('Received neighbor info:')
|
logging.info('Received neighbor info:')
|
||||||
logging.info(neighborInfo)
|
info = {
|
||||||
|
'node_id' : getattr(neighborInfo, 'node_id'),
|
||||||
|
'last_sent_by_id' : getattr(neighborInfo, 'last_sent_by_id'),
|
||||||
|
'node_broadcast_interval_secs' : getattr(neighborInfo, 'node_broadcast_interval_secs'),
|
||||||
|
'neighbors' : getattr(neighborInfo, 'neighbors')
|
||||||
|
}
|
||||||
|
logging.info(info)
|
||||||
|
|
||||||
elif message_packet.decoded.portnum == portnums_pb2.ATAK_PLUGIN:
|
elif message_packet.decoded.portnum == portnums_pb2.ATAK_PLUGIN:
|
||||||
data = mesh_pb2.AtakPlugin()
|
data = mesh_pb2.AtakPlugin()
|
||||||
@ -312,6 +392,7 @@ class MeshtasticMQTT(object):
|
|||||||
pos.ParseFromString(message_packet.decoded.payload)
|
pos.ParseFromString(message_packet.decoded.payload)
|
||||||
logging.info('Received map report:')
|
logging.info('Received map report:')
|
||||||
logging.info(pos)
|
logging.info(pos)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logging.warning('Received an unencrypted message')
|
logging.warning('Received an unencrypted message')
|
||||||
logging.info(f'Payload: {message_packet}')
|
logging.info(f'Payload: {message_packet}')
|
||||||
|
Loading…
Reference in New Issue
Block a user