mirror of
https://github.com/meshtastic/python.git
synced 2026-04-17 21:42:20 -04:00
Add optional parameter to specify what fields to show with --nodes
This commit is contained in:
17
.vscode/launch.json
vendored
17
.vscode/launch.json
vendored
@@ -245,6 +245,23 @@
|
||||
"module": "meshtastic",
|
||||
"justMyCode": true,
|
||||
"args": ["--debug", "--nodes"]
|
||||
},
|
||||
{
|
||||
"name": "meshtastic nodes table",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "meshtastic",
|
||||
"justMyCode": true,
|
||||
"args": ["--nodes"]
|
||||
},
|
||||
{
|
||||
"name": "meshtastic nodes table with show-fields",
|
||||
"type": "debugpy",
|
||||
"request": "launch",
|
||||
"module": "meshtastic",
|
||||
"justMyCode": true,
|
||||
"args": ["--nodes", "--show-fields", "AKA,Pubkey,Role,Role,Role,Latitude,Latitude,deviceMetrics.voltage"]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
|
||||
@@ -921,7 +921,11 @@ def onConnected(interface):
|
||||
if args.dest != BROADCAST_ADDR:
|
||||
print("Showing node list of a remote node is not supported.")
|
||||
return
|
||||
interface.showNodes()
|
||||
interface.showNodes(True, args.show_fields)
|
||||
|
||||
if args.show_fields and not args.nodes:
|
||||
print("--show-fields can only be used with --nodes")
|
||||
return
|
||||
|
||||
if args.qr or args.qr_all:
|
||||
closeNow = True
|
||||
@@ -1626,6 +1630,13 @@ def addLocalActionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPars
|
||||
help="Print Node List in a pretty formatted table",
|
||||
action="store_true",
|
||||
)
|
||||
|
||||
group.add_argument(
|
||||
"--show-fields",
|
||||
help="Specify fields to show (comma-separated) when using --nodes",
|
||||
type=lambda s: s.split(','),
|
||||
default=None
|
||||
)
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
@@ -222,7 +222,7 @@ class MeshInterface: # pylint: disable=R0902
|
||||
return infos
|
||||
|
||||
def showNodes(
|
||||
self, includeSelf: bool = True
|
||||
self, includeSelf: bool = True, showFields: Optional[List[str]] = None
|
||||
) -> str: # pylint: disable=W0613
|
||||
"""Show table summary of nodes in mesh"""
|
||||
|
||||
@@ -246,6 +246,23 @@ class MeshInterface: # pylint: disable=R0902
|
||||
return None # not handling a timestamp from the future
|
||||
return _timeago(delta_secs)
|
||||
|
||||
def getNestedValue(node_dict: Dict[str, Any], key_path: str) -> Any:
|
||||
keys = key_path.split(".")
|
||||
value = node_dict
|
||||
for key in keys:
|
||||
if isinstance(value, dict):
|
||||
value = value.get(key)
|
||||
else:
|
||||
return None
|
||||
return value
|
||||
|
||||
if showFields is None or showFields.count == 0:
|
||||
# The default set of fields to show (e.g., the status quo)
|
||||
showFields = ["N", "User", "ID", "AKA", "Hardware", "Pubkey", "Role", "Latitude", "Longitude", "Altitude", "Battery", "Channel util.", "Tx air util.", "SNR", "Hops", "Channel", "LastHeard", "Since"]
|
||||
else:
|
||||
# Always at least include the row number.
|
||||
showFields.insert(0, "N")
|
||||
|
||||
rows: List[Dict[str, Any]] = []
|
||||
if self.nodesByNum:
|
||||
logging.debug(f"self.nodes:{self.nodes}")
|
||||
@@ -287,11 +304,12 @@ class MeshInterface: # pylint: disable=R0902
|
||||
if metrics:
|
||||
batteryLevel = metrics.get("batteryLevel")
|
||||
if batteryLevel is not None:
|
||||
if batteryLevel == 0:
|
||||
if batteryLevel in (0, 101): # Note: for boards without battery pin or PMU, 101% battery means 'the board is using external power'
|
||||
batteryString = "Powered"
|
||||
else:
|
||||
batteryString = str(batteryLevel) + "%"
|
||||
row.update({"Battery": batteryString})
|
||||
|
||||
row.update(
|
||||
{
|
||||
"Channel util.": formatFloat(
|
||||
@@ -313,7 +331,21 @@ class MeshInterface: # pylint: disable=R0902
|
||||
}
|
||||
)
|
||||
|
||||
rows.append(row)
|
||||
# This allows the user to specify fields that wouldn't otherwise be included.
|
||||
extraFields = {}
|
||||
for field in showFields:
|
||||
if field in row:
|
||||
# We already have it, move along.
|
||||
continue
|
||||
elif "." in field:
|
||||
extraFields[field] = getNestedValue(node, field)
|
||||
else:
|
||||
extraFields[field] = node.get(field)
|
||||
|
||||
# Filter out any field in the data set that was not specified.
|
||||
filteredData = {key: value for key, value in row.items() if key in showFields}
|
||||
filteredData.update(extraFields)
|
||||
rows.append(filteredData)
|
||||
|
||||
rows.sort(key=lambda r: r.get("LastHeard") or "0000", reverse=True)
|
||||
for i, row in enumerate(rows):
|
||||
|
||||
Reference in New Issue
Block a user