meshcore-cli 1.2.12__tar.gz → 1.2.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshcore-cli
3
- Version: 1.2.12
3
+ Version: 1.2.14
4
4
  Summary: Command line interface to meshcore companion radios
5
5
  Project-URL: Homepage, https://github.com/fdlamotte/meshcore-cli
6
6
  Project-URL: Issues, https://github.com/fdlamotte/meshcore-cli/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "meshcore-cli"
7
- version = "1.2.12"
7
+ version = "1.2.14"
8
8
  authors = [
9
9
  { name="Florent de Lamotte", email="florent@frizoncorrea.fr" },
10
10
  ]
@@ -32,7 +32,7 @@ import re
32
32
  from meshcore import MeshCore, EventType, logger
33
33
 
34
34
  # Version
35
- VERSION = "v1.2.12"
35
+ VERSION = "v1.2.14"
36
36
 
37
37
  # default ble address is stored in a config file
38
38
  MCCLI_CONFIG_DIR = str(Path.home()) + "/.config/meshcore/"
@@ -76,13 +76,11 @@ ANSI_YELLOW = "\033[0;33m"
76
76
  ANSI_BYELLOW = "\033[1;33m"
77
77
 
78
78
  #Unicode chars
79
- # some possible symbols for prompts 🭬🬛🬗🭬🬛🬃🬗🭬🬛🬃🬗🬏🭀🭋🭨🮋
80
- ARROW_TAIL = "🭨"
81
- ARROW_HEAD = "🭬"
82
-
83
- if platform.system() == 'Windows' or platform.system() == 'Darwin':
84
- ARROW_TAIL = ""
85
- ARROW_HEAD = " "
79
+ # some possible symbols for prompts 🭬🬛🬗🭬🬛🬃🬗🭬🬛🬃🬗🬏🭀🭋🭨🮋
80
+ ARROW_HEAD = ""
81
+ SLASH_END = ""
82
+ SLASH_START = ""
83
+ INVERT_SLASH = False
86
84
 
87
85
  def escape_ansi(line):
88
86
  ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
@@ -470,7 +468,7 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None):
470
468
  "login" : contact_list,
471
469
  "cmd" : contact_list,
472
470
  "req_status" : contact_list,
473
- "req_bstatus" : contact_list,
471
+ "req_neighbours": contact_list,
474
472
  "logout" : contact_list,
475
473
  "req_telemetry" : contact_list,
476
474
  "req_binary" : contact_list,
@@ -495,7 +493,6 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None):
495
493
  "print_snr" : {"on":None, "off": None},
496
494
  "json_msgs" : {"on":None, "off": None},
497
495
  "color" : {"on":None, "off":None},
498
- "print_name" : {"on":None, "off":None},
499
496
  "print_adverts" : {"on":None, "off":None},
500
497
  "json_log_rx" : {"on":None, "off":None},
501
498
  "channel_echoes" : {"on":None, "off":None},
@@ -525,7 +522,6 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None):
525
522
  "print_snr":None,
526
523
  "json_msgs":None,
527
524
  "color":None,
528
- "print_name":None,
529
525
  "print_adverts":None,
530
526
  "json_log_rx":None,
531
527
  "channel_echoes":None,
@@ -577,7 +573,6 @@ def make_completion_dict(contacts, pending={}, to=None, channels=None):
577
573
  "login" : None,
578
574
  "logout" : None,
579
575
  "req_status" : None,
580
- "req_bstatus" : None,
581
576
  "req_neighbours": None,
582
577
  "cmd" : None,
583
578
  "ver" : None,
@@ -765,26 +760,32 @@ Line starting with \"$\" or \".\" will issue a meshcli command.
765
760
 
766
761
  color = process_event_message.color
767
762
  classic = interactive_loop.classic or not color
768
- print_name = interactive_loop.print_name
769
763
 
770
764
  if classic:
771
765
  prompt = ""
772
766
  else:
773
767
  prompt = f"{ANSI_INVERT}"
774
768
 
775
- if print_name or contact is None :
776
- if color:
777
- prompt = prompt + f"{ANSI_BGRAY}"
778
- prompt = prompt + f"{mc.self_info['name']}"
779
- if contact is None: # display scope
780
- if not scope is None:
781
- prompt = prompt + f"|{scope}"
769
+ prompt = prompt + f"{ANSI_BGRAY}"
770
+ prompt = prompt + f"{mc.self_info['name']}"
771
+ if contact is None: # display scope
772
+ if not scope is None:
773
+ prompt = prompt + f"|{scope}"
774
+
775
+ if contact is None :
782
776
  if classic :
783
- prompt = prompt + "> "
777
+ prompt = prompt + ">"
784
778
  else :
785
- prompt = prompt + f"{ANSI_NORMAL}{ARROW_HEAD}{ANSI_INVERT}"
786
-
787
- if not contact is None :
779
+ prompt = prompt + f"{ANSI_NORMAL}{ARROW_HEAD}"
780
+ else:
781
+ if classic :
782
+ prompt = prompt + "/"
783
+ else :
784
+ if INVERT_SLASH:
785
+ prompt = prompt + f"{ANSI_INVERT}"
786
+ else:
787
+ prompt = prompt + f"{ANSI_NORMAL}"
788
+ prompt = prompt + f"{SLASH_START}"
788
789
  if not last_ack:
789
790
  prompt = prompt + f"{ANSI_BRED}"
790
791
  if classic :
@@ -800,11 +801,9 @@ Line starting with \"$\" or \".\" will issue a meshcli command.
800
801
  else :
801
802
  prompt = prompt + f"{ANSI_BBLUE}"
802
803
  if not classic:
804
+ prompt = prompt + f"{SLASH_END}"
803
805
  prompt = prompt + f"{ANSI_INVERT}"
804
806
 
805
- if print_name and not classic :
806
- prompt = prompt + f"{ANSI_NORMAL}{ARROW_TAIL}{ANSI_INVERT}"
807
-
808
807
  prompt = prompt + f"{contact['adv_name']}"
809
808
  if contact["type"] == 0 or contact["out_path_len"]==-1:
810
809
  if scope is None:
@@ -818,14 +817,15 @@ Line starting with \"$\" or \".\" will issue a meshcli command.
818
817
  prompt = prompt + "|" + contact["out_path"]
819
818
 
820
819
  if classic :
821
- prompt = prompt + f"{ANSI_NORMAL}> "
820
+ prompt = prompt + f"{ANSI_NORMAL}>"
822
821
  else:
823
822
  prompt = prompt + f"{ANSI_NORMAL}{ARROW_HEAD}"
824
823
 
825
824
  prompt = prompt + f"{ANSI_END}"
826
825
 
827
- if not color :
828
- prompt=escape_ansi(prompt)
826
+ prompt = prompt + " "
827
+ if not color :
828
+ prompt=escape_ansi(prompt)
829
829
 
830
830
  session.app.ttimeoutlen = 0.2
831
831
  session.app.timeoutlen = 0.2
@@ -1036,8 +1036,10 @@ Line starting with \"$\" or \".\" will issue a meshcli command.
1036
1036
  except asyncio.CancelledError:
1037
1037
  # Handle task cancellation from KeyboardInterrupt in asyncio.run()
1038
1038
  print("Exiting cli")
1039
- interactive_loop.classic = False
1040
- interactive_loop.print_name = True
1039
+ if platform.system() == "Darwin" or platform.system() == "Windows":
1040
+ interactive_loop.classic = True
1041
+ else:
1042
+ interactive_loop.classic = False
1041
1043
 
1042
1044
  async def process_contact_chat_line(mc, contact, line):
1043
1045
  if contact["type"] == 0:
@@ -1085,7 +1087,6 @@ async def process_contact_chat_line(mc, contact, line):
1085
1087
  line == "contact_info" or line == "ci" or\
1086
1088
  line == "req_status" or line == "rs" or\
1087
1089
  line == "req_neighbours" or line == "rn" or\
1088
- line == "req_bstatus" or line == "rbs" or\
1089
1090
  line == "req_telemetry" or line == "rt" or\
1090
1091
  line == "req_acl" or\
1091
1092
  line == "path" or\
@@ -1615,7 +1616,7 @@ async def print_disc_trace_to (mc, contact):
1615
1616
 
1616
1617
  async def next_cmd(mc, cmds, json_output=False):
1617
1618
  """ process next command """
1618
- global ARROW_TAIL, ARROW_HEAD
1619
+ global ARROW_HEAD, SLASH_START, SLASH_END, INVERT_SLASH
1619
1620
  try :
1620
1621
  argnum = 0
1621
1622
 
@@ -1741,18 +1742,18 @@ async def next_cmd(mc, cmds, json_output=False):
1741
1742
  msg_ack.max_attempts=int(cmds[2])
1742
1743
  case "flood_after":
1743
1744
  msg_ack.flood_after=int(cmds[2])
1744
- case "print_name":
1745
- interactive_loop.print_name = (cmds[2] == "on")
1746
- if json_output :
1747
- print(json.dumps({"cmd" : cmds[1], "param" : cmds[2]}))
1748
1745
  case "classic_prompt":
1749
1746
  interactive_loop.classic = (cmds[2] == "on")
1750
1747
  if json_output :
1751
1748
  print(json.dumps({"cmd" : cmds[1], "param" : cmds[2]}))
1752
- case "arrow_tail":
1753
- ARROW_TAIL = cmds[2]
1754
1749
  case "arrow_head":
1755
1750
  ARROW_HEAD = cmds[2]
1751
+ case "slash_start":
1752
+ SLASH_START = cmds[2]
1753
+ case "slash_end":
1754
+ SLASH_END = cmds[2]
1755
+ case "invert_slash":
1756
+ INVERT_SLASH = cmds[2] == "on"
1756
1757
  case "color" :
1757
1758
  process_event_message.color = (cmds[2] == "on")
1758
1759
  if json_output :
@@ -1983,11 +1984,6 @@ async def next_cmd(mc, cmds, json_output=False):
1983
1984
  print(json.dumps({"flood_after" : msg_ack.flood_after}))
1984
1985
  else:
1985
1986
  print(f"flood_after: {msg_ack.flood_after}")
1986
- case "print_name":
1987
- if json_output :
1988
- print(json.dumps({"print_name" : interactive_loop.print_name}))
1989
- else:
1990
- print(f"{'on' if interactive_loop.print_name else 'off'}")
1991
1987
  case "classic_prompt":
1992
1988
  if json_output :
1993
1989
  print(json.dumps({"classic_prompt" : interactive_loop.classic}))
@@ -2344,12 +2340,11 @@ async def next_cmd(mc, cmds, json_output=False):
2344
2340
  else :
2345
2341
  color = process_event_message.color
2346
2342
  classic = interactive_loop.classic or not color
2347
- print("]",end="")
2348
2343
  for t in ev.payload["path"]:
2349
2344
  if classic :
2350
2345
  print("→",end="")
2351
2346
  else:
2352
- print(f" {ANSI_INVERT}", end="")
2347
+ print(f"{ANSI_INVERT}", end="")
2353
2348
  snr = t['snr']
2354
2349
  if color:
2355
2350
  if snr >= 10 :
@@ -2368,7 +2363,7 @@ async def next_cmd(mc, cmds, json_output=False):
2368
2363
  if "hash" in t:
2369
2364
  print(f"[{t['hash']}]",end="")
2370
2365
  else:
2371
- print("[")
2366
+ print()
2372
2367
 
2373
2368
  case "login" | "l" :
2374
2369
  argnum = 2
@@ -2428,46 +2423,6 @@ async def next_cmd(mc, cmds, json_output=False):
2428
2423
  contact = mc.get_contact_by_name(cmds[1])
2429
2424
  contact["timeout"] = float(cmds[2])
2430
2425
 
2431
- case "req_status" | "rs" :
2432
- argnum = 1
2433
- await mc.ensure_contacts()
2434
- contact = mc.get_contact_by_name(cmds[1])
2435
- res = await mc.commands.send_statusreq(contact)
2436
- logger.debug(res)
2437
- if res.type == EventType.ERROR:
2438
- print(f"Error while requesting status: {res}")
2439
- else :
2440
- timeout = res.payload["suggested_timeout"]/800 if not "timeout" in contact or contact['timeout']==0 else contact["timeout"]
2441
- res = await mc.wait_for_event(EventType.STATUS_RESPONSE, timeout=timeout)
2442
- logger.debug(res)
2443
- if res is None:
2444
- if json_output :
2445
- print(json.dumps({"error" : "Timeout waiting status"}))
2446
- else:
2447
- print("Timeout waiting status")
2448
- else :
2449
- print(json.dumps(res.payload, indent=4))
2450
-
2451
- case "req_telemetry" | "rt" :
2452
- argnum = 1
2453
- await mc.ensure_contacts()
2454
- contact = mc.get_contact_by_name(cmds[1])
2455
- res = await mc.commands.send_telemetry_req(contact)
2456
- logger.debug(res)
2457
- if res.type == EventType.ERROR:
2458
- print(f"Error while requesting telemetry")
2459
- else:
2460
- timeout = res.payload["suggested_timeout"]/800 if not "timeout" in contact or contact['timeout']==0 else contact["timeout"]
2461
- res = await mc.wait_for_event(EventType.TELEMETRY_RESPONSE, timeout=timeout)
2462
- logger.debug(res)
2463
- if res is None:
2464
- if json_output :
2465
- print(json.dumps({"error" : "Timeout waiting telemetry"}))
2466
- else:
2467
- print("Timeout waiting telemetry")
2468
- else :
2469
- print(json.dumps(res.payload, indent=4))
2470
-
2471
2426
  case "disc_path" | "dp" :
2472
2427
  argnum = 1
2473
2428
  await mc.ensure_contacts()
@@ -2553,7 +2508,7 @@ async def next_cmd(mc, cmds, json_output=False):
2553
2508
 
2554
2509
  print(f" {name:16} {type:>4} SNR: {n['SNR_in']:6,.2f}->{n['SNR']:6,.2f} RSSI: ->{n['RSSI']:4}")
2555
2510
 
2556
- case "req_btelemetry"|"rbt" :
2511
+ case "req_telemetry"|"rt" :
2557
2512
  argnum = 1
2558
2513
  await mc.ensure_contacts()
2559
2514
  contact = mc.get_contact_by_name(cmds[1])
@@ -2565,9 +2520,13 @@ async def next_cmd(mc, cmds, json_output=False):
2565
2520
  else:
2566
2521
  print("Error getting data")
2567
2522
  else :
2568
- print(json.dumps(res))
2523
+ print(json.dumps({
2524
+ "name": contact["adv_name"],
2525
+ "pubkey_pre": contact["public_key"][0:12],
2526
+ "lpp": res,
2527
+ }, indent = 4))
2569
2528
 
2570
- case "req_bstatus"|"rbs" :
2529
+ case "req_status"|"rs" :
2571
2530
  argnum = 1
2572
2531
  await mc.ensure_contacts()
2573
2532
  contact = mc.get_contact_by_name(cmds[1])
@@ -3174,6 +3133,7 @@ def usage () :
3174
3133
  -D : debug
3175
3134
  -S : scan for devices and show a selector
3176
3135
  -l : list available ble/serial devices and exit
3136
+ -C : toggles classic mode for prompt
3177
3137
  -c <on/off> : disables most of color output if off
3178
3138
  -T <timeout> : timeout for the ble scan (-S and -l) default 2s
3179
3139
  -a <address> : specifies device address (can be a name)
@@ -3242,12 +3202,14 @@ async def main(argv):
3242
3202
  with open(MCCLI_ADDRESS, encoding="utf-8") as f :
3243
3203
  address = f.readline().strip()
3244
3204
 
3245
- opts, args = getopt.getopt(argv, "a:d:s:ht:p:b:fjDhvSlT:Pc:")
3205
+ opts, args = getopt.getopt(argv, "a:d:s:ht:p:b:fjDhvSlT:Pc:C")
3246
3206
  for opt, arg in opts :
3247
3207
  match opt:
3248
3208
  case "-c" :
3249
3209
  if arg == "off":
3250
3210
  process_event_message.color = False
3211
+ case "-C":
3212
+ interactive_loop.classic = not interactive_loop.classic
3251
3213
  case "-d" : # name specified on cmdline
3252
3214
  address = arg
3253
3215
  case "-a" : # address specified on cmdline
File without changes
File without changes
File without changes
File without changes
File without changes