Skip to content

Add backup / restore admin commands #747

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 8 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
43 changes: 43 additions & 0 deletions meshtastic/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,21 @@ def onConnected(interface):
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).removeFavorite(args.remove_favorite_node)

if args.backup_prefs:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).re(args.backup_preferences)

if args.restore_prefs:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).re(args.backup_preferences)

if args.remove_backup_prefs:
closeNow = True
waitForAckNak = True
interface.getNode(args.dest, False, **getNode_kwargs).re(args.remove_backup_preferences)

if args.set_ignored_node:
closeNow = True
waitForAckNak = True
Expand Down Expand Up @@ -1794,12 +1809,40 @@ def addRemoteAdminArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentPars
action="store_true",
)

group.add_argument(
"--backup-prefs",
help="Tell the destination node to create a backup preferences file."
"Location: 0 for local flash, 1 for SD card.",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be nice if we allow people to pass FLASH and SD here. I think we could do that by trying to parse as an int, and if it fails, throw it at something like admin_pb2.AdminMessage.BackupLocation.__getattr__('FLASH') to convert.

I think this could be done by adding a helper function and passing it as type to these add_argument calls:

def backup_location(string):
    try:
        return int(string)
    except ValueError:
        return admin_pb2.AdminMessage.BackupLocation.__getattr__(string)

I'm a bit tired so hopefully I'm relaying this properly, heh.

default=None,
nargs="?",
const=0,
)

group.add_argument(
"--restore-prefs",
help="Tell the destination node to remove backup preferences files."
"Location: 0 for local flash, 1 for SD card.",
default=None,
nargs="?",
const=0,
)

group.add_argument(
"--remove-backup-prefs",
help="Tell the destination node to remove backup preferences files."
"Location: 0 for local flash, 1 for SD card.",
default=None,
nargs="?",
const=0,
)

group.add_argument(
"--remove-node",
help="Tell the destination node to remove a specific node from its NodeDB. "
"Use the node ID with a '!' or '0x' prefix or the node number.",
metavar="!xxxxxxxx"
)

group.add_argument(
"--set-favorite-node",
help="Tell the destination node to set the specified node to be favorited on the NodeDB. "
Expand Down
41 changes: 40 additions & 1 deletion meshtastic/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -707,8 +707,47 @@ def setFavorite(self, nodeId: Union[int, str]):
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)

def backupPreferences(self, location: Optional[int] = 0):
"""Tell the node to backup preferences to flash."""
self.ensureSessionKey()

p = admin_pb2.AdminMessage()
p.backup_preferences = location

if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)

def restorePreferences(self, location: Optional[int] = 0):
"""Tell the node to restore preferences from backup."""
self.ensureSessionKey()

p = admin_pb2.AdminMessage()
p.restore_preferences = location

if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)

def removePreferencesBackups(self, location: Optional[int] = 0):
"""Tell the node to remove backup preferences from the filesystem."""
self.ensureSessionKey()

p = admin_pb2.AdminMessage()
p.remove_backup_preferences = location

if self == self.iface.localNode:
onResponse = None
else:
onResponse = self.onAckNak
return self._sendAdmin(p, onResponse=onResponse)

def removeFavorite(self, nodeId: Union[int, str]):
"""Tell the node to set the specified node ID to be un-favorited on the NodeDB on the device"""
"""Tell the node to set the specified node ID to be un-favorited on the NodeDB on the device."""
self.ensureSessionKey()
if isinstance(nodeId, str):
if nodeId.startswith("!"):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "meshtastic"
version = "2.5.12"
version = "2.6.0"
description = "Python API & client shell for talking to Meshtastic devices"
authors = ["Meshtastic Developers <[email protected]>"]
license = "GPL-3.0-only"
Expand Down
Loading