Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

# Add files or directories matching the regex patterns to the blacklist. The
# regex matches against base names, not paths.
ignore-patterns=mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_pb2.py,deviceonly_pb2.py,apponly_pb2.py,remote_hardware_pb2.py,portnums_pb2.py,mesh_pb2.py,storeforward_pb2.py,cannedmessages_pb2.py,module_config_pb2.py,localonly_pb2.py,node.py,device_metadata_pb2.py,nanopb_pb2.py
ignore-patterns=xmodem_pb2.py,rtttl_pb2.py,powermon_pb2.py,paxcount_pb2.py,interdevice_pb2.py,atak_pb2,clientonly_pb2.py,connection_status_pb2.py,device_ui_pb2.py,mqtt_pb2.py,channel_pb2.py,telemetry_pb2.py,admin_pb2.py,config_pb2.py,deviceonly_pb2.py,apponly_pb2.py,remote_hardware_pb2.py,portnums_pb2.py,mesh_pb2.py,storeforward_pb2.py,cannedmessages_pb2.py,module_config_pb2.py,localonly_pb2.py,node.py,device_metadata_pb2.py,nanopb_pb2.py



Expand Down
44 changes: 37 additions & 7 deletions exampleConfig.yaml
Original file line number Diff line number Diff line change
@@ -1,16 +1,46 @@
# example config using camelCase keys
owner: Bob TBeam
ownerShort: BOB
isUnmessagable: true

channelUrl: https://www.meshtastic.org/d/#CgUYAyIBAQ
channelUrl: https://www.meshtastic.org/e/#CgQ6AggNEg8IATgBQANIAVAeaAHABgE

cannedMessages: Hi|Bye|Yes|No|Ok
ringtone: 24:d=32,o=5,b=565:f6,p,f6,4p,p,f6,p,f6,2p,p,b6,p,b6,p,b6,p,b6,p,b,p,b,p,b,p,b,p,b,p,b,p,b,p,b,1p.,2p.,p

location:
lat: 35.88888
lon: -93.88888
alt: 304

userPrefs:
region: 1
isAlwaysPowered: "true"
screenOnSecs: 31536000
waitBluetoothSecs: 31536000
config:
bluetooth:
enabled: true
fixedPin: 123456
device:
serialEnabled: true
display:
screenOnSecs: 781
lora:
region: US
hopLimit: 3
txEnabled: true
txPower: 30
network:
ntpServer: 0.pool.ntp.org
position:
gpsAttemptTime: 900
gpsEnabled: true
gpsUpdateInterval: 120
positionBroadcastSecs: 900
positionBroadcastSmartEnabled: true
positionFlags: 3
power:
lsSecs: 300
meshSdsTimeoutSecs: 7200
minWakeSecs: 10
sdsSecs: 4294967295
waitBluetoothSecs: 344
moduleConfig:
telemetry:
deviceUpdateInterval: 900
environmentUpdateInterval: 900
7 changes: 4 additions & 3 deletions example_config.yaml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# example configuration file with snake_case keys
owner: Bob TBeam
owner_short: BOB
is_unmessagable: true

channel_url: https://www.meshtastic.org/e/#CgMSAQESCDgBQANIAVAe
channel_url: https://www.meshtastic.org/e/#CgQ6AggNEg8IATgBQANIAVAeaAHABgE

canned_messages: Hi|Bye|Yes|No|Ok
ringtone: 24:d=32,o=5,b=565:f6,p,f6,4p,p,f6,p,f6,2p,p,b6,p,b6,p,b6,p,b6,p,b,p,b,p,b,p,b,p,b,p,b,p,b,p,b,1p.,2p.,p
Expand All @@ -19,7 +20,7 @@ config:
device:
serialEnabled: true
display:
screenOnSecs: 600
screenOnSecs: 781
lora:
region: US
hopLimit: 3
Expand All @@ -39,7 +40,7 @@ config:
meshSdsTimeoutSecs: 7200
minWakeSecs: 10
sdsSecs: 4294967295

waitBluetoothSecs: 344
module_config:
telemetry:
deviceUpdateInterval: 900
Expand Down
332 changes: 177 additions & 155 deletions meshtastic/__main__.py

Large diffs are not rendered by default.

34 changes: 25 additions & 9 deletions meshtastic/mesh_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,13 +225,14 @@ def showInfo(self, file=sys.stdout) -> str: # pylint: disable=W0613
return infos

def showNodes(
self, includeSelf: bool = True, showFields: Optional[List[str]] = None
self, includeSelf: bool = True, showFields: Optional[List[str]] = None, printFmt: Optional[str] = None
) -> str: # pylint: disable=W0613
"""Show table summary of nodes in mesh

Args:
includeSelf (bool): Include ourself in the output?
showFields (List[str]): List of fields to show in output
printFmt (str): name of format to use
"""

def get_human_readable(name):
Expand Down Expand Up @@ -261,7 +262,6 @@ def get_human_readable(name):
else:
return name


def formatFloat(value, precision=2, unit="") -> Optional[str]:
"""Format a float value with precision."""
return f"{value:.{precision}f}{unit}" if value else None
Expand Down Expand Up @@ -296,7 +296,7 @@ def getNestedValue(node_dict: Dict[str, Any], key_path: str) -> Any:
return value

if showFields is None or len(showFields) == 0:
# The default set of fields to show (e.g., the status quo)
# The default set of fields to show (e.g., the status quo)
showFields = ["N", "user.longName", "user.id", "user.shortName", "user.hwModel", "user.publicKey",
"user.role", "position.latitude", "position.longitude", "position.altitude",
"deviceMetrics.batteryLevel", "deviceMetrics.channelUtilization",
Expand Down Expand Up @@ -372,7 +372,16 @@ def getNestedValue(node_dict: Dict[str, Any], key_path: str) -> Any:
for i, row in enumerate(rows):
row["N"] = i + 1

table = tabulate(rows, headers="keys", missingval="N/A", tablefmt="fancy_grid")
if not printFmt or len(printFmt) == 0:
printFmt = "fancy_grid"
if printFmt.lower() == 'json':
headers = []
if len(rows) > 0:
headers = list(rows[0].keys())
outDict = {'headers': headers, 'nodes': rows}
table = json.dumps(outDict)
else:
table = tabulate(rows, headers="keys", missingval="N/A", tablefmt=printFmt)
print(table)
return table

Expand Down Expand Up @@ -1061,42 +1070,49 @@ def getMyNodeInfo(self) -> Optional[Dict]:
logger.debug(f"self.nodesByNum:{self.nodesByNum}")
return self.nodesByNum.get(self.myInfo.my_node_num)

def getMyUser(self):
def getMyUser(self) -> dict | None:
"""Get user"""
nodeInfo = self.getMyNodeInfo()
if nodeInfo is not None:
return nodeInfo.get("user")
return None

def getLongName(self):
def getLongName(self) -> str | None:
"""Get long name"""
user = self.getMyUser()
if user is not None:
return user.get("longName", None)
return None

def getShortName(self):
def getShortName(self) -> str | None:
"""Get short name"""
user = self.getMyUser()
if user is not None:
return user.get("shortName", None)
return None

def getIsUnmessagable(self) -> bool | None:
"""Get getIsUnmessagable property"""
user = self.getMyUser()
if user is not None:
return user.get("isUnmessagable", None)
return None

def getPublicKey(self):
"""Get Public Key"""
user = self.getMyUser()
if user is not None:
return user.get("publicKey", None)
return None

def getCannedMessage(self):
def getCannedMessage(self) -> str | None:
"""Get canned message"""
node = self.localNode
if node is not None:
return node.get_canned_message()
return None

def getRingtone(self):
def getRingtone(self) -> str | None:
"""Get ringtone"""
node = self.localNode
if node is not None:
Expand Down
Loading