Simplified, tabular output of meshtastic --info

The bigger the number of nodes in mesh, the harder I find to read the output of

meshtastic --info

I was then wondering whether it might be a good idea to add a switch to format the output in tabular form and reduce data to a minimum when just a quick glance at the mesh status is required.

Examples:

user position battery snr
longName latitude, longitude, altitude batteryLevel snr
user distance battery snr
longName distance, bearing batteryLevel snr

Would that be feasible AND useful also to others?

Cheers

1 Like

I think this is a great idea and super useful. If you want to add a “–nodes” option that prints a nicely formatted ascii table (by adding a printNodes() function in main.py, this lib might help.

1 Like

Glad you like it! Unfortunately that’s beyond my skills. Shall I file a bug?

2 Likes

Hi,

I’ve cloned the repo and made a branch implementing the feature requested, How can i push to the repo to create a pull request?

Regards Manuel

4 Likes

In your fork, click on New Pull Request.

Then click Compare Across Forks.

You’l get it from there.

1 Like

thanks to @iz1kga and @IZ1IVA. @iz1kga just fixed this (and did his first github pull request ever - bravo!). python tool 1.1.46 released to pypi!

meshtastic --info --port /dev/ttyUSB0 --nodes
Connected to radio
my_node_num: 2885173400
has_gps: true
num_channels: 10
region: "1.0"
hw_model: "tbeam"
firmware_version: "1.1.46"
packet_id_bits: 32
current_packet_id: 943105723
node_num_bits: 32
message_timeout_msec: 300000
min_app_version: 20120

preferences {
  position_broadcast_secs: 30
  ls_secs: 15
  region: TW
}
channel_settings {
  modem_config: Bw125Cr48Sf4096
  psk: "\001"
}

Channel URL https://www.meshtastic.org/c/#GAMiAQE=
Nodes in mesh:
{'num': 2885173400, 'user': {'id': '!abf84098', 'longName': 'Unknown 4098', 'shortName': '?98', 'macaddr': 'JGKr+ECY'}, 'position': {'batteryLevel': 100}}
{'num': 681021528, 'user': {'id': '!246f28979058', 'longName': 'Unknown 9058', 'shortName': '?58', 'macaddr': 'JG8ol5BY'}, 'position': {}, 'snr': 9.5}
/------------------------------------------------\
|    User    |       Position        |Battery|SNR|
|------------+-----------------------+-------+---|
|Unknown 4098|Lat:N/A,Lon:N/A,Alt:N/A|  100  |N/A|
|------------+-----------------------+-------+---|
|Unknown 9058|Lat:N/A,Lon:N/A,Alt:N/A|  N/A  |9.5|
\------------------------------------------------/
3 Likes

Hi Guys,

thank to you, I’m appy to contribute. We tried to install the new version on IZ1IVA’s raspberry and i’ve noticed a strange behaviour. I don’t know if is a system problem or something else. Running meshtastic import error for module easy_tables is rised

doing pip3 freeze I saw that the version of easy tables installed was 3.0.0, WoW how is possible? on PyPI lastest version is 0.0.4

So… I’ve uninstalled easy-table and reinstalled forcing version easy-table==0.0.4

now it works, so, do you noticed something similar could be better to set a fixed version in setup.py requirements?

Please, let me know what do you thin about that.

Regards

p.s.
@geeksville thanks for you email support :slight_smile:

2 Likes

For those who are curious about the looks of the “new” --nodes output format:

This is from @iz1kga branch and we’re looking for your take on this before making a new pull request to the main branch. Please do send in your comments!

Cheers

5 Likes

I think this is lovely! I have a couple suggestions. These may be closer to suggestions for the python tool in general and outside this scope, if so I apologize in advance!

The labels for Lat/Long/Alt may not be necessary and if removed would both make the table more (?) readable and fully compliant with ISO 6709! The other notion is also aimed at readability and involves using ANSI escape sequences to color-code data in the python tool. In the most basic implementation the table could contrast with the text in the cells, that alone would help greatly. This functionality can be made to work on non-Unix systems with something like Colorama.

2 Likes

Hi,

thanks for you suggestions, I’ll have a look on how to accomplish your requests. I’m non the best programmer you can find around, but I’ll try to do something, at least, decent.

Regards

1 Like

This looks great!!
Two possible improvements for me would be:

  1. Add this as a page in the app

  2. Option to use alternate coordinates ie OSGG (others are available)

Cheers
Paul

Hi Paul,

Could you provide some info about OSGG coordinates, I’m not so aware on this.

Regards

Hi @iz1kga

Sure in Python there is already a helpful library available:
https://pypi.org/project/OSGridConverter

How that translates for the android app I have no idea, sorry.

Paul

1 Like

OK, thanks.

for the android App could be better to ask @geeksville where is the best place where to ask new features.

Regards

1 Like

I should add that usually only the first 3 digits from eastings and northings are used, e.g.

   g=latlong2grid(52.657977,1.716038)
   str(g)

‘TG 51408 13177’ ← too much detail accurate to 1m. Given most maps used in the outdoors have a scale of 1:25k or 1:50k
‘TG 514 131’ ← usable accurate to 100m,
‘514 131’ ← most of the time you could also drop the prefix as it is only required if you have no idea where you are as they represent a 500km grid

With this feature in the App we would have true off-line mapping (paper based) :laughing:

Hi @paulcart1,

I tried to add the OSG feature to meshtastic --nodesOSG command. I’ve noticed that the lib you suggested return valid OSG coordinate only if the input lat lon are in the UK area. IMHO is not good to integrate a function that could work only in a Area. Are, in your opinion, available other libraries that will return OSG coordinate worldwide (I think no)?

regards
Manuel

1 Like

1 Like

Hi @iz1kga ,
Yes the OSGB would only be valid in the UK. I guess other regions must have similar systems; would it be possible to keep --nodeOSG and add in similar options for other regions similar to the way we currently handle frequencies

This is one thing that has always confused me… What do people do with these LAT/LON numbers as most paper maps are based on some national coordinates.

Cheers
Paul

Hi Paul,

I’ll ask @geeksville what he think about that, this is the project of him. In my opinion the best option is to write a custom script that will accomplish your needs using the python API, Code Below:

from datetime import datetime
import timeago
from easy_table import EasyTable
import meshtastic
from OSGridConverter import latlong2grid

#Returns formatted value
def formatFloat(value, formatStr="{:.2f}", unit="", default="N/A"):
    return formatStr.format(value)+unit if value else default

#Returns OSG coordinates
def getOSG(lat, lon):
    try:
        out = str(latlong2grid(lat,lon))
    except:
        out = ""

    if len(out)==14:
        return out
    else:
        return "Conversion Error"

#Returns Last Heard Time in human readable format
def getLH(ts, default="N/A"):
    return datetime.fromtimestamp(ts).strftime('%Y-%m-%d %H:%M:%S') if ts else default

#Returns time ago for the last heard
def getTimeAgo(ts, default="N/A"):
    return timeago.format(datetime.fromtimestamp(ts), datetime.now()) if ts else default if ts else default

#Print Nodes
def printNodes(nodes, osg=False):
    #Create the table and define the structure
    table = EasyTable("Nodes")
    table.setCorners("/", "\\", "\\", "/")
    table.setOuterStructure("|", "-")
    table.setInnerStructure("|", "-", "+")

    tableData = []
    i = 1
    for node in nodes:
        #aux var to get not defined keys
        lat=formatFloat(node['position'].get("latitude"), "{:.4f}", "°")
        lon=formatFloat(node['position'].get("longitude"), "{:.4f}", "°")
        alt=formatFloat(node['position'].get("altitude"), "{:.0f}", " m")
        if osg:
            pos = getOSG(node['position'].get("latitude"),node['position'].get("longitude"))
        else:
            pos = lat+", "+lon+", "+alt

        batt=formatFloat(node['position'].get("batteryLevel"), "{:.2f}", "%")
        snr=formatFloat(node.get("snr"), "{:.2f}", " dB")
        LH= getLH(node['position'].get("time"))
        timeAgo = getTimeAgo(node['position'].get("time"))
        tableData.append({"N":i, "User":node['user']['longName'],
                          "AKA":node['user']['shortName'], "ID":node['user']['id'],
                          "Position":pos,
                          "Battery":batt, "SNR":snr,
                          "LastHeard":LH, "Since":timeAgo})
        i = i+1
    Rows = sorted(tableData, key=lambda k: k['LastHeard'], reverse=True) 
    RowsOk = sorted(Rows, key=lambda k:k ['LastHeard'].startswith("N/A")) 
    table.setData(RowsOk)

    table.displayTable()

interface = meshtastic.SerialInterface()
interface.close()

printNodes(interface.nodes.values(),True)
1 Like

Hi guys,

seems that easy-tables disappeared on PyPI:

https://pypi.org/project/easy-table/

I’m wondering why while saying WOW! What’s next? We have to look for a new Library?

Regards

4 Likes