manage timeouts, and override for contact

This commit is contained in:
Florent de Lamotte 2025-07-16 16:57:59 +02:00
parent 65cd239952
commit 581116def5
2 changed files with 45 additions and 14 deletions

View file

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project] [project]
name = "meshcore-cli" name = "meshcore-cli"
version = "1.1.2" version = "1.1.3"
authors = [ authors = [
{ name="Florent de Lamotte", email="florent@frizoncorrea.fr" }, { name="Florent de Lamotte", email="florent@frizoncorrea.fr" },
] ]
@ -17,7 +17,7 @@ classifiers = [
] ]
license = "MIT" license = "MIT"
license-files = ["LICEN[CS]E*"] license-files = ["LICEN[CS]E*"]
dependencies = [ "meshcore >= 1.9.15", "prompt_toolkit >= 3.0.50", "requests >= 2.28.0" ] dependencies = [ "meshcore >= 1.9.16", "prompt_toolkit >= 3.0.50", "requests >= 2.28.0" ]
[project.urls] [project.urls]
Homepage = "https://github.com/fdlamotte/meshcore-cli" Homepage = "https://github.com/fdlamotte/meshcore-cli"

View file

@ -22,7 +22,7 @@ from prompt_toolkit.shortcuts import radiolist_dialog
from meshcore import MeshCore, EventType, logger from meshcore import MeshCore, EventType, logger
# Version # Version
VERSION = "v1.1.2" VERSION = "v1.1.3"
# default ble address is stored in a config file # default ble address is stored in a config file
MCCLI_CONFIG_DIR = str(Path.home()) + "/.config/meshcore/" MCCLI_CONFIG_DIR = str(Path.home()) + "/.config/meshcore/"
@ -399,6 +399,16 @@ def make_completion_dict(contacts, pending={}, to=None):
"req_binary" : None, "req_binary" : None,
}) })
if to['type'] == 1 :
completion_list.update({
"get" : {
"timeout":None,
},
"set" : {
"timeout":None,
},
})
if to['type'] > 1 : # repeaters and room servers if to['type'] > 1 : # repeaters and room servers
completion_list.update({ completion_list.update({
"login" : None, "login" : None,
@ -432,7 +442,8 @@ def make_completion_dict(contacts, pending={}, to=None):
"lat" : None, "lat" : None,
"lon" : None, "lon" : None,
"telemetry" : None, "telemetry" : None,
"status" : None "status" : None,
"timeout" : None,
}, },
"set" : {"name" : None, "set" : {"name" : None,
"radio" : {",,,":None, "f,bw,sf,cr": None}, "radio" : {",,,":None, "f,bw,sf,cr": None},
@ -450,6 +461,7 @@ def make_completion_dict(contacts, pending={}, to=None):
"direct.txdelay" : None, "direct.txdelay" : None,
"lat" : None, "lat" : None,
"lon" : None, "lon" : None,
"timeout" : None,
}, },
"erase": None, "erase": None,
"log" : {"start" : None, "stop" : None, "erase" : None} "log" : {"start" : None, "stop" : None, "erase" : None}
@ -667,6 +679,13 @@ Line starting with \"$\" or \".\" will issue a meshcli command.
args = [line, contact['adv_name']] args = [line, contact['adv_name']]
await process_cmds(mc, args) await process_cmds(mc, args)
elif contact["type"] > 0 and line.startswith("set timeout "):
cmds=line.split(" ")
contact["timeout"] = float(cmds[2])
elif contact["type"] > 0 and line == "get timeout":
print(f"timeout: {0 if not 'timeout' in contact else contact['timeout']}")
elif contact["type"] == 4 and\ elif contact["type"] == 4 and\
(line == "get acl" or line.startswith("get mma ")) or\ (line == "get acl" or line.startswith("get mma ")) or\
contact["type"] > 1 and\ contact["type"] > 1 and\
@ -767,7 +786,8 @@ async def msg_ack (mc, contact, msg) :
return False return False
exp_ack = result.payload["expected_ack"].hex() exp_ack = result.payload["expected_ack"].hex()
res = await mc.wait_for_event(EventType.ACK, attribute_filters={"code": exp_ack}, timeout=5) timeout = result.payload["suggested_timeout"] / 1000 * 1.2 if not "timeout" in contact else contact["timeout"]
res = await mc.wait_for_event(EventType.ACK, attribute_filters={"code": exp_ack}, timeout=timeout)
if res is None : if res is None :
return False return False
@ -1354,7 +1374,8 @@ async def next_cmd(mc, cmds, json_output=False):
else: else:
print(f"Error while loging: {res}") print(f"Error while loging: {res}")
else: # should probably wait for the good ack else: # should probably wait for the good ack
res = await mc.wait_for_event(EventType.LOGIN_SUCCESS) timeout = res.payload["suggested_timeout"]/800 if not "timeout" in contact else contact["timeout"]
res = await mc.wait_for_event(EventType.LOGIN_SUCCESS, timeout=timeout)
logger.debug(res) logger.debug(res)
if res is None: if res is None:
print("Login failed : Timeout waiting response") print("Login failed : Timeout waiting response")
@ -1382,6 +1403,12 @@ async def next_cmd(mc, cmds, json_output=False):
else: else:
print("Logout ok") print("Logout ok")
case "timeout_for_contact" :
argnum = 2
await mc.ensure_contacts()
contact = mc.get_contact_by_name(cmds[1])
contact["timeout"] = float(cmds[2])
case "req_status" | "rs" : case "req_status" | "rs" :
argnum = 1 argnum = 1
await mc.ensure_contacts() await mc.ensure_contacts()
@ -1391,7 +1418,8 @@ async def next_cmd(mc, cmds, json_output=False):
if res.type == EventType.ERROR: if res.type == EventType.ERROR:
print(f"Error while requesting status: {res}") print(f"Error while requesting status: {res}")
else : else :
res = await mc.wait_for_event(EventType.STATUS_RESPONSE) timeout = res.payload["suggested_timeout"]/800 if not "timeout" in contact else contact["timeout"]
res = await mc.wait_for_event(EventType.STATUS_RESPONSE, timeout=timeout)
logger.debug(res) logger.debug(res)
if res is None: if res is None:
if json_output : if json_output :
@ -1410,7 +1438,8 @@ async def next_cmd(mc, cmds, json_output=False):
if res.type == EventType.ERROR: if res.type == EventType.ERROR:
print(f"Error while requesting telemetry") print(f"Error while requesting telemetry")
else: else:
res = await mc.wait_for_event(EventType.TELEMETRY_RESPONSE) timeout = res.payload["suggested_timeout"]/800 if not "timeout" in contact else contact["timeout"]
res = await mc.wait_for_event(EventType.TELEMETRY_RESPONSE, timeout=timeout)
logger.debug(res) logger.debug(res)
if res is None: if res is None:
if json_output : if json_output :
@ -1424,7 +1453,8 @@ async def next_cmd(mc, cmds, json_output=False):
argnum = 1 argnum = 1
await mc.ensure_contacts() await mc.ensure_contacts()
contact = mc.get_contact_by_name(cmds[1]) contact = mc.get_contact_by_name(cmds[1])
res = await mc.commands.binary.req_telemetry(contact) timeout = 0 if not "timeout" in contact else contact["timeout"]
res = await mc.commands.binary.req_telemetry(contact, timeout)
if res is None : if res is None :
if json_output : if json_output :
print(json.dumps({"error" : "Getting data"})) print(json.dumps({"error" : "Getting data"}))
@ -1453,7 +1483,8 @@ async def next_cmd(mc, cmds, json_output=False):
to_secs = int(cmds[3][0:-1]) * 3600 to_secs = int(cmds[3][0:-1]) * 3600
else : else :
to_secs = int(cmds[3]) * 60 to_secs = int(cmds[3]) * 60
res = await mc.commands.binary.req_mma(contact, from_secs, to_secs) timeout = 0 if not "timeout" in contact else contact["timeout"]
res = await mc.commands.binary.req_mma(contact, from_secs, to_secs, timeout)
if res is None : if res is None :
if json_output : if json_output :
print(json.dumps({"error" : "Getting data"})) print(json.dumps({"error" : "Getting data"}))
@ -1466,7 +1497,8 @@ async def next_cmd(mc, cmds, json_output=False):
argnum = 1 argnum = 1
await mc.ensure_contacts() await mc.ensure_contacts()
contact = mc.get_contact_by_name(cmds[1]) contact = mc.get_contact_by_name(cmds[1])
res = await mc.commands.binary.req_acl(contact) timeout = 0 if not "timeout" in contact else contact["timeout"]
res = await mc.commands.binary.req_acl(contact, timeout)
if res is None : if res is None :
if json_output : if json_output :
print(json.dumps({"error" : "Getting data"})) print(json.dumps({"error" : "Getting data"}))
@ -1485,14 +1517,13 @@ async def next_cmd(mc, cmds, json_output=False):
else: else:
name = f"{ct['adv_name']:<20} [{e['key']}]" name = f"{ct['adv_name']:<20} [{e['key']}]"
print(f"{name:{' '}<35}: {e['perm']:02x}") print(f"{name:{' '}<35}: {e['perm']:02x}")
case "req_binary" : case "req_binary" :
argnum = 2 argnum = 2
await mc.ensure_contacts() await mc.ensure_contacts()
contact = mc.get_contact_by_name(cmds[1]) contact = mc.get_contact_by_name(cmds[1])
res = await mc.commands.binary.req_binary(contact, bytes.fromhex(cmds[2])) timeout = 0 if not "timeout" in contact else contact["timeout"]
res = await mc.commands.binary.req_binary(contact, bytes.fromhex(cmds[2]), timeout)
if res is None : if res is None :
if json_output : if json_output :
print(json.dumps({"error" : "Getting binary data"})) print(json.dumps({"error" : "Getting binary data"}))