mirror of
https://github.com/meshcore-dev/meshcore_py.git
synced 2026-09-14 17:56:38 +00:00
support for run_cli_command
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "meshcore"
|
name = "meshcore"
|
||||||
version = "2.3.8"
|
version = "2.3.9"
|
||||||
authors = [
|
authors = [
|
||||||
{ name="Florent de Lamotte", email="florent@frizoncorrea.fr" },
|
{ name="Florent de Lamotte", email="florent@frizoncorrea.fr" },
|
||||||
{ name="Alex Wolden", email="awolden@gmail.com" },
|
{ name="Alex Wolden", email="awolden@gmail.com" },
|
||||||
|
|||||||
@@ -16,6 +16,12 @@ class DeviceCommands(CommandHandlerBase):
|
|||||||
b1 = bytearray(b"\x01\x03 mccli")
|
b1 = bytearray(b"\x01\x03 mccli")
|
||||||
return await self.send(b1, [EventType.SELF_INFO, EventType.ERROR])
|
return await self.send(b1, [EventType.SELF_INFO, EventType.ERROR])
|
||||||
|
|
||||||
|
async def run_cli_command(self, cmd: str) -> Event:
|
||||||
|
logger.debug(f"Sending cli command: {cmd}")
|
||||||
|
cmd_data = bytearray([CommandType.RUN_CLI_COMMAND.value])
|
||||||
|
cmd_data.extend(cmd.encode("utf-8"))
|
||||||
|
return await self.send(cmd_data, [EventType.CLI_REPLY, EventType.ERROR])
|
||||||
|
|
||||||
async def send_device_query(self) -> Event:
|
async def send_device_query(self) -> Event:
|
||||||
logger.debug("Sending device query command")
|
logger.debug("Sending device query command")
|
||||||
return await self.send(b"\x16\x03", [EventType.DEVICE_INFO, EventType.ERROR])
|
return await self.send(b"\x16\x03", [EventType.DEVICE_INFO, EventType.ERROR])
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ from typing import Optional, Union
|
|||||||
from hashlib import sha256
|
from hashlib import sha256
|
||||||
|
|
||||||
from ..events import Event, EventType
|
from ..events import Event, EventType
|
||||||
from ..packets import CommandType
|
from ..packets import CommandType, TxtType, AdvType
|
||||||
from .base import CommandHandlerBase, DestinationType, _validate_destination
|
from .base import CommandHandlerBase, DestinationType, _validate_destination
|
||||||
|
|
||||||
logger = logging.getLogger("meshcore")
|
logger = logging.getLogger("meshcore")
|
||||||
@@ -61,23 +61,33 @@ class MessagingCommands(CommandHandlerBase):
|
|||||||
return await self.send(data, [EventType.MSG_SENT, EventType.ERROR])
|
return await self.send(data, [EventType.MSG_SENT, EventType.ERROR])
|
||||||
|
|
||||||
async def send_cmd(
|
async def send_cmd(
|
||||||
self, dst: DestinationType, cmd: str, timestamp: Optional[int] = None
|
self, dst: DestinationType, cmd: str, timestamp: Optional[int] = None,
|
||||||
|
dst_type = None # if None, will have to get a contact to know this
|
||||||
) -> Event:
|
) -> Event:
|
||||||
dst_bytes = _validate_destination(dst)
|
dst_bytes = _validate_destination(dst)
|
||||||
logger.debug(f"Sending command to {dst_bytes.hex()}: {cmd}")
|
logger.debug(f"Sending command to {dst_bytes.hex()}: {cmd}")
|
||||||
|
|
||||||
if timestamp is None:
|
if timestamp is None:
|
||||||
import time
|
import time
|
||||||
|
|
||||||
timestamp = int(time.time())
|
timestamp = int(time.time())
|
||||||
|
|
||||||
data = (
|
if dst_type is None:
|
||||||
b"\x02\x01\x00"
|
if isinstance(dst, dict) and "type" in dst :
|
||||||
+ timestamp.to_bytes(4, "little")
|
dst_type = dst["type"]
|
||||||
+ dst_bytes
|
else: # assume destination is a repeater
|
||||||
+ cmd.encode("utf-8")
|
logger.warning("Can't determine destination type, please ensure contacts first or specify dst_type when calling `send_cmd`. Assuming it's a repeater.")
|
||||||
)
|
dst_type = AdvType.REPEATER.value
|
||||||
return await self.send(data, [EventType.MSG_SENT, EventType.ERROR])
|
|
||||||
|
cmd_data = bytearray([CommandType.SEND_TXT_MSG.value])
|
||||||
|
if dst_type == AdvType.REPEATER.value :
|
||||||
|
cmd_data.append(TxtType.CLI_DATA.value)
|
||||||
|
else:
|
||||||
|
cmd_data.append(TxtType.CLI_CMD.value)
|
||||||
|
cmd_data.append(0) # first and only attempt
|
||||||
|
cmd_data.extend(timestamp.to_bytes(4, "little"))
|
||||||
|
cmd_data.extend(dst_bytes)
|
||||||
|
cmd_data.extend(cmd.encode("utf-8"))
|
||||||
|
return await self.send(cmd_data, [EventType.MSG_SENT, EventType.ERROR])
|
||||||
|
|
||||||
async def send_msg(
|
async def send_msg(
|
||||||
self, dst: DestinationType, msg: str, timestamp: Optional[int] = None,
|
self, dst: DestinationType, msg: str, timestamp: Optional[int] = None,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class EventType(Enum):
|
|||||||
NEXT_CONTACT = "next_contact"
|
NEXT_CONTACT = "next_contact"
|
||||||
AUTOADD_CONFIG = "autoadd_config"
|
AUTOADD_CONFIG = "autoadd_config"
|
||||||
ADVERT_PATH = "advert_path"
|
ADVERT_PATH = "advert_path"
|
||||||
|
CLI_REPLY = "cli_reply"
|
||||||
|
|
||||||
# Push notifications
|
# Push notifications
|
||||||
ADVERTISEMENT = "advertisement"
|
ADVERTISEMENT = "advertisement"
|
||||||
|
|||||||
@@ -1,5 +1,18 @@
|
|||||||
from enum import Enum
|
from enum import Enum
|
||||||
|
|
||||||
|
class AdvType(Enum):
|
||||||
|
NONE = 0x00
|
||||||
|
CHAT = 0x01
|
||||||
|
REPEATER = 0x02
|
||||||
|
ROOM = 0x03
|
||||||
|
SENSOR = 0x04
|
||||||
|
|
||||||
|
class TxtType(Enum):
|
||||||
|
PLAIN = 0x00
|
||||||
|
CLI_DATA = 0x01
|
||||||
|
SIGNED_PLAIN = 0x02
|
||||||
|
CLI_CMD = 0x03
|
||||||
|
|
||||||
class AnonReqType(Enum):
|
class AnonReqType(Enum):
|
||||||
REGIONS = 0x01
|
REGIONS = 0x01
|
||||||
OWNER = 0x02
|
OWNER = 0x02
|
||||||
@@ -75,6 +88,8 @@ class CommandType(Enum):
|
|||||||
SET_PATH_HASH_MODE = 61
|
SET_PATH_HASH_MODE = 61
|
||||||
SET_DEFAULT_FLOOD_SCOPE = 63
|
SET_DEFAULT_FLOOD_SCOPE = 63
|
||||||
GET_DEFAULT_FLOOD_SCOPE = 64
|
GET_DEFAULT_FLOOD_SCOPE = 64
|
||||||
|
SEND_RAW_PACKET = 65
|
||||||
|
RUN_CLI_COMMAND = 66
|
||||||
|
|
||||||
# Packet prefixes for the protocol
|
# Packet prefixes for the protocol
|
||||||
class PacketType(Enum):
|
class PacketType(Enum):
|
||||||
@@ -107,6 +122,7 @@ class PacketType(Enum):
|
|||||||
ALLOWED_REPEAT_FREQ = 26
|
ALLOWED_REPEAT_FREQ = 26
|
||||||
CHANNEL_DATA_RECV = 27
|
CHANNEL_DATA_RECV = 27
|
||||||
DEFAULT_FLOOD_SCOPE = 28
|
DEFAULT_FLOOD_SCOPE = 28
|
||||||
|
CLI_REPLY = 29
|
||||||
|
|
||||||
# Push notifications
|
# Push notifications
|
||||||
ADVERTISEMENT = 0x80
|
ADVERTISEMENT = 0x80
|
||||||
|
|||||||
@@ -1052,6 +1052,11 @@ class MessageReader:
|
|||||||
res = {"rx_delay": rx_delay, "airtime_factor": airtime_factor}
|
res = {"rx_delay": rx_delay, "airtime_factor": airtime_factor}
|
||||||
await self.dispatcher.dispatch(Event(EventType.TUNING_PARAMS, res))
|
await self.dispatcher.dispatch(Event(EventType.TUNING_PARAMS, res))
|
||||||
|
|
||||||
|
elif packet_type_value == PacketType.CLI_REPLY.value:
|
||||||
|
res = {}
|
||||||
|
res["text"] = data[1:].decode("utf-8", "ignore")
|
||||||
|
await self.dispatcher.dispatch(Event(EventType.CLI_REPLY, res))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
logger.debug(f"Unhandled data received {data}")
|
logger.debug(f"Unhandled data received {data}")
|
||||||
logger.debug(f"Unhandled packet type: {packet_type_value}")
|
logger.debug(f"Unhandled packet type: {packet_type_value}")
|
||||||
|
|||||||
Reference in New Issue
Block a user