mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-07-07 18:30:58 +02:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 992296b0c1 | |||
| e2adb73fea | |||
| 5386f39611 | |||
| 2175fcb44d | |||
| c16e19336a | |||
| 7f5b50b6f3 | |||
| dff2ea0249 | |||
| 029d22ff9c | |||
| 02c77dcca8 | |||
| d4f6a8ba9b | |||
| 31ca098de5 | |||
| 794502d63f | |||
| ad4785baec | |||
| 493fadf0d2 | |||
| db04f4dc9f | |||
| 2ecaaae2a9 | |||
| 7cafefb59b | |||
| 85cd05177e | |||
| 69150b2efc | |||
| 4695537291 | |||
| f1ad6333dd | |||
| 1089cfd256 | |||
| 2ae4483e1f | |||
| fb2c947a14 | |||
| ac161e5764 | |||
| 1f606e5fa0 | |||
| c1a9bb63c7 | |||
| 29e5b36dbf | |||
| 671af01e0b | |||
| 82323a8783 | |||
| 98549e05b9 | |||
| 1fafb344de | |||
| 0368259bf7 | |||
| c54c2e9f8d | |||
| 96fa6b3063 | |||
| 15e105b3fc | |||
| 1f83de5698 | |||
| 660c7e60bc | |||
| 4656a9a939 | |||
| 3a5881975c | |||
| 0fdf771980 |
@@ -22,6 +22,7 @@ meshview-web.pid
|
||||
/table_details.py
|
||||
config.ini
|
||||
*.log
|
||||
*.status.json
|
||||
|
||||
# Screenshots
|
||||
screenshots/*
|
||||
|
||||
+1
-1
@@ -52,7 +52,7 @@ Unacceptable behavior includes harassment, insults, hate speech, personal attack
|
||||
|
||||
---
|
||||
|
||||
## I Want to Contribute
|
||||
## I Want to Contribute!
|
||||
|
||||
### Legal Notice
|
||||
By contributing to Meshview, you agree that:
|
||||
|
||||
@@ -4,6 +4,21 @@
|
||||
|
||||
The project serves as a real-time monitoring and diagnostic tool for the Meshtastic mesh network. It provides detailed insights into network activity, including message traffic, node positions, and telemetry data.
|
||||
|
||||
### Version 3.0.7 — May 2026
|
||||
- Reliability report: added a dedicated reliability page for checking how well a selected node is heard across the mesh, including heard/missed status, packet counts, hop counts, gateway tables, and a map view.
|
||||
- Node list/map UX: added node list filtering for wider active-node ranges, included all database nodes where appropriate, and made map node colors persistent across reboots.
|
||||
- QR/API fixes: corrected QR code generation when a node role is missing or unavailable.
|
||||
- Database cleanup: removed stored node public key data and added the Alembic migration to drop `node.public_key`.
|
||||
- Protobufs: refreshed Meshtastic protobuf Python modules to upstream commit
|
||||
- Tooling: improved the protobuf updater so it supports raw commit SHAs, the newer upstream `meshtastic/*.proto` layout, generated `.pyi` stubs, and the vendored `nanopb`/`serial_hal` outputs.
|
||||
|
||||
### Version 3.0.6 — March 2026
|
||||
- Daily snapshots: added the `daily_snapshot` table, scheduled snapshot capture, and `/api/snapshots/daily` for historical node, packet, and gateway counts.
|
||||
- Stats/UI: expanded stats views with snapshot data and added channel filters to Chat and Firehose.
|
||||
- Map/node fixes: corrected node location handling, map popup behavior, packet page display, and node list sorting.
|
||||
- Ingestion/API reliability: improved duplicate `PacketSeen` handling, guarded invalid node info packets, and made traceroute/edge APIs more tolerant of decode failures.
|
||||
- Language support: added Russian translations.
|
||||
|
||||
### Version 3.0.5 — February 2026
|
||||
- **IMPORTANT:** the predicted coverage feature requires the extra `pyitm` dependency. If it is not installed, the coverage API will return 503.
|
||||
- Ubuntu install (inside the venv): `./env/bin/pip install pyitm`
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
"""Drop node_public_key table
|
||||
|
||||
Revision ID: e8f2c4b6d9a1
|
||||
Revises: c6b1d8f2a9e3
|
||||
Create Date: 2026-05-25 00:00:00.000000
|
||||
|
||||
"""
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
import sqlalchemy as sa
|
||||
|
||||
from alembic import op
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = "e8f2c4b6d9a1"
|
||||
down_revision: str | None = "c6b1d8f2a9e3"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
op.drop_index("idx_node_public_key_public_key", table_name="node_public_key")
|
||||
op.drop_index("idx_node_public_key_node_id", table_name="node_public_key")
|
||||
op.drop_table("node_public_key")
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
op.create_table(
|
||||
"node_public_key",
|
||||
sa.Column("id", sa.Integer(), primary_key=True, autoincrement=True),
|
||||
sa.Column("node_id", sa.BigInteger(), nullable=False),
|
||||
sa.Column("public_key", sa.String(), nullable=False),
|
||||
sa.Column("first_seen_us", sa.BigInteger(), nullable=True),
|
||||
sa.Column("last_seen_us", sa.BigInteger(), nullable=True),
|
||||
)
|
||||
op.create_index("idx_node_public_key_node_id", "node_public_key", ["node_id"], unique=False)
|
||||
op.create_index(
|
||||
"idx_node_public_key_public_key",
|
||||
"node_public_key",
|
||||
["public_key"],
|
||||
unique=False,
|
||||
)
|
||||
@@ -368,6 +368,49 @@ Response Example
|
||||
"timestamp": "2025-07-22T12:45:00+00:00",
|
||||
"version": "3.0.3",
|
||||
"git_revision": "abc1234",
|
||||
"cleanup": {
|
||||
"enabled": true,
|
||||
"days_to_keep": 14,
|
||||
"scheduled_time": "02:00",
|
||||
"vacuum": false,
|
||||
"status": "ok",
|
||||
"status_file": "dbcleanup.status.json",
|
||||
"last_run": {
|
||||
"status": "ok",
|
||||
"started_at": "2026-06-04T09:00:00+00:00",
|
||||
"completed_at": "2026-06-04T09:00:03+00:00",
|
||||
"cutoff_at": "2026-05-21T09:00:00+00:00",
|
||||
"days_to_keep": 14,
|
||||
"vacuum_requested": false,
|
||||
"vacuum_completed": false,
|
||||
"rows_deleted": {
|
||||
"packet": 1200,
|
||||
"packet_seen": 3400,
|
||||
"traceroute": 42,
|
||||
"node": 3
|
||||
},
|
||||
"error": null
|
||||
}
|
||||
},
|
||||
"backup": {
|
||||
"enabled": true,
|
||||
"backup_dir": "./backups",
|
||||
"scheduled_time": "02:00",
|
||||
"status": "ok",
|
||||
"status_file": "dbbackup.status.json",
|
||||
"last_run": {
|
||||
"status": "ok",
|
||||
"started_at": "2026-06-04T09:00:00+00:00",
|
||||
"completed_at": "2026-06-04T09:00:02+00:00",
|
||||
"backup_dir": "./backups",
|
||||
"database_path": "packets.db",
|
||||
"backup_file": "backups/packets_backup_20260604_090000.db.gz",
|
||||
"original_size_bytes": 12939444,
|
||||
"compressed_size_bytes": 4211560,
|
||||
"compression_percent": 67.5,
|
||||
"error": null
|
||||
}
|
||||
},
|
||||
"database": "connected",
|
||||
"database_size": "12.34 MB",
|
||||
"database_size_bytes": 12939444
|
||||
|
||||
@@ -1 +1 @@
|
||||
cb1f89372a70b0d4b4f8caf05aec28de8d4a13e0
|
||||
9ab4a1d08cb833d897aee2367013318718391f2f
|
||||
|
||||
File diff suppressed because one or more lines are too long
+300
-876
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/apponly.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -17,12 +17,12 @@ from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/apponly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\"\x81\x01\n\nChannelSet\x12\x36\n\x08settings\x18\x01 \x03(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12;\n\x0blora_config\x18\x02 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigBc\n\x14org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.apponly_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.apponly_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\rAppOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_CHANNELSET']._serialized_start=128
|
||||
_globals['_CHANNELSET']._serialized_end=257
|
||||
_CHANNELSET._serialized_start=128
|
||||
_CHANNELSET._serialized_end=257
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,52 +1,16 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from meshtastic.protobuf import channel_pb2 as _channel_pb2
|
||||
from meshtastic.protobuf import config_pb2 as _config_pb2
|
||||
from google.protobuf.internal import containers as _containers
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import collections.abc
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.containers
|
||||
import google.protobuf.message
|
||||
import meshtastic.protobuf.channel_pb2
|
||||
import meshtastic.protobuf.config_pb2
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class ChannelSet(google.protobuf.message.Message):
|
||||
"""
|
||||
This is the most compact possible representation for a set of channels.
|
||||
It includes only one PRIMARY channel (which must be first) and
|
||||
any SECONDARY channels.
|
||||
No DISABLED channels are included.
|
||||
This abstraction is used only on the the 'app side' of the world (ie python, javascript and android etc) to show a group of Channels as a (long) URL
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
SETTINGS_FIELD_NUMBER: builtins.int
|
||||
LORA_CONFIG_FIELD_NUMBER: builtins.int
|
||||
@property
|
||||
def settings(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.channel_pb2.ChannelSettings]:
|
||||
"""
|
||||
Channel list with settings
|
||||
"""
|
||||
|
||||
@property
|
||||
def lora_config(self) -> meshtastic.protobuf.config_pb2.Config.LoRaConfig:
|
||||
"""
|
||||
LoRa config
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
settings: collections.abc.Iterable[meshtastic.protobuf.channel_pb2.ChannelSettings] | None = ...,
|
||||
lora_config: meshtastic.protobuf.config_pb2.Config.LoRaConfig | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["lora_config", b"lora_config"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["lora_config", b"lora_config", "settings", b"settings"]) -> None: ...
|
||||
|
||||
global___ChannelSet = ChannelSet
|
||||
class ChannelSet(_message.Message):
|
||||
__slots__ = ["lora_config", "settings"]
|
||||
LORA_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
SETTINGS_FIELD_NUMBER: _ClassVar[int]
|
||||
lora_config: _config_pb2.Config.LoRaConfig
|
||||
settings: _containers.RepeatedCompositeFieldContainer[_channel_pb2.ChannelSettings]
|
||||
def __init__(self, settings: _Optional[_Iterable[_Union[_channel_pb2.ChannelSettings, _Mapping]]] = ..., lora_config: _Optional[_Union[_config_pb2.Config.LoRaConfig, _Mapping]] = ...) -> None: ...
|
||||
|
||||
File diff suppressed because one or more lines are too long
+721
-450
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/cannedmessages.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,12 +15,12 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n(meshtastic/protobuf/cannedmessages.proto\x12\x13meshtastic.protobuf\"-\n\x19\x43\x61nnedMessageModuleConfig\x12\x10\n\x08messages\x18\x01 \x01(\tBo\n\x14org.meshtastic.protoB\x19\x43\x61nnedMessageConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.cannedmessages_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.cannedmessages_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\031CannedMessageConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_CANNEDMESSAGEMODULECONFIG']._serialized_start=65
|
||||
_globals['_CANNEDMESSAGEMODULECONFIG']._serialized_end=110
|
||||
_CANNEDMESSAGEMODULECONFIG._serialized_start=65
|
||||
_CANNEDMESSAGEMODULECONFIG._serialized_end=110
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,33 +1,11 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class CannedMessageModuleConfig(google.protobuf.message.Message):
|
||||
"""
|
||||
Canned message module configuration.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
MESSAGES_FIELD_NUMBER: builtins.int
|
||||
messages: builtins.str
|
||||
"""
|
||||
Predefined messages for canned message module separated by '|' characters.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
messages: builtins.str = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["messages", b"messages"]) -> None: ...
|
||||
|
||||
global___CannedMessageModuleConfig = CannedMessageModuleConfig
|
||||
class CannedMessageModuleConfig(_message.Message):
|
||||
__slots__ = ["messages"]
|
||||
MESSAGES_FIELD_NUMBER: _ClassVar[int]
|
||||
messages: str
|
||||
def __init__(self, messages: _Optional[str] = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/channel.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,20 +15,20 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/channel.proto\x12\x13meshtastic.protobuf\"\xc1\x01\n\x0f\x43hannelSettings\x12\x17\n\x0b\x63hannel_num\x18\x01 \x01(\rB\x02\x18\x01\x12\x0b\n\x03psk\x18\x02 \x01(\x0c\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\n\n\x02id\x18\x04 \x01(\x07\x12\x16\n\x0euplink_enabled\x18\x05 \x01(\x08\x12\x18\n\x10\x64ownlink_enabled\x18\x06 \x01(\x08\x12<\n\x0fmodule_settings\x18\x07 \x01(\x0b\x32#.meshtastic.protobuf.ModuleSettings\">\n\x0eModuleSettings\x12\x1a\n\x12position_precision\x18\x01 \x01(\r\x12\x10\n\x08is_muted\x18\x02 \x01(\x08\"\xb3\x01\n\x07\x43hannel\x12\r\n\x05index\x18\x01 \x01(\x05\x12\x36\n\x08settings\x18\x02 \x01(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12/\n\x04role\x18\x03 \x01(\x0e\x32!.meshtastic.protobuf.Channel.Role\"0\n\x04Role\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07PRIMARY\x10\x01\x12\r\n\tSECONDARY\x10\x02\x42\x63\n\x14org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.channel_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.channel_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\rChannelProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_CHANNELSETTINGS.fields_by_name['channel_num']._options = None
|
||||
_CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001'
|
||||
_globals['_CHANNELSETTINGS']._serialized_start=59
|
||||
_globals['_CHANNELSETTINGS']._serialized_end=252
|
||||
_globals['_MODULESETTINGS']._serialized_start=254
|
||||
_globals['_MODULESETTINGS']._serialized_end=316
|
||||
_globals['_CHANNEL']._serialized_start=319
|
||||
_globals['_CHANNEL']._serialized_end=498
|
||||
_globals['_CHANNEL_ROLE']._serialized_start=450
|
||||
_globals['_CHANNEL_ROLE']._serialized_end=498
|
||||
_CHANNELSETTINGS._serialized_start=59
|
||||
_CHANNELSETTINGS._serialized_end=252
|
||||
_MODULESETTINGS._serialized_start=254
|
||||
_MODULESETTINGS._serialized_end=316
|
||||
_CHANNEL._serialized_start=319
|
||||
_CHANNEL._serialized_end=498
|
||||
_CHANNEL_ROLE._serialized_start=450
|
||||
_CHANNEL_ROLE._serialized_end=498
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,234 +1,47 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
class Channel(_message.Message):
|
||||
__slots__ = ["index", "role", "settings"]
|
||||
class Role(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
DISABLED: Channel.Role
|
||||
INDEX_FIELD_NUMBER: _ClassVar[int]
|
||||
PRIMARY: Channel.Role
|
||||
ROLE_FIELD_NUMBER: _ClassVar[int]
|
||||
SECONDARY: Channel.Role
|
||||
SETTINGS_FIELD_NUMBER: _ClassVar[int]
|
||||
index: int
|
||||
role: Channel.Role
|
||||
settings: ChannelSettings
|
||||
def __init__(self, index: _Optional[int] = ..., settings: _Optional[_Union[ChannelSettings, _Mapping]] = ..., role: _Optional[_Union[Channel.Role, str]] = ...) -> None: ...
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class ChannelSettings(_message.Message):
|
||||
__slots__ = ["channel_num", "downlink_enabled", "id", "module_settings", "name", "psk", "uplink_enabled"]
|
||||
CHANNEL_NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
DOWNLINK_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
ID_FIELD_NUMBER: _ClassVar[int]
|
||||
MODULE_SETTINGS_FIELD_NUMBER: _ClassVar[int]
|
||||
NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
PSK_FIELD_NUMBER: _ClassVar[int]
|
||||
UPLINK_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
channel_num: int
|
||||
downlink_enabled: bool
|
||||
id: int
|
||||
module_settings: ModuleSettings
|
||||
name: str
|
||||
psk: bytes
|
||||
uplink_enabled: bool
|
||||
def __init__(self, channel_num: _Optional[int] = ..., psk: _Optional[bytes] = ..., name: _Optional[str] = ..., id: _Optional[int] = ..., uplink_enabled: bool = ..., downlink_enabled: bool = ..., module_settings: _Optional[_Union[ModuleSettings, _Mapping]] = ...) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class ChannelSettings(google.protobuf.message.Message):
|
||||
"""
|
||||
This information can be encoded as a QRcode/url so that other users can configure
|
||||
their radio to join the same channel.
|
||||
A note about how channel names are shown to users: channelname-X
|
||||
poundsymbol is a prefix used to indicate this is a channel name (idea from @professr).
|
||||
Where X is a letter from A-Z (base 26) representing a hash of the PSK for this
|
||||
channel - so that if the user changes anything about the channel (which does
|
||||
force a new PSK) this letter will also change. Thus preventing user confusion if
|
||||
two friends try to type in a channel name of "BobsChan" and then can't talk
|
||||
because their PSKs will be different.
|
||||
The PSK is hashed into this letter by "0x41 + [xor all bytes of the psk ] modulo 26"
|
||||
This also allows the option of someday if people have the PSK off (zero), the
|
||||
users COULD type in a channel name and be able to talk.
|
||||
FIXME: Add description of multi-channel support and how primary vs secondary channels are used.
|
||||
FIXME: explain how apps use channels for security.
|
||||
explain how remote settings and remote gpio are managed as an example
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
CHANNEL_NUM_FIELD_NUMBER: builtins.int
|
||||
PSK_FIELD_NUMBER: builtins.int
|
||||
NAME_FIELD_NUMBER: builtins.int
|
||||
ID_FIELD_NUMBER: builtins.int
|
||||
UPLINK_ENABLED_FIELD_NUMBER: builtins.int
|
||||
DOWNLINK_ENABLED_FIELD_NUMBER: builtins.int
|
||||
MODULE_SETTINGS_FIELD_NUMBER: builtins.int
|
||||
channel_num: builtins.int
|
||||
"""
|
||||
Deprecated in favor of LoraConfig.channel_num
|
||||
"""
|
||||
psk: builtins.bytes
|
||||
"""
|
||||
A simple pre-shared key for now for crypto.
|
||||
Must be either 0 bytes (no crypto), 16 bytes (AES128), or 32 bytes (AES256).
|
||||
A special shorthand is used for 1 byte long psks.
|
||||
These psks should be treated as only minimally secure,
|
||||
because they are listed in this source code.
|
||||
Those bytes are mapped using the following scheme:
|
||||
`0` = No crypto
|
||||
`1` = The special "default" channel key: {0xd4, 0xf1, 0xbb, 0x3a, 0x20, 0x29, 0x07, 0x59, 0xf0, 0xbc, 0xff, 0xab, 0xcf, 0x4e, 0x69, 0x01}
|
||||
`2` through 10 = The default channel key, except with 1 through 9 added to the last byte.
|
||||
Shown to user as simple1 through 10
|
||||
"""
|
||||
name: builtins.str
|
||||
"""
|
||||
A SHORT name that will be packed into the URL.
|
||||
Less than 12 bytes.
|
||||
Something for end users to call the channel
|
||||
If this is the empty string it is assumed that this channel
|
||||
is the special (minimally secure) "Default"channel.
|
||||
In user interfaces it should be rendered as a local language translation of "X".
|
||||
For channel_num hashing empty string will be treated as "X".
|
||||
Where "X" is selected based on the English words listed above for ModemPreset
|
||||
"""
|
||||
id: builtins.int
|
||||
"""
|
||||
Used to construct a globally unique channel ID.
|
||||
The full globally unique ID will be: "name.id" where ID is shown as base36.
|
||||
Assuming that the number of meshtastic users is below 20K (true for a long time)
|
||||
the chance of this 64 bit random number colliding with anyone else is super low.
|
||||
And the penalty for collision is low as well, it just means that anyone trying to decrypt channel messages might need to
|
||||
try multiple candidate channels.
|
||||
Any time a non wire compatible change is made to a channel, this field should be regenerated.
|
||||
There are a small number of 'special' globally known (and fairly) insecure standard channels.
|
||||
Those channels do not have a numeric id included in the settings, but instead it is pulled from
|
||||
a table of well known IDs.
|
||||
(see Well Known Channels FIXME)
|
||||
"""
|
||||
uplink_enabled: builtins.bool
|
||||
"""
|
||||
If true, messages on the mesh will be sent to the *public* internet by any gateway ndoe
|
||||
"""
|
||||
downlink_enabled: builtins.bool
|
||||
"""
|
||||
If true, messages seen on the internet will be forwarded to the local mesh.
|
||||
"""
|
||||
@property
|
||||
def module_settings(self) -> global___ModuleSettings:
|
||||
"""
|
||||
Per-channel module settings.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
channel_num: builtins.int = ...,
|
||||
psk: builtins.bytes = ...,
|
||||
name: builtins.str = ...,
|
||||
id: builtins.int = ...,
|
||||
uplink_enabled: builtins.bool = ...,
|
||||
downlink_enabled: builtins.bool = ...,
|
||||
module_settings: global___ModuleSettings | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["module_settings", b"module_settings"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["channel_num", b"channel_num", "downlink_enabled", b"downlink_enabled", "id", b"id", "module_settings", b"module_settings", "name", b"name", "psk", b"psk", "uplink_enabled", b"uplink_enabled"]) -> None: ...
|
||||
|
||||
global___ChannelSettings = ChannelSettings
|
||||
|
||||
@typing.final
|
||||
class ModuleSettings(google.protobuf.message.Message):
|
||||
"""
|
||||
This message is specifically for modules to store per-channel configuration data.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
POSITION_PRECISION_FIELD_NUMBER: builtins.int
|
||||
IS_MUTED_FIELD_NUMBER: builtins.int
|
||||
position_precision: builtins.int
|
||||
"""
|
||||
Bits of precision for the location sent in position packets.
|
||||
"""
|
||||
is_muted: builtins.bool
|
||||
"""
|
||||
Controls whether or not the client / device should mute the current channel
|
||||
Useful for noisy public channels you don't necessarily want to disable
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
position_precision: builtins.int = ...,
|
||||
is_muted: builtins.bool = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["is_muted", b"is_muted", "position_precision", b"position_precision"]) -> None: ...
|
||||
|
||||
global___ModuleSettings = ModuleSettings
|
||||
|
||||
@typing.final
|
||||
class Channel(google.protobuf.message.Message):
|
||||
"""
|
||||
A pair of a channel number, mode and the (sharable) settings for that channel
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _Role:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _RoleEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[Channel._Role.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
DISABLED: Channel._Role.ValueType # 0
|
||||
"""
|
||||
This channel is not in use right now
|
||||
"""
|
||||
PRIMARY: Channel._Role.ValueType # 1
|
||||
"""
|
||||
This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY
|
||||
"""
|
||||
SECONDARY: Channel._Role.ValueType # 2
|
||||
"""
|
||||
Secondary channels are only used for encryption/decryption/authentication purposes.
|
||||
Their radio settings (freq etc) are ignored, only psk is used.
|
||||
"""
|
||||
|
||||
class Role(_Role, metaclass=_RoleEnumTypeWrapper):
|
||||
"""
|
||||
How this channel is being used (or not).
|
||||
Note: this field is an enum to give us options for the future.
|
||||
In particular, someday we might make a 'SCANNING' option.
|
||||
SCANNING channels could have different frequencies and the radio would
|
||||
occasionally check that freq to see if anything is being transmitted.
|
||||
For devices that have multiple physical radios attached, we could keep multiple PRIMARY/SCANNING channels active at once to allow
|
||||
cross band routing as needed.
|
||||
If a device has only a single radio (the common case) only one channel can be PRIMARY at a time
|
||||
(but any number of SECONDARY channels can't be sent received on that common frequency)
|
||||
"""
|
||||
|
||||
DISABLED: Channel.Role.ValueType # 0
|
||||
"""
|
||||
This channel is not in use right now
|
||||
"""
|
||||
PRIMARY: Channel.Role.ValueType # 1
|
||||
"""
|
||||
This channel is used to set the frequency for the radio - all other enabled channels must be SECONDARY
|
||||
"""
|
||||
SECONDARY: Channel.Role.ValueType # 2
|
||||
"""
|
||||
Secondary channels are only used for encryption/decryption/authentication purposes.
|
||||
Their radio settings (freq etc) are ignored, only psk is used.
|
||||
"""
|
||||
|
||||
INDEX_FIELD_NUMBER: builtins.int
|
||||
SETTINGS_FIELD_NUMBER: builtins.int
|
||||
ROLE_FIELD_NUMBER: builtins.int
|
||||
index: builtins.int
|
||||
"""
|
||||
The index of this channel in the channel table (from 0 to MAX_NUM_CHANNELS-1)
|
||||
(Someday - not currently implemented) An index of -1 could be used to mean "set by name",
|
||||
in which case the target node will find and set the channel by settings.name.
|
||||
"""
|
||||
role: global___Channel.Role.ValueType
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
@property
|
||||
def settings(self) -> global___ChannelSettings:
|
||||
"""
|
||||
The new settings, or NULL to disable that channel
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
index: builtins.int = ...,
|
||||
settings: global___ChannelSettings | None = ...,
|
||||
role: global___Channel.Role.ValueType = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["settings", b"settings"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["index", b"index", "role", b"role", "settings", b"settings"]) -> None: ...
|
||||
|
||||
global___Channel = Channel
|
||||
class ModuleSettings(_message.Message):
|
||||
__slots__ = ["is_muted", "position_precision"]
|
||||
IS_MUTED_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_PRECISION_FIELD_NUMBER: _ClassVar[int]
|
||||
is_muted: bool
|
||||
position_precision: int
|
||||
def __init__(self, position_precision: _Optional[int] = ..., is_muted: bool = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/clientonly.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -17,12 +17,12 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"\xc4\x03\n\rDeviceProfile\x12\x16\n\tlong_name\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x17\n\nshort_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x18\n\x0b\x63hannel_url\x18\x03 \x01(\tH\x02\x88\x01\x01\x12\x35\n\x06\x63onfig\x18\x04 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfigH\x03\x88\x01\x01\x12\x42\n\rmodule_config\x18\x05 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfigH\x04\x88\x01\x01\x12:\n\x0e\x66ixed_position\x18\x06 \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x05\x88\x01\x01\x12\x15\n\x08ringtone\x18\x07 \x01(\tH\x06\x88\x01\x01\x12\x1c\n\x0f\x63\x61nned_messages\x18\x08 \x01(\tH\x07\x88\x01\x01\x42\x0c\n\n_long_nameB\r\n\x0b_short_nameB\x0e\n\x0c_channel_urlB\t\n\x07_configB\x10\n\x0e_module_configB\x11\n\x0f_fixed_positionB\x0b\n\t_ringtoneB\x12\n\x10_canned_messagesBf\n\x14org.meshtastic.protoB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.clientonly_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.clientonly_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020ClientOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_DEVICEPROFILE']._serialized_start=131
|
||||
_globals['_DEVICEPROFILE']._serialized_end=583
|
||||
_DEVICEPROFILE._serialized_start=131
|
||||
_DEVICEPROFILE._serialized_end=583
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,101 +1,27 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from meshtastic.protobuf import localonly_pb2 as _localonly_pb2
|
||||
from meshtastic.protobuf import mesh_pb2 as _mesh_pb2
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import meshtastic.protobuf.localonly_pb2
|
||||
import meshtastic.protobuf.mesh_pb2
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class DeviceProfile(google.protobuf.message.Message):
|
||||
"""
|
||||
This abstraction is used to contain any configuration for provisioning a node on any client.
|
||||
It is useful for importing and exporting configurations.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
LONG_NAME_FIELD_NUMBER: builtins.int
|
||||
SHORT_NAME_FIELD_NUMBER: builtins.int
|
||||
CHANNEL_URL_FIELD_NUMBER: builtins.int
|
||||
CONFIG_FIELD_NUMBER: builtins.int
|
||||
MODULE_CONFIG_FIELD_NUMBER: builtins.int
|
||||
FIXED_POSITION_FIELD_NUMBER: builtins.int
|
||||
RINGTONE_FIELD_NUMBER: builtins.int
|
||||
CANNED_MESSAGES_FIELD_NUMBER: builtins.int
|
||||
long_name: builtins.str
|
||||
"""
|
||||
Long name for the node
|
||||
"""
|
||||
short_name: builtins.str
|
||||
"""
|
||||
Short name of the node
|
||||
"""
|
||||
channel_url: builtins.str
|
||||
"""
|
||||
The url of the channels from our node
|
||||
"""
|
||||
ringtone: builtins.str
|
||||
"""
|
||||
Ringtone for ExternalNotification
|
||||
"""
|
||||
canned_messages: builtins.str
|
||||
"""
|
||||
Predefined messages for CannedMessage
|
||||
"""
|
||||
@property
|
||||
def config(self) -> meshtastic.protobuf.localonly_pb2.LocalConfig:
|
||||
"""
|
||||
The Config of the node
|
||||
"""
|
||||
|
||||
@property
|
||||
def module_config(self) -> meshtastic.protobuf.localonly_pb2.LocalModuleConfig:
|
||||
"""
|
||||
The ModuleConfig of the node
|
||||
"""
|
||||
|
||||
@property
|
||||
def fixed_position(self) -> meshtastic.protobuf.mesh_pb2.Position:
|
||||
"""
|
||||
Fixed position data
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
long_name: builtins.str | None = ...,
|
||||
short_name: builtins.str | None = ...,
|
||||
channel_url: builtins.str | None = ...,
|
||||
config: meshtastic.protobuf.localonly_pb2.LocalConfig | None = ...,
|
||||
module_config: meshtastic.protobuf.localonly_pb2.LocalModuleConfig | None = ...,
|
||||
fixed_position: meshtastic.protobuf.mesh_pb2.Position | None = ...,
|
||||
ringtone: builtins.str | None = ...,
|
||||
canned_messages: builtins.str | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["_canned_messages", b"_canned_messages", "_channel_url", b"_channel_url", "_config", b"_config", "_fixed_position", b"_fixed_position", "_long_name", b"_long_name", "_module_config", b"_module_config", "_ringtone", b"_ringtone", "_short_name", b"_short_name", "canned_messages", b"canned_messages", "channel_url", b"channel_url", "config", b"config", "fixed_position", b"fixed_position", "long_name", b"long_name", "module_config", b"module_config", "ringtone", b"ringtone", "short_name", b"short_name"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["_canned_messages", b"_canned_messages", "_channel_url", b"_channel_url", "_config", b"_config", "_fixed_position", b"_fixed_position", "_long_name", b"_long_name", "_module_config", b"_module_config", "_ringtone", b"_ringtone", "_short_name", b"_short_name", "canned_messages", b"canned_messages", "channel_url", b"channel_url", "config", b"config", "fixed_position", b"fixed_position", "long_name", b"long_name", "module_config", b"module_config", "ringtone", b"ringtone", "short_name", b"short_name"]) -> None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_canned_messages", b"_canned_messages"]) -> typing.Literal["canned_messages"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_channel_url", b"_channel_url"]) -> typing.Literal["channel_url"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_config", b"_config"]) -> typing.Literal["config"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_fixed_position", b"_fixed_position"]) -> typing.Literal["fixed_position"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_long_name", b"_long_name"]) -> typing.Literal["long_name"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_module_config", b"_module_config"]) -> typing.Literal["module_config"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_ringtone", b"_ringtone"]) -> typing.Literal["ringtone"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_short_name", b"_short_name"]) -> typing.Literal["short_name"] | None: ...
|
||||
|
||||
global___DeviceProfile = DeviceProfile
|
||||
class DeviceProfile(_message.Message):
|
||||
__slots__ = ["canned_messages", "channel_url", "config", "fixed_position", "long_name", "module_config", "ringtone", "short_name"]
|
||||
CANNED_MESSAGES_FIELD_NUMBER: _ClassVar[int]
|
||||
CHANNEL_URL_FIELD_NUMBER: _ClassVar[int]
|
||||
CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
FIXED_POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
MODULE_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
RINGTONE_FIELD_NUMBER: _ClassVar[int]
|
||||
SHORT_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
canned_messages: str
|
||||
channel_url: str
|
||||
config: _localonly_pb2.LocalConfig
|
||||
fixed_position: _mesh_pb2.Position
|
||||
long_name: str
|
||||
module_config: _localonly_pb2.LocalModuleConfig
|
||||
ringtone: str
|
||||
short_name: str
|
||||
def __init__(self, long_name: _Optional[str] = ..., short_name: _Optional[str] = ..., channel_url: _Optional[str] = ..., config: _Optional[_Union[_localonly_pb2.LocalConfig, _Mapping]] = ..., module_config: _Optional[_Union[_localonly_pb2.LocalModuleConfig, _Mapping]] = ..., fixed_position: _Optional[_Union[_mesh_pb2.Position, _Mapping]] = ..., ringtone: _Optional[str] = ..., canned_messages: _Optional[str] = ...) -> None: ...
|
||||
|
||||
File diff suppressed because one or more lines are too long
+395
-1895
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/connection_status.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,22 +15,22 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+meshtastic/protobuf/connection_status.proto\x12\x13meshtastic.protobuf\"\xd5\x02\n\x16\x44\x65viceConnectionStatus\x12<\n\x04wifi\x18\x01 \x01(\x0b\x32).meshtastic.protobuf.WifiConnectionStatusH\x00\x88\x01\x01\x12\x44\n\x08\x65thernet\x18\x02 \x01(\x0b\x32-.meshtastic.protobuf.EthernetConnectionStatusH\x01\x88\x01\x01\x12\x46\n\tbluetooth\x18\x03 \x01(\x0b\x32..meshtastic.protobuf.BluetoothConnectionStatusH\x02\x88\x01\x01\x12@\n\x06serial\x18\x04 \x01(\x0b\x32+.meshtastic.protobuf.SerialConnectionStatusH\x03\x88\x01\x01\x42\x07\n\x05_wifiB\x0b\n\t_ethernetB\x0c\n\n_bluetoothB\t\n\x07_serial\"p\n\x14WifiConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\x12\x0c\n\x04ssid\x18\x02 \x01(\t\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\"X\n\x18\x45thernetConnectionStatus\x12<\n\x06status\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.NetworkConnectionStatus\"{\n\x17NetworkConnectionStatus\x12\x12\n\nip_address\x18\x01 \x01(\x07\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x12\x19\n\x11is_mqtt_connected\x18\x03 \x01(\x08\x12\x1b\n\x13is_syslog_connected\x18\x04 \x01(\x08\"L\n\x19\x42luetoothConnectionStatus\x12\x0b\n\x03pin\x18\x01 \x01(\r\x12\x0c\n\x04rssi\x18\x02 \x01(\x05\x12\x14\n\x0cis_connected\x18\x03 \x01(\x08\"<\n\x16SerialConnectionStatus\x12\x0c\n\x04\x62\x61ud\x18\x01 \x01(\r\x12\x14\n\x0cis_connected\x18\x02 \x01(\x08\x42\x66\n\x14org.meshtastic.protoB\x10\x43onnStatusProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.connection_status_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.connection_status_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020ConnStatusProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_DEVICECONNECTIONSTATUS']._serialized_start=69
|
||||
_globals['_DEVICECONNECTIONSTATUS']._serialized_end=410
|
||||
_globals['_WIFICONNECTIONSTATUS']._serialized_start=412
|
||||
_globals['_WIFICONNECTIONSTATUS']._serialized_end=524
|
||||
_globals['_ETHERNETCONNECTIONSTATUS']._serialized_start=526
|
||||
_globals['_ETHERNETCONNECTIONSTATUS']._serialized_end=614
|
||||
_globals['_NETWORKCONNECTIONSTATUS']._serialized_start=616
|
||||
_globals['_NETWORKCONNECTIONSTATUS']._serialized_end=739
|
||||
_globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_start=741
|
||||
_globals['_BLUETOOTHCONNECTIONSTATUS']._serialized_end=817
|
||||
_globals['_SERIALCONNECTIONSTATUS']._serialized_start=819
|
||||
_globals['_SERIALCONNECTIONSTATUS']._serialized_end=879
|
||||
_DEVICECONNECTIONSTATUS._serialized_start=69
|
||||
_DEVICECONNECTIONSTATUS._serialized_end=410
|
||||
_WIFICONNECTIONSTATUS._serialized_start=412
|
||||
_WIFICONNECTIONSTATUS._serialized_end=524
|
||||
_ETHERNETCONNECTIONSTATUS._serialized_start=526
|
||||
_ETHERNETCONNECTIONSTATUS._serialized_end=614
|
||||
_NETWORKCONNECTIONSTATUS._serialized_start=616
|
||||
_NETWORKCONNECTIONSTATUS._serialized_end=739
|
||||
_BLUETOOTHCONNECTIONSTATUS._serialized_start=741
|
||||
_BLUETOOTHCONNECTIONSTATUS._serialized_end=817
|
||||
_SERIALCONNECTIONSTATUS._serialized_start=819
|
||||
_SERIALCONNECTIONSTATUS._serialized_end=879
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,228 +1,63 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class BluetoothConnectionStatus(_message.Message):
|
||||
__slots__ = ["is_connected", "pin", "rssi"]
|
||||
IS_CONNECTED_FIELD_NUMBER: _ClassVar[int]
|
||||
PIN_FIELD_NUMBER: _ClassVar[int]
|
||||
RSSI_FIELD_NUMBER: _ClassVar[int]
|
||||
is_connected: bool
|
||||
pin: int
|
||||
rssi: int
|
||||
def __init__(self, pin: _Optional[int] = ..., rssi: _Optional[int] = ..., is_connected: bool = ...) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class DeviceConnectionStatus(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
class DeviceConnectionStatus(_message.Message):
|
||||
__slots__ = ["bluetooth", "ethernet", "serial", "wifi"]
|
||||
BLUETOOTH_FIELD_NUMBER: _ClassVar[int]
|
||||
ETHERNET_FIELD_NUMBER: _ClassVar[int]
|
||||
SERIAL_FIELD_NUMBER: _ClassVar[int]
|
||||
WIFI_FIELD_NUMBER: _ClassVar[int]
|
||||
bluetooth: BluetoothConnectionStatus
|
||||
ethernet: EthernetConnectionStatus
|
||||
serial: SerialConnectionStatus
|
||||
wifi: WifiConnectionStatus
|
||||
def __init__(self, wifi: _Optional[_Union[WifiConnectionStatus, _Mapping]] = ..., ethernet: _Optional[_Union[EthernetConnectionStatus, _Mapping]] = ..., bluetooth: _Optional[_Union[BluetoothConnectionStatus, _Mapping]] = ..., serial: _Optional[_Union[SerialConnectionStatus, _Mapping]] = ...) -> None: ...
|
||||
|
||||
WIFI_FIELD_NUMBER: builtins.int
|
||||
ETHERNET_FIELD_NUMBER: builtins.int
|
||||
BLUETOOTH_FIELD_NUMBER: builtins.int
|
||||
SERIAL_FIELD_NUMBER: builtins.int
|
||||
@property
|
||||
def wifi(self) -> global___WifiConnectionStatus:
|
||||
"""
|
||||
WiFi Status
|
||||
"""
|
||||
class EthernetConnectionStatus(_message.Message):
|
||||
__slots__ = ["status"]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
status: NetworkConnectionStatus
|
||||
def __init__(self, status: _Optional[_Union[NetworkConnectionStatus, _Mapping]] = ...) -> None: ...
|
||||
|
||||
@property
|
||||
def ethernet(self) -> global___EthernetConnectionStatus:
|
||||
"""
|
||||
WiFi Status
|
||||
"""
|
||||
class NetworkConnectionStatus(_message.Message):
|
||||
__slots__ = ["ip_address", "is_connected", "is_mqtt_connected", "is_syslog_connected"]
|
||||
IP_ADDRESS_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_CONNECTED_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_MQTT_CONNECTED_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_SYSLOG_CONNECTED_FIELD_NUMBER: _ClassVar[int]
|
||||
ip_address: int
|
||||
is_connected: bool
|
||||
is_mqtt_connected: bool
|
||||
is_syslog_connected: bool
|
||||
def __init__(self, ip_address: _Optional[int] = ..., is_connected: bool = ..., is_mqtt_connected: bool = ..., is_syslog_connected: bool = ...) -> None: ...
|
||||
|
||||
@property
|
||||
def bluetooth(self) -> global___BluetoothConnectionStatus:
|
||||
"""
|
||||
Bluetooth Status
|
||||
"""
|
||||
class SerialConnectionStatus(_message.Message):
|
||||
__slots__ = ["baud", "is_connected"]
|
||||
BAUD_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_CONNECTED_FIELD_NUMBER: _ClassVar[int]
|
||||
baud: int
|
||||
is_connected: bool
|
||||
def __init__(self, baud: _Optional[int] = ..., is_connected: bool = ...) -> None: ...
|
||||
|
||||
@property
|
||||
def serial(self) -> global___SerialConnectionStatus:
|
||||
"""
|
||||
Serial Status
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
wifi: global___WifiConnectionStatus | None = ...,
|
||||
ethernet: global___EthernetConnectionStatus | None = ...,
|
||||
bluetooth: global___BluetoothConnectionStatus | None = ...,
|
||||
serial: global___SerialConnectionStatus | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["_bluetooth", b"_bluetooth", "_ethernet", b"_ethernet", "_serial", b"_serial", "_wifi", b"_wifi", "bluetooth", b"bluetooth", "ethernet", b"ethernet", "serial", b"serial", "wifi", b"wifi"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["_bluetooth", b"_bluetooth", "_ethernet", b"_ethernet", "_serial", b"_serial", "_wifi", b"_wifi", "bluetooth", b"bluetooth", "ethernet", b"ethernet", "serial", b"serial", "wifi", b"wifi"]) -> None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_bluetooth", b"_bluetooth"]) -> typing.Literal["bluetooth"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_ethernet", b"_ethernet"]) -> typing.Literal["ethernet"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_serial", b"_serial"]) -> typing.Literal["serial"] | None: ...
|
||||
@typing.overload
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_wifi", b"_wifi"]) -> typing.Literal["wifi"] | None: ...
|
||||
|
||||
global___DeviceConnectionStatus = DeviceConnectionStatus
|
||||
|
||||
@typing.final
|
||||
class WifiConnectionStatus(google.protobuf.message.Message):
|
||||
"""
|
||||
WiFi connection status
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
STATUS_FIELD_NUMBER: builtins.int
|
||||
SSID_FIELD_NUMBER: builtins.int
|
||||
RSSI_FIELD_NUMBER: builtins.int
|
||||
ssid: builtins.str
|
||||
"""
|
||||
WiFi access point SSID
|
||||
"""
|
||||
rssi: builtins.int
|
||||
"""
|
||||
RSSI of wireless connection
|
||||
"""
|
||||
@property
|
||||
def status(self) -> global___NetworkConnectionStatus:
|
||||
"""
|
||||
Connection status
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
status: global___NetworkConnectionStatus | None = ...,
|
||||
ssid: builtins.str = ...,
|
||||
rssi: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["status", b"status"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["rssi", b"rssi", "ssid", b"ssid", "status", b"status"]) -> None: ...
|
||||
|
||||
global___WifiConnectionStatus = WifiConnectionStatus
|
||||
|
||||
@typing.final
|
||||
class EthernetConnectionStatus(google.protobuf.message.Message):
|
||||
"""
|
||||
Ethernet connection status
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
STATUS_FIELD_NUMBER: builtins.int
|
||||
@property
|
||||
def status(self) -> global___NetworkConnectionStatus:
|
||||
"""
|
||||
Connection status
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
status: global___NetworkConnectionStatus | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["status", b"status"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["status", b"status"]) -> None: ...
|
||||
|
||||
global___EthernetConnectionStatus = EthernetConnectionStatus
|
||||
|
||||
@typing.final
|
||||
class NetworkConnectionStatus(google.protobuf.message.Message):
|
||||
"""
|
||||
Ethernet or WiFi connection status
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
IP_ADDRESS_FIELD_NUMBER: builtins.int
|
||||
IS_CONNECTED_FIELD_NUMBER: builtins.int
|
||||
IS_MQTT_CONNECTED_FIELD_NUMBER: builtins.int
|
||||
IS_SYSLOG_CONNECTED_FIELD_NUMBER: builtins.int
|
||||
ip_address: builtins.int
|
||||
"""
|
||||
IP address of device
|
||||
"""
|
||||
is_connected: builtins.bool
|
||||
"""
|
||||
Whether the device has an active connection or not
|
||||
"""
|
||||
is_mqtt_connected: builtins.bool
|
||||
"""
|
||||
Whether the device has an active connection to an MQTT broker or not
|
||||
"""
|
||||
is_syslog_connected: builtins.bool
|
||||
"""
|
||||
Whether the device is actively remote syslogging or not
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
ip_address: builtins.int = ...,
|
||||
is_connected: builtins.bool = ...,
|
||||
is_mqtt_connected: builtins.bool = ...,
|
||||
is_syslog_connected: builtins.bool = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["ip_address", b"ip_address", "is_connected", b"is_connected", "is_mqtt_connected", b"is_mqtt_connected", "is_syslog_connected", b"is_syslog_connected"]) -> None: ...
|
||||
|
||||
global___NetworkConnectionStatus = NetworkConnectionStatus
|
||||
|
||||
@typing.final
|
||||
class BluetoothConnectionStatus(google.protobuf.message.Message):
|
||||
"""
|
||||
Bluetooth connection status
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
PIN_FIELD_NUMBER: builtins.int
|
||||
RSSI_FIELD_NUMBER: builtins.int
|
||||
IS_CONNECTED_FIELD_NUMBER: builtins.int
|
||||
pin: builtins.int
|
||||
"""
|
||||
The pairing PIN for bluetooth
|
||||
"""
|
||||
rssi: builtins.int
|
||||
"""
|
||||
RSSI of bluetooth connection
|
||||
"""
|
||||
is_connected: builtins.bool
|
||||
"""
|
||||
Whether the device has an active connection or not
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
pin: builtins.int = ...,
|
||||
rssi: builtins.int = ...,
|
||||
is_connected: builtins.bool = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["is_connected", b"is_connected", "pin", b"pin", "rssi", b"rssi"]) -> None: ...
|
||||
|
||||
global___BluetoothConnectionStatus = BluetoothConnectionStatus
|
||||
|
||||
@typing.final
|
||||
class SerialConnectionStatus(google.protobuf.message.Message):
|
||||
"""
|
||||
Serial connection status
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
BAUD_FIELD_NUMBER: builtins.int
|
||||
IS_CONNECTED_FIELD_NUMBER: builtins.int
|
||||
baud: builtins.int
|
||||
"""
|
||||
Serial baud rate
|
||||
"""
|
||||
is_connected: builtins.bool
|
||||
"""
|
||||
Whether the device has an active connection or not
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
baud: builtins.int = ...,
|
||||
is_connected: builtins.bool = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["baud", b"baud", "is_connected", b"is_connected"]) -> None: ...
|
||||
|
||||
global___SerialConnectionStatus = SerialConnectionStatus
|
||||
class WifiConnectionStatus(_message.Message):
|
||||
__slots__ = ["rssi", "ssid", "status"]
|
||||
RSSI_FIELD_NUMBER: _ClassVar[int]
|
||||
SSID_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
rssi: int
|
||||
ssid: str
|
||||
status: NetworkConnectionStatus
|
||||
def __init__(self, status: _Optional[_Union[NetworkConnectionStatus, _Mapping]] = ..., ssid: _Optional[str] = ..., rssi: _Optional[int] = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/device_ui.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,28 +15,28 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/device_ui.proto\x12\x13meshtastic.protobuf\"\xff\x05\n\x0e\x44\x65viceUIConfig\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x19\n\x11screen_brightness\x18\x02 \x01(\r\x12\x16\n\x0escreen_timeout\x18\x03 \x01(\r\x12\x13\n\x0bscreen_lock\x18\x04 \x01(\x08\x12\x15\n\rsettings_lock\x18\x05 \x01(\x08\x12\x10\n\x08pin_code\x18\x06 \x01(\r\x12)\n\x05theme\x18\x07 \x01(\x0e\x32\x1a.meshtastic.protobuf.Theme\x12\x15\n\ralert_enabled\x18\x08 \x01(\x08\x12\x16\n\x0e\x62\x61nner_enabled\x18\t \x01(\x08\x12\x14\n\x0cring_tone_id\x18\n \x01(\r\x12/\n\x08language\x18\x0b \x01(\x0e\x32\x1d.meshtastic.protobuf.Language\x12\x34\n\x0bnode_filter\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.NodeFilter\x12:\n\x0enode_highlight\x18\r \x01(\x0b\x32\".meshtastic.protobuf.NodeHighlight\x12\x18\n\x10\x63\x61libration_data\x18\x0e \x01(\x0c\x12*\n\x08map_data\x18\x0f \x01(\x0b\x32\x18.meshtastic.protobuf.Map\x12\x36\n\x0c\x63ompass_mode\x18\x10 \x01(\x0e\x32 .meshtastic.protobuf.CompassMode\x12\x18\n\x10screen_rgb_color\x18\x11 \x01(\r\x12\x1b\n\x13is_clockface_analog\x18\x12 \x01(\x08\x12K\n\ngps_format\x18\x13 \x01(\x0e\x32\x37.meshtastic.protobuf.DeviceUIConfig.GpsCoordinateFormat\"V\n\x13GpsCoordinateFormat\x12\x07\n\x03\x44\x45\x43\x10\x00\x12\x07\n\x03\x44MS\x10\x01\x12\x07\n\x03UTM\x10\x02\x12\x08\n\x04MGRS\x10\x03\x12\x07\n\x03OLC\x10\x04\x12\x08\n\x04OSGR\x10\x05\x12\x07\n\x03MLS\x10\x06\"\xa7\x01\n\nNodeFilter\x12\x16\n\x0eunknown_switch\x18\x01 \x01(\x08\x12\x16\n\x0eoffline_switch\x18\x02 \x01(\x08\x12\x19\n\x11public_key_switch\x18\x03 \x01(\x08\x12\x11\n\thops_away\x18\x04 \x01(\x05\x12\x17\n\x0fposition_switch\x18\x05 \x01(\x08\x12\x11\n\tnode_name\x18\x06 \x01(\t\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\x05\"~\n\rNodeHighlight\x12\x13\n\x0b\x63hat_switch\x18\x01 \x01(\x08\x12\x17\n\x0fposition_switch\x18\x02 \x01(\x08\x12\x18\n\x10telemetry_switch\x18\x03 \x01(\x08\x12\x12\n\niaq_switch\x18\x04 \x01(\x08\x12\x11\n\tnode_name\x18\x05 \x01(\t\"=\n\x08GeoPoint\x12\x0c\n\x04zoom\x18\x01 \x01(\x05\x12\x10\n\x08latitude\x18\x02 \x01(\x05\x12\x11\n\tlongitude\x18\x03 \x01(\x05\"U\n\x03Map\x12+\n\x04home\x18\x01 \x01(\x0b\x32\x1d.meshtastic.protobuf.GeoPoint\x12\r\n\x05style\x18\x02 \x01(\t\x12\x12\n\nfollow_gps\x18\x03 \x01(\x08*>\n\x0b\x43ompassMode\x12\x0b\n\x07\x44YNAMIC\x10\x00\x12\x0e\n\nFIXED_RING\x10\x01\x12\x12\n\x0e\x46REEZE_HEADING\x10\x02*%\n\x05Theme\x12\x08\n\x04\x44\x41RK\x10\x00\x12\t\n\x05LIGHT\x10\x01\x12\x07\n\x03RED\x10\x02*\xc0\x02\n\x08Language\x12\x0b\n\x07\x45NGLISH\x10\x00\x12\n\n\x06\x46RENCH\x10\x01\x12\n\n\x06GERMAN\x10\x02\x12\x0b\n\x07ITALIAN\x10\x03\x12\x0e\n\nPORTUGUESE\x10\x04\x12\x0b\n\x07SPANISH\x10\x05\x12\x0b\n\x07SWEDISH\x10\x06\x12\x0b\n\x07\x46INNISH\x10\x07\x12\n\n\x06POLISH\x10\x08\x12\x0b\n\x07TURKISH\x10\t\x12\x0b\n\x07SERBIAN\x10\n\x12\x0b\n\x07RUSSIAN\x10\x0b\x12\t\n\x05\x44UTCH\x10\x0c\x12\t\n\x05GREEK\x10\r\x12\r\n\tNORWEGIAN\x10\x0e\x12\r\n\tSLOVENIAN\x10\x0f\x12\r\n\tUKRAINIAN\x10\x10\x12\r\n\tBULGARIAN\x10\x11\x12\t\n\x05\x43ZECH\x10\x12\x12\n\n\x06\x44\x41NISH\x10\x13\x12\x16\n\x12SIMPLIFIED_CHINESE\x10\x1e\x12\x17\n\x13TRADITIONAL_CHINESE\x10\x1f\x42\x64\n\x14org.meshtastic.protoB\x0e\x44\x65viceUIProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.device_ui_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.device_ui_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016DeviceUIProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_COMPASSMODE']._serialized_start=1278
|
||||
_globals['_COMPASSMODE']._serialized_end=1340
|
||||
_globals['_THEME']._serialized_start=1342
|
||||
_globals['_THEME']._serialized_end=1379
|
||||
_globals['_LANGUAGE']._serialized_start=1382
|
||||
_globals['_LANGUAGE']._serialized_end=1702
|
||||
_globals['_DEVICEUICONFIG']._serialized_start=61
|
||||
_globals['_DEVICEUICONFIG']._serialized_end=828
|
||||
_globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_start=742
|
||||
_globals['_DEVICEUICONFIG_GPSCOORDINATEFORMAT']._serialized_end=828
|
||||
_globals['_NODEFILTER']._serialized_start=831
|
||||
_globals['_NODEFILTER']._serialized_end=998
|
||||
_globals['_NODEHIGHLIGHT']._serialized_start=1000
|
||||
_globals['_NODEHIGHLIGHT']._serialized_end=1126
|
||||
_globals['_GEOPOINT']._serialized_start=1128
|
||||
_globals['_GEOPOINT']._serialized_end=1189
|
||||
_globals['_MAP']._serialized_start=1191
|
||||
_globals['_MAP']._serialized_end=1276
|
||||
_COMPASSMODE._serialized_start=1278
|
||||
_COMPASSMODE._serialized_end=1340
|
||||
_THEME._serialized_start=1342
|
||||
_THEME._serialized_end=1379
|
||||
_LANGUAGE._serialized_start=1382
|
||||
_LANGUAGE._serialized_end=1702
|
||||
_DEVICEUICONFIG._serialized_start=61
|
||||
_DEVICEUICONFIG._serialized_end=828
|
||||
_DEVICEUICONFIG_GPSCOORDINATEFORMAT._serialized_start=742
|
||||
_DEVICEUICONFIG_GPSCOORDINATEFORMAT._serialized_end=828
|
||||
_NODEFILTER._serialized_start=831
|
||||
_NODEFILTER._serialized_end=998
|
||||
_NODEHIGHLIGHT._serialized_start=1000
|
||||
_NODEHIGHLIGHT._serialized_end=1126
|
||||
_GEOPOINT._serialized_start=1128
|
||||
_GEOPOINT._serialized_end=1189
|
||||
_MAP._serialized_start=1191
|
||||
_MAP._serialized_end=1276
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,649 +1,146 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
BULGARIAN: Language
|
||||
CZECH: Language
|
||||
DANISH: Language
|
||||
DARK: Theme
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
DUTCH: Language
|
||||
DYNAMIC: CompassMode
|
||||
ENGLISH: Language
|
||||
FINNISH: Language
|
||||
FIXED_RING: CompassMode
|
||||
FREEZE_HEADING: CompassMode
|
||||
FRENCH: Language
|
||||
GERMAN: Language
|
||||
GREEK: Language
|
||||
ITALIAN: Language
|
||||
LIGHT: Theme
|
||||
NORWEGIAN: Language
|
||||
POLISH: Language
|
||||
PORTUGUESE: Language
|
||||
RED: Theme
|
||||
RUSSIAN: Language
|
||||
SERBIAN: Language
|
||||
SIMPLIFIED_CHINESE: Language
|
||||
SLOVENIAN: Language
|
||||
SPANISH: Language
|
||||
SWEDISH: Language
|
||||
TRADITIONAL_CHINESE: Language
|
||||
TURKISH: Language
|
||||
UKRAINIAN: Language
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
class DeviceUIConfig(_message.Message):
|
||||
__slots__ = ["alert_enabled", "banner_enabled", "calibration_data", "compass_mode", "gps_format", "is_clockface_analog", "language", "map_data", "node_filter", "node_highlight", "pin_code", "ring_tone_id", "screen_brightness", "screen_lock", "screen_rgb_color", "screen_timeout", "settings_lock", "theme", "version"]
|
||||
class GpsCoordinateFormat(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
ALERT_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
BANNER_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
CALIBRATION_DATA_FIELD_NUMBER: _ClassVar[int]
|
||||
COMPASS_MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
DEC: DeviceUIConfig.GpsCoordinateFormat
|
||||
DMS: DeviceUIConfig.GpsCoordinateFormat
|
||||
GPS_FORMAT_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_CLOCKFACE_ANALOG_FIELD_NUMBER: _ClassVar[int]
|
||||
LANGUAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
MAP_DATA_FIELD_NUMBER: _ClassVar[int]
|
||||
MGRS: DeviceUIConfig.GpsCoordinateFormat
|
||||
MLS: DeviceUIConfig.GpsCoordinateFormat
|
||||
NODE_FILTER_FIELD_NUMBER: _ClassVar[int]
|
||||
NODE_HIGHLIGHT_FIELD_NUMBER: _ClassVar[int]
|
||||
OLC: DeviceUIConfig.GpsCoordinateFormat
|
||||
OSGR: DeviceUIConfig.GpsCoordinateFormat
|
||||
PIN_CODE_FIELD_NUMBER: _ClassVar[int]
|
||||
RING_TONE_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
SCREEN_BRIGHTNESS_FIELD_NUMBER: _ClassVar[int]
|
||||
SCREEN_LOCK_FIELD_NUMBER: _ClassVar[int]
|
||||
SCREEN_RGB_COLOR_FIELD_NUMBER: _ClassVar[int]
|
||||
SCREEN_TIMEOUT_FIELD_NUMBER: _ClassVar[int]
|
||||
SETTINGS_LOCK_FIELD_NUMBER: _ClassVar[int]
|
||||
THEME_FIELD_NUMBER: _ClassVar[int]
|
||||
UTM: DeviceUIConfig.GpsCoordinateFormat
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
alert_enabled: bool
|
||||
banner_enabled: bool
|
||||
calibration_data: bytes
|
||||
compass_mode: CompassMode
|
||||
gps_format: DeviceUIConfig.GpsCoordinateFormat
|
||||
is_clockface_analog: bool
|
||||
language: Language
|
||||
map_data: Map
|
||||
node_filter: NodeFilter
|
||||
node_highlight: NodeHighlight
|
||||
pin_code: int
|
||||
ring_tone_id: int
|
||||
screen_brightness: int
|
||||
screen_lock: bool
|
||||
screen_rgb_color: int
|
||||
screen_timeout: int
|
||||
settings_lock: bool
|
||||
theme: Theme
|
||||
version: int
|
||||
def __init__(self, version: _Optional[int] = ..., screen_brightness: _Optional[int] = ..., screen_timeout: _Optional[int] = ..., screen_lock: bool = ..., settings_lock: bool = ..., pin_code: _Optional[int] = ..., theme: _Optional[_Union[Theme, str]] = ..., alert_enabled: bool = ..., banner_enabled: bool = ..., ring_tone_id: _Optional[int] = ..., language: _Optional[_Union[Language, str]] = ..., node_filter: _Optional[_Union[NodeFilter, _Mapping]] = ..., node_highlight: _Optional[_Union[NodeHighlight, _Mapping]] = ..., calibration_data: _Optional[bytes] = ..., map_data: _Optional[_Union[Map, _Mapping]] = ..., compass_mode: _Optional[_Union[CompassMode, str]] = ..., screen_rgb_color: _Optional[int] = ..., is_clockface_analog: bool = ..., gps_format: _Optional[_Union[DeviceUIConfig.GpsCoordinateFormat, str]] = ...) -> None: ...
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class GeoPoint(_message.Message):
|
||||
__slots__ = ["latitude", "longitude", "zoom"]
|
||||
LATITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
ZOOM_FIELD_NUMBER: _ClassVar[int]
|
||||
latitude: int
|
||||
longitude: int
|
||||
zoom: int
|
||||
def __init__(self, zoom: _Optional[int] = ..., latitude: _Optional[int] = ..., longitude: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class _CompassMode:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
class Map(_message.Message):
|
||||
__slots__ = ["follow_gps", "home", "style"]
|
||||
FOLLOW_GPS_FIELD_NUMBER: _ClassVar[int]
|
||||
HOME_FIELD_NUMBER: _ClassVar[int]
|
||||
STYLE_FIELD_NUMBER: _ClassVar[int]
|
||||
follow_gps: bool
|
||||
home: GeoPoint
|
||||
style: str
|
||||
def __init__(self, home: _Optional[_Union[GeoPoint, _Mapping]] = ..., style: _Optional[str] = ..., follow_gps: bool = ...) -> None: ...
|
||||
|
||||
class _CompassModeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_CompassMode.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
DYNAMIC: _CompassMode.ValueType # 0
|
||||
"""
|
||||
Compass with dynamic ring and heading
|
||||
"""
|
||||
FIXED_RING: _CompassMode.ValueType # 1
|
||||
"""
|
||||
Compass with fixed ring and heading
|
||||
"""
|
||||
FREEZE_HEADING: _CompassMode.ValueType # 2
|
||||
"""
|
||||
Compass with heading and freeze option
|
||||
"""
|
||||
class NodeFilter(_message.Message):
|
||||
__slots__ = ["channel", "hops_away", "node_name", "offline_switch", "position_switch", "public_key_switch", "unknown_switch"]
|
||||
CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
HOPS_AWAY_FIELD_NUMBER: _ClassVar[int]
|
||||
NODE_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFLINE_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
PUBLIC_KEY_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
UNKNOWN_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
channel: int
|
||||
hops_away: int
|
||||
node_name: str
|
||||
offline_switch: bool
|
||||
position_switch: bool
|
||||
public_key_switch: bool
|
||||
unknown_switch: bool
|
||||
def __init__(self, unknown_switch: bool = ..., offline_switch: bool = ..., public_key_switch: bool = ..., hops_away: _Optional[int] = ..., position_switch: bool = ..., node_name: _Optional[str] = ..., channel: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class CompassMode(_CompassMode, metaclass=_CompassModeEnumTypeWrapper): ...
|
||||
class NodeHighlight(_message.Message):
|
||||
__slots__ = ["chat_switch", "iaq_switch", "node_name", "position_switch", "telemetry_switch"]
|
||||
CHAT_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
IAQ_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
NODE_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
TELEMETRY_SWITCH_FIELD_NUMBER: _ClassVar[int]
|
||||
chat_switch: bool
|
||||
iaq_switch: bool
|
||||
node_name: str
|
||||
position_switch: bool
|
||||
telemetry_switch: bool
|
||||
def __init__(self, chat_switch: bool = ..., position_switch: bool = ..., telemetry_switch: bool = ..., iaq_switch: bool = ..., node_name: _Optional[str] = ...) -> None: ...
|
||||
|
||||
DYNAMIC: CompassMode.ValueType # 0
|
||||
"""
|
||||
Compass with dynamic ring and heading
|
||||
"""
|
||||
FIXED_RING: CompassMode.ValueType # 1
|
||||
"""
|
||||
Compass with fixed ring and heading
|
||||
"""
|
||||
FREEZE_HEADING: CompassMode.ValueType # 2
|
||||
"""
|
||||
Compass with heading and freeze option
|
||||
"""
|
||||
global___CompassMode = CompassMode
|
||||
class CompassMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class _Theme:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
class Theme(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class _ThemeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Theme.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
DARK: _Theme.ValueType # 0
|
||||
"""
|
||||
Dark
|
||||
"""
|
||||
LIGHT: _Theme.ValueType # 1
|
||||
"""
|
||||
Light
|
||||
"""
|
||||
RED: _Theme.ValueType # 2
|
||||
"""
|
||||
Red
|
||||
"""
|
||||
|
||||
class Theme(_Theme, metaclass=_ThemeEnumTypeWrapper): ...
|
||||
|
||||
DARK: Theme.ValueType # 0
|
||||
"""
|
||||
Dark
|
||||
"""
|
||||
LIGHT: Theme.ValueType # 1
|
||||
"""
|
||||
Light
|
||||
"""
|
||||
RED: Theme.ValueType # 2
|
||||
"""
|
||||
Red
|
||||
"""
|
||||
global___Theme = Theme
|
||||
|
||||
class _Language:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _LanguageEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_Language.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
ENGLISH: _Language.ValueType # 0
|
||||
"""
|
||||
English
|
||||
"""
|
||||
FRENCH: _Language.ValueType # 1
|
||||
"""
|
||||
French
|
||||
"""
|
||||
GERMAN: _Language.ValueType # 2
|
||||
"""
|
||||
German
|
||||
"""
|
||||
ITALIAN: _Language.ValueType # 3
|
||||
"""
|
||||
Italian
|
||||
"""
|
||||
PORTUGUESE: _Language.ValueType # 4
|
||||
"""
|
||||
Portuguese
|
||||
"""
|
||||
SPANISH: _Language.ValueType # 5
|
||||
"""
|
||||
Spanish
|
||||
"""
|
||||
SWEDISH: _Language.ValueType # 6
|
||||
"""
|
||||
Swedish
|
||||
"""
|
||||
FINNISH: _Language.ValueType # 7
|
||||
"""
|
||||
Finnish
|
||||
"""
|
||||
POLISH: _Language.ValueType # 8
|
||||
"""
|
||||
Polish
|
||||
"""
|
||||
TURKISH: _Language.ValueType # 9
|
||||
"""
|
||||
Turkish
|
||||
"""
|
||||
SERBIAN: _Language.ValueType # 10
|
||||
"""
|
||||
Serbian
|
||||
"""
|
||||
RUSSIAN: _Language.ValueType # 11
|
||||
"""
|
||||
Russian
|
||||
"""
|
||||
DUTCH: _Language.ValueType # 12
|
||||
"""
|
||||
Dutch
|
||||
"""
|
||||
GREEK: _Language.ValueType # 13
|
||||
"""
|
||||
Greek
|
||||
"""
|
||||
NORWEGIAN: _Language.ValueType # 14
|
||||
"""
|
||||
Norwegian
|
||||
"""
|
||||
SLOVENIAN: _Language.ValueType # 15
|
||||
"""
|
||||
Slovenian
|
||||
"""
|
||||
UKRAINIAN: _Language.ValueType # 16
|
||||
"""
|
||||
Ukrainian
|
||||
"""
|
||||
BULGARIAN: _Language.ValueType # 17
|
||||
"""
|
||||
Bulgarian
|
||||
"""
|
||||
CZECH: _Language.ValueType # 18
|
||||
"""
|
||||
Czech
|
||||
"""
|
||||
DANISH: _Language.ValueType # 19
|
||||
"""
|
||||
Danish
|
||||
"""
|
||||
SIMPLIFIED_CHINESE: _Language.ValueType # 30
|
||||
"""
|
||||
Simplified Chinese (experimental)
|
||||
"""
|
||||
TRADITIONAL_CHINESE: _Language.ValueType # 31
|
||||
"""
|
||||
Traditional Chinese (experimental)
|
||||
"""
|
||||
|
||||
class Language(_Language, metaclass=_LanguageEnumTypeWrapper):
|
||||
"""
|
||||
Localization
|
||||
"""
|
||||
|
||||
ENGLISH: Language.ValueType # 0
|
||||
"""
|
||||
English
|
||||
"""
|
||||
FRENCH: Language.ValueType # 1
|
||||
"""
|
||||
French
|
||||
"""
|
||||
GERMAN: Language.ValueType # 2
|
||||
"""
|
||||
German
|
||||
"""
|
||||
ITALIAN: Language.ValueType # 3
|
||||
"""
|
||||
Italian
|
||||
"""
|
||||
PORTUGUESE: Language.ValueType # 4
|
||||
"""
|
||||
Portuguese
|
||||
"""
|
||||
SPANISH: Language.ValueType # 5
|
||||
"""
|
||||
Spanish
|
||||
"""
|
||||
SWEDISH: Language.ValueType # 6
|
||||
"""
|
||||
Swedish
|
||||
"""
|
||||
FINNISH: Language.ValueType # 7
|
||||
"""
|
||||
Finnish
|
||||
"""
|
||||
POLISH: Language.ValueType # 8
|
||||
"""
|
||||
Polish
|
||||
"""
|
||||
TURKISH: Language.ValueType # 9
|
||||
"""
|
||||
Turkish
|
||||
"""
|
||||
SERBIAN: Language.ValueType # 10
|
||||
"""
|
||||
Serbian
|
||||
"""
|
||||
RUSSIAN: Language.ValueType # 11
|
||||
"""
|
||||
Russian
|
||||
"""
|
||||
DUTCH: Language.ValueType # 12
|
||||
"""
|
||||
Dutch
|
||||
"""
|
||||
GREEK: Language.ValueType # 13
|
||||
"""
|
||||
Greek
|
||||
"""
|
||||
NORWEGIAN: Language.ValueType # 14
|
||||
"""
|
||||
Norwegian
|
||||
"""
|
||||
SLOVENIAN: Language.ValueType # 15
|
||||
"""
|
||||
Slovenian
|
||||
"""
|
||||
UKRAINIAN: Language.ValueType # 16
|
||||
"""
|
||||
Ukrainian
|
||||
"""
|
||||
BULGARIAN: Language.ValueType # 17
|
||||
"""
|
||||
Bulgarian
|
||||
"""
|
||||
CZECH: Language.ValueType # 18
|
||||
"""
|
||||
Czech
|
||||
"""
|
||||
DANISH: Language.ValueType # 19
|
||||
"""
|
||||
Danish
|
||||
"""
|
||||
SIMPLIFIED_CHINESE: Language.ValueType # 30
|
||||
"""
|
||||
Simplified Chinese (experimental)
|
||||
"""
|
||||
TRADITIONAL_CHINESE: Language.ValueType # 31
|
||||
"""
|
||||
Traditional Chinese (experimental)
|
||||
"""
|
||||
global___Language = Language
|
||||
|
||||
@typing.final
|
||||
class DeviceUIConfig(google.protobuf.message.Message):
|
||||
"""
|
||||
Protobuf structures for device-ui persistency
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _GpsCoordinateFormat:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _GpsCoordinateFormatEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[DeviceUIConfig._GpsCoordinateFormat.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
DEC: DeviceUIConfig._GpsCoordinateFormat.ValueType # 0
|
||||
"""
|
||||
GPS coordinates are displayed in the normal decimal degrees format:
|
||||
DD.DDDDDD DDD.DDDDDD
|
||||
"""
|
||||
DMS: DeviceUIConfig._GpsCoordinateFormat.ValueType # 1
|
||||
"""
|
||||
GPS coordinates are displayed in the degrees minutes seconds format:
|
||||
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
|
||||
"""
|
||||
UTM: DeviceUIConfig._GpsCoordinateFormat.ValueType # 2
|
||||
"""
|
||||
Universal Transverse Mercator format:
|
||||
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
|
||||
"""
|
||||
MGRS: DeviceUIConfig._GpsCoordinateFormat.ValueType # 3
|
||||
"""
|
||||
Military Grid Reference System format:
|
||||
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
|
||||
E is easting, N is northing
|
||||
"""
|
||||
OLC: DeviceUIConfig._GpsCoordinateFormat.ValueType # 4
|
||||
"""
|
||||
Open Location Code (aka Plus Codes).
|
||||
"""
|
||||
OSGR: DeviceUIConfig._GpsCoordinateFormat.ValueType # 5
|
||||
"""
|
||||
Ordnance Survey Grid Reference (the National Grid System of the UK).
|
||||
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
|
||||
E is the easting, N is the northing
|
||||
"""
|
||||
MLS: DeviceUIConfig._GpsCoordinateFormat.ValueType # 6
|
||||
"""
|
||||
Maidenhead Locator System
|
||||
Described here: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
|
||||
"""
|
||||
|
||||
class GpsCoordinateFormat(_GpsCoordinateFormat, metaclass=_GpsCoordinateFormatEnumTypeWrapper):
|
||||
"""
|
||||
How the GPS coordinates are displayed on the OLED screen.
|
||||
"""
|
||||
|
||||
DEC: DeviceUIConfig.GpsCoordinateFormat.ValueType # 0
|
||||
"""
|
||||
GPS coordinates are displayed in the normal decimal degrees format:
|
||||
DD.DDDDDD DDD.DDDDDD
|
||||
"""
|
||||
DMS: DeviceUIConfig.GpsCoordinateFormat.ValueType # 1
|
||||
"""
|
||||
GPS coordinates are displayed in the degrees minutes seconds format:
|
||||
DD°MM'SS"C DDD°MM'SS"C, where C is the compass point representing the locations quadrant
|
||||
"""
|
||||
UTM: DeviceUIConfig.GpsCoordinateFormat.ValueType # 2
|
||||
"""
|
||||
Universal Transverse Mercator format:
|
||||
ZZB EEEEEE NNNNNNN, where Z is zone, B is band, E is easting, N is northing
|
||||
"""
|
||||
MGRS: DeviceUIConfig.GpsCoordinateFormat.ValueType # 3
|
||||
"""
|
||||
Military Grid Reference System format:
|
||||
ZZB CD EEEEE NNNNN, where Z is zone, B is band, C is the east 100k square, D is the north 100k square,
|
||||
E is easting, N is northing
|
||||
"""
|
||||
OLC: DeviceUIConfig.GpsCoordinateFormat.ValueType # 4
|
||||
"""
|
||||
Open Location Code (aka Plus Codes).
|
||||
"""
|
||||
OSGR: DeviceUIConfig.GpsCoordinateFormat.ValueType # 5
|
||||
"""
|
||||
Ordnance Survey Grid Reference (the National Grid System of the UK).
|
||||
Format: AB EEEEE NNNNN, where A is the east 100k square, B is the north 100k square,
|
||||
E is the easting, N is the northing
|
||||
"""
|
||||
MLS: DeviceUIConfig.GpsCoordinateFormat.ValueType # 6
|
||||
"""
|
||||
Maidenhead Locator System
|
||||
Described here: https://en.wikipedia.org/wiki/Maidenhead_Locator_System
|
||||
"""
|
||||
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
SCREEN_BRIGHTNESS_FIELD_NUMBER: builtins.int
|
||||
SCREEN_TIMEOUT_FIELD_NUMBER: builtins.int
|
||||
SCREEN_LOCK_FIELD_NUMBER: builtins.int
|
||||
SETTINGS_LOCK_FIELD_NUMBER: builtins.int
|
||||
PIN_CODE_FIELD_NUMBER: builtins.int
|
||||
THEME_FIELD_NUMBER: builtins.int
|
||||
ALERT_ENABLED_FIELD_NUMBER: builtins.int
|
||||
BANNER_ENABLED_FIELD_NUMBER: builtins.int
|
||||
RING_TONE_ID_FIELD_NUMBER: builtins.int
|
||||
LANGUAGE_FIELD_NUMBER: builtins.int
|
||||
NODE_FILTER_FIELD_NUMBER: builtins.int
|
||||
NODE_HIGHLIGHT_FIELD_NUMBER: builtins.int
|
||||
CALIBRATION_DATA_FIELD_NUMBER: builtins.int
|
||||
MAP_DATA_FIELD_NUMBER: builtins.int
|
||||
COMPASS_MODE_FIELD_NUMBER: builtins.int
|
||||
SCREEN_RGB_COLOR_FIELD_NUMBER: builtins.int
|
||||
IS_CLOCKFACE_ANALOG_FIELD_NUMBER: builtins.int
|
||||
GPS_FORMAT_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
A version integer used to invalidate saved files when we make incompatible changes.
|
||||
"""
|
||||
screen_brightness: builtins.int
|
||||
"""
|
||||
TFT display brightness 1..255
|
||||
"""
|
||||
screen_timeout: builtins.int
|
||||
"""
|
||||
Screen timeout 0..900
|
||||
"""
|
||||
screen_lock: builtins.bool
|
||||
"""
|
||||
Screen/Settings lock enabled
|
||||
"""
|
||||
settings_lock: builtins.bool
|
||||
pin_code: builtins.int
|
||||
theme: global___Theme.ValueType
|
||||
"""
|
||||
Color theme
|
||||
"""
|
||||
alert_enabled: builtins.bool
|
||||
"""
|
||||
Audible message, banner and ring tone
|
||||
"""
|
||||
banner_enabled: builtins.bool
|
||||
ring_tone_id: builtins.int
|
||||
language: global___Language.ValueType
|
||||
"""
|
||||
Localization
|
||||
"""
|
||||
calibration_data: builtins.bytes
|
||||
"""
|
||||
8 integers for screen calibration data
|
||||
"""
|
||||
compass_mode: global___CompassMode.ValueType
|
||||
"""
|
||||
Compass mode
|
||||
"""
|
||||
screen_rgb_color: builtins.int
|
||||
"""
|
||||
RGB color for BaseUI
|
||||
0xRRGGBB format, e.g. 0xFF0000 for red
|
||||
"""
|
||||
is_clockface_analog: builtins.bool
|
||||
"""
|
||||
Clockface analog style
|
||||
true for analog clockface, false for digital clockface
|
||||
"""
|
||||
gps_format: global___DeviceUIConfig.GpsCoordinateFormat.ValueType
|
||||
"""
|
||||
How the GPS coordinates are formatted on the OLED screen.
|
||||
"""
|
||||
@property
|
||||
def node_filter(self) -> global___NodeFilter:
|
||||
"""
|
||||
Node list filter
|
||||
"""
|
||||
|
||||
@property
|
||||
def node_highlight(self) -> global___NodeHighlight:
|
||||
"""
|
||||
Node list highlightening
|
||||
"""
|
||||
|
||||
@property
|
||||
def map_data(self) -> global___Map:
|
||||
"""
|
||||
Map related data
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
version: builtins.int = ...,
|
||||
screen_brightness: builtins.int = ...,
|
||||
screen_timeout: builtins.int = ...,
|
||||
screen_lock: builtins.bool = ...,
|
||||
settings_lock: builtins.bool = ...,
|
||||
pin_code: builtins.int = ...,
|
||||
theme: global___Theme.ValueType = ...,
|
||||
alert_enabled: builtins.bool = ...,
|
||||
banner_enabled: builtins.bool = ...,
|
||||
ring_tone_id: builtins.int = ...,
|
||||
language: global___Language.ValueType = ...,
|
||||
node_filter: global___NodeFilter | None = ...,
|
||||
node_highlight: global___NodeHighlight | None = ...,
|
||||
calibration_data: builtins.bytes = ...,
|
||||
map_data: global___Map | None = ...,
|
||||
compass_mode: global___CompassMode.ValueType = ...,
|
||||
screen_rgb_color: builtins.int = ...,
|
||||
is_clockface_analog: builtins.bool = ...,
|
||||
gps_format: global___DeviceUIConfig.GpsCoordinateFormat.ValueType = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["map_data", b"map_data", "node_filter", b"node_filter", "node_highlight", b"node_highlight"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["alert_enabled", b"alert_enabled", "banner_enabled", b"banner_enabled", "calibration_data", b"calibration_data", "compass_mode", b"compass_mode", "gps_format", b"gps_format", "is_clockface_analog", b"is_clockface_analog", "language", b"language", "map_data", b"map_data", "node_filter", b"node_filter", "node_highlight", b"node_highlight", "pin_code", b"pin_code", "ring_tone_id", b"ring_tone_id", "screen_brightness", b"screen_brightness", "screen_lock", b"screen_lock", "screen_rgb_color", b"screen_rgb_color", "screen_timeout", b"screen_timeout", "settings_lock", b"settings_lock", "theme", b"theme", "version", b"version"]) -> None: ...
|
||||
|
||||
global___DeviceUIConfig = DeviceUIConfig
|
||||
|
||||
@typing.final
|
||||
class NodeFilter(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
UNKNOWN_SWITCH_FIELD_NUMBER: builtins.int
|
||||
OFFLINE_SWITCH_FIELD_NUMBER: builtins.int
|
||||
PUBLIC_KEY_SWITCH_FIELD_NUMBER: builtins.int
|
||||
HOPS_AWAY_FIELD_NUMBER: builtins.int
|
||||
POSITION_SWITCH_FIELD_NUMBER: builtins.int
|
||||
NODE_NAME_FIELD_NUMBER: builtins.int
|
||||
CHANNEL_FIELD_NUMBER: builtins.int
|
||||
unknown_switch: builtins.bool
|
||||
"""
|
||||
Filter unknown nodes
|
||||
"""
|
||||
offline_switch: builtins.bool
|
||||
"""
|
||||
Filter offline nodes
|
||||
"""
|
||||
public_key_switch: builtins.bool
|
||||
"""
|
||||
Filter nodes w/o public key
|
||||
"""
|
||||
hops_away: builtins.int
|
||||
"""
|
||||
Filter based on hops away
|
||||
"""
|
||||
position_switch: builtins.bool
|
||||
"""
|
||||
Filter nodes w/o position
|
||||
"""
|
||||
node_name: builtins.str
|
||||
"""
|
||||
Filter nodes by matching name string
|
||||
"""
|
||||
channel: builtins.int
|
||||
"""
|
||||
Filter based on channel
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
unknown_switch: builtins.bool = ...,
|
||||
offline_switch: builtins.bool = ...,
|
||||
public_key_switch: builtins.bool = ...,
|
||||
hops_away: builtins.int = ...,
|
||||
position_switch: builtins.bool = ...,
|
||||
node_name: builtins.str = ...,
|
||||
channel: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["channel", b"channel", "hops_away", b"hops_away", "node_name", b"node_name", "offline_switch", b"offline_switch", "position_switch", b"position_switch", "public_key_switch", b"public_key_switch", "unknown_switch", b"unknown_switch"]) -> None: ...
|
||||
|
||||
global___NodeFilter = NodeFilter
|
||||
|
||||
@typing.final
|
||||
class NodeHighlight(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
CHAT_SWITCH_FIELD_NUMBER: builtins.int
|
||||
POSITION_SWITCH_FIELD_NUMBER: builtins.int
|
||||
TELEMETRY_SWITCH_FIELD_NUMBER: builtins.int
|
||||
IAQ_SWITCH_FIELD_NUMBER: builtins.int
|
||||
NODE_NAME_FIELD_NUMBER: builtins.int
|
||||
chat_switch: builtins.bool
|
||||
"""
|
||||
Hightlight nodes w/ active chat
|
||||
"""
|
||||
position_switch: builtins.bool
|
||||
"""
|
||||
Highlight nodes w/ position
|
||||
"""
|
||||
telemetry_switch: builtins.bool
|
||||
"""
|
||||
Highlight nodes w/ telemetry data
|
||||
"""
|
||||
iaq_switch: builtins.bool
|
||||
"""
|
||||
Highlight nodes w/ iaq data
|
||||
"""
|
||||
node_name: builtins.str
|
||||
"""
|
||||
Highlight nodes by matching name string
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
chat_switch: builtins.bool = ...,
|
||||
position_switch: builtins.bool = ...,
|
||||
telemetry_switch: builtins.bool = ...,
|
||||
iaq_switch: builtins.bool = ...,
|
||||
node_name: builtins.str = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["chat_switch", b"chat_switch", "iaq_switch", b"iaq_switch", "node_name", b"node_name", "position_switch", b"position_switch", "telemetry_switch", b"telemetry_switch"]) -> None: ...
|
||||
|
||||
global___NodeHighlight = NodeHighlight
|
||||
|
||||
@typing.final
|
||||
class GeoPoint(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
ZOOM_FIELD_NUMBER: builtins.int
|
||||
LATITUDE_FIELD_NUMBER: builtins.int
|
||||
LONGITUDE_FIELD_NUMBER: builtins.int
|
||||
zoom: builtins.int
|
||||
"""
|
||||
Zoom level
|
||||
"""
|
||||
latitude: builtins.int
|
||||
"""
|
||||
Coordinate: latitude
|
||||
"""
|
||||
longitude: builtins.int
|
||||
"""
|
||||
Coordinate: longitude
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
zoom: builtins.int = ...,
|
||||
latitude: builtins.int = ...,
|
||||
longitude: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["latitude", b"latitude", "longitude", b"longitude", "zoom", b"zoom"]) -> None: ...
|
||||
|
||||
global___GeoPoint = GeoPoint
|
||||
|
||||
@typing.final
|
||||
class Map(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
HOME_FIELD_NUMBER: builtins.int
|
||||
STYLE_FIELD_NUMBER: builtins.int
|
||||
FOLLOW_GPS_FIELD_NUMBER: builtins.int
|
||||
style: builtins.str
|
||||
"""
|
||||
Map tile style
|
||||
"""
|
||||
follow_gps: builtins.bool
|
||||
"""
|
||||
Map scroll follows GPS
|
||||
"""
|
||||
@property
|
||||
def home(self) -> global___GeoPoint:
|
||||
"""
|
||||
Home coordinates
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
home: global___GeoPoint | None = ...,
|
||||
style: builtins.str = ...,
|
||||
follow_gps: builtins.bool = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["home", b"home"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["follow_gps", b"follow_gps", "home", b"home", "style", b"style"]) -> None: ...
|
||||
|
||||
global___Map = Map
|
||||
class Language(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/deviceonly.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -21,10 +21,10 @@ from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/deviceonly.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/nanopb.proto\"\x99\x01\n\x0cPositionLite\x12\x12\n\nlatitude_i\x18\x01 \x01(\x0f\x12\x13\n\x0blongitude_i\x18\x02 \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x03 \x01(\x05\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\"\x94\x02\n\x08UserLite\x12\x13\n\x07macaddr\x18\x01 \x01(\x0c\x42\x02\x18\x01\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x05 \x01(\x08\x12;\n\x04role\x18\x06 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x07 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"\xf0\x02\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12+\n\x04user\x18\x02 \x01(\x0b\x32\x1d.meshtastic.protobuf.UserLite\x12\x33\n\x08position\x18\x03 \x01(\x0b\x32!.meshtastic.protobuf.PositionLite\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12:\n\x0e\x64\x65vice_metrics\x18\x06 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x10\n\x08via_mqtt\x18\x08 \x01(\x08\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x13\n\x0bis_favorite\x18\n \x01(\x08\x12\x12\n\nis_ignored\x18\x0b \x01(\x08\x12\x10\n\x08next_hop\x18\x0c \x01(\r\x12\x10\n\x08\x62itfield\x18\r \x01(\rB\x0c\n\n_hops_away\"\xa1\x03\n\x0b\x44\x65viceState\x12\x30\n\x07my_node\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.MyNodeInfo\x12(\n\x05owner\x18\x03 \x01(\x0b\x32\x19.meshtastic.protobuf.User\x12\x36\n\rreceive_queue\x18\x05 \x03(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x0f\n\x07version\x18\x08 \x01(\r\x12\x38\n\x0frx_text_message\x18\x07 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x13\n\x07no_save\x18\t \x01(\x08\x42\x02\x18\x01\x12\x19\n\rdid_gps_reset\x18\x0b \x01(\x08\x42\x02\x18\x01\x12\x34\n\x0brx_waypoint\x18\x0c \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12M\n\x19node_remote_hardware_pins\x18\r \x03(\x0b\x32*.meshtastic.protobuf.NodeRemoteHardwarePin\"}\n\x0cNodeDatabase\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\\\n\x05nodes\x18\x02 \x03(\x0b\x32!.meshtastic.protobuf.NodeInfoLiteB*\x92?\'\x92\x01$std::vector<meshtastic_NodeInfoLite>\"N\n\x0b\x43hannelFile\x12.\n\x08\x63hannels\x18\x01 \x03(\x0b\x32\x1c.meshtastic.protobuf.Channel\x12\x0f\n\x07version\x18\x02 \x01(\r\"\x86\x02\n\x11\x42\x61\x63kupPreferences\x12\x0f\n\x07version\x18\x01 \x01(\r\x12\x11\n\ttimestamp\x18\x02 \x01(\x07\x12\x30\n\x06\x63onfig\x18\x03 \x01(\x0b\x32 .meshtastic.protobuf.LocalConfig\x12=\n\rmodule_config\x18\x04 \x01(\x0b\x32&.meshtastic.protobuf.LocalModuleConfig\x12\x32\n\x08\x63hannels\x18\x05 \x01(\x0b\x32 .meshtastic.protobuf.ChannelFile\x12(\n\x05owner\x18\x06 \x01(\x0b\x32\x19.meshtastic.protobuf.UserBn\n\x14org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08<vector>b\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceonly_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceonly_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nDeviceOnlyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010<vector>'
|
||||
_USERLITE.fields_by_name['macaddr']._options = None
|
||||
@@ -35,18 +35,18 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
_DEVICESTATE.fields_by_name['did_gps_reset']._serialized_options = b'\030\001'
|
||||
_NODEDATABASE.fields_by_name['nodes']._options = None
|
||||
_NODEDATABASE.fields_by_name['nodes']._serialized_options = b'\222?\'\222\001$std::vector<meshtastic_NodeInfoLite>'
|
||||
_globals['_POSITIONLITE']._serialized_start=271
|
||||
_globals['_POSITIONLITE']._serialized_end=424
|
||||
_globals['_USERLITE']._serialized_start=427
|
||||
_globals['_USERLITE']._serialized_end=703
|
||||
_globals['_NODEINFOLITE']._serialized_start=706
|
||||
_globals['_NODEINFOLITE']._serialized_end=1074
|
||||
_globals['_DEVICESTATE']._serialized_start=1077
|
||||
_globals['_DEVICESTATE']._serialized_end=1494
|
||||
_globals['_NODEDATABASE']._serialized_start=1496
|
||||
_globals['_NODEDATABASE']._serialized_end=1621
|
||||
_globals['_CHANNELFILE']._serialized_start=1623
|
||||
_globals['_CHANNELFILE']._serialized_end=1701
|
||||
_globals['_BACKUPPREFERENCES']._serialized_start=1704
|
||||
_globals['_BACKUPPREFERENCES']._serialized_end=1966
|
||||
_POSITIONLITE._serialized_start=271
|
||||
_POSITIONLITE._serialized_end=424
|
||||
_USERLITE._serialized_start=427
|
||||
_USERLITE._serialized_end=703
|
||||
_NODEINFOLITE._serialized_start=706
|
||||
_NODEINFOLITE._serialized_end=1074
|
||||
_DEVICESTATE._serialized_start=1077
|
||||
_DEVICESTATE._serialized_end=1494
|
||||
_NODEDATABASE._serialized_start=1496
|
||||
_NODEDATABASE._serialized_end=1621
|
||||
_CHANNELFILE._serialized_start=1623
|
||||
_CHANNELFILE._serialized_end=1701
|
||||
_BACKUPPREFERENCES._serialized_start=1704
|
||||
_BACKUPPREFERENCES._serialized_end=1966
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,458 +1,130 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from meshtastic.protobuf import channel_pb2 as _channel_pb2
|
||||
from meshtastic.protobuf import config_pb2 as _config_pb2
|
||||
from meshtastic.protobuf import localonly_pb2 as _localonly_pb2
|
||||
from meshtastic.protobuf import mesh_pb2 as _mesh_pb2
|
||||
from meshtastic.protobuf import telemetry_pb2 as _telemetry_pb2
|
||||
from meshtastic.protobuf import nanopb_pb2 as _nanopb_pb2
|
||||
from google.protobuf.internal import containers as _containers
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import collections.abc
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.containers
|
||||
import google.protobuf.message
|
||||
import meshtastic.protobuf.channel_pb2
|
||||
import meshtastic.protobuf.config_pb2
|
||||
import meshtastic.protobuf.localonly_pb2
|
||||
import meshtastic.protobuf.mesh_pb2
|
||||
import meshtastic.protobuf.telemetry_pb2
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class BackupPreferences(_message.Message):
|
||||
__slots__ = ["channels", "config", "module_config", "owner", "timestamp", "version"]
|
||||
CHANNELS_FIELD_NUMBER: _ClassVar[int]
|
||||
CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
MODULE_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
OWNER_FIELD_NUMBER: _ClassVar[int]
|
||||
TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
channels: ChannelFile
|
||||
config: _localonly_pb2.LocalConfig
|
||||
module_config: _localonly_pb2.LocalModuleConfig
|
||||
owner: _mesh_pb2.User
|
||||
timestamp: int
|
||||
version: int
|
||||
def __init__(self, version: _Optional[int] = ..., timestamp: _Optional[int] = ..., config: _Optional[_Union[_localonly_pb2.LocalConfig, _Mapping]] = ..., module_config: _Optional[_Union[_localonly_pb2.LocalModuleConfig, _Mapping]] = ..., channels: _Optional[_Union[ChannelFile, _Mapping]] = ..., owner: _Optional[_Union[_mesh_pb2.User, _Mapping]] = ...) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class PositionLite(google.protobuf.message.Message):
|
||||
"""
|
||||
Position with static location information only for NodeDBLite
|
||||
"""
|
||||
class ChannelFile(_message.Message):
|
||||
__slots__ = ["channels", "version"]
|
||||
CHANNELS_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
channels: _containers.RepeatedCompositeFieldContainer[_channel_pb2.Channel]
|
||||
version: int
|
||||
def __init__(self, channels: _Optional[_Iterable[_Union[_channel_pb2.Channel, _Mapping]]] = ..., version: _Optional[int] = ...) -> None: ...
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
class DeviceState(_message.Message):
|
||||
__slots__ = ["did_gps_reset", "my_node", "no_save", "node_remote_hardware_pins", "owner", "receive_queue", "rx_text_message", "rx_waypoint", "version"]
|
||||
DID_GPS_RESET_FIELD_NUMBER: _ClassVar[int]
|
||||
MY_NODE_FIELD_NUMBER: _ClassVar[int]
|
||||
NODE_REMOTE_HARDWARE_PINS_FIELD_NUMBER: _ClassVar[int]
|
||||
NO_SAVE_FIELD_NUMBER: _ClassVar[int]
|
||||
OWNER_FIELD_NUMBER: _ClassVar[int]
|
||||
RECEIVE_QUEUE_FIELD_NUMBER: _ClassVar[int]
|
||||
RX_TEXT_MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
RX_WAYPOINT_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
did_gps_reset: bool
|
||||
my_node: _mesh_pb2.MyNodeInfo
|
||||
no_save: bool
|
||||
node_remote_hardware_pins: _containers.RepeatedCompositeFieldContainer[_mesh_pb2.NodeRemoteHardwarePin]
|
||||
owner: _mesh_pb2.User
|
||||
receive_queue: _containers.RepeatedCompositeFieldContainer[_mesh_pb2.MeshPacket]
|
||||
rx_text_message: _mesh_pb2.MeshPacket
|
||||
rx_waypoint: _mesh_pb2.MeshPacket
|
||||
version: int
|
||||
def __init__(self, my_node: _Optional[_Union[_mesh_pb2.MyNodeInfo, _Mapping]] = ..., owner: _Optional[_Union[_mesh_pb2.User, _Mapping]] = ..., receive_queue: _Optional[_Iterable[_Union[_mesh_pb2.MeshPacket, _Mapping]]] = ..., version: _Optional[int] = ..., rx_text_message: _Optional[_Union[_mesh_pb2.MeshPacket, _Mapping]] = ..., no_save: bool = ..., did_gps_reset: bool = ..., rx_waypoint: _Optional[_Union[_mesh_pb2.MeshPacket, _Mapping]] = ..., node_remote_hardware_pins: _Optional[_Iterable[_Union[_mesh_pb2.NodeRemoteHardwarePin, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
LATITUDE_I_FIELD_NUMBER: builtins.int
|
||||
LONGITUDE_I_FIELD_NUMBER: builtins.int
|
||||
ALTITUDE_FIELD_NUMBER: builtins.int
|
||||
TIME_FIELD_NUMBER: builtins.int
|
||||
LOCATION_SOURCE_FIELD_NUMBER: builtins.int
|
||||
latitude_i: builtins.int
|
||||
"""
|
||||
The new preferred location encoding, multiply by 1e-7 to get degrees
|
||||
in floating point
|
||||
"""
|
||||
longitude_i: builtins.int
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
altitude: builtins.int
|
||||
"""
|
||||
In meters above MSL (but see issue #359)
|
||||
"""
|
||||
time: builtins.int
|
||||
"""
|
||||
This is usually not sent over the mesh (to save space), but it is sent
|
||||
from the phone so that the local device can set its RTC If it is sent over
|
||||
the mesh (because there are devices on the mesh without GPS), it will only
|
||||
be sent by devices which has a hardware GPS clock.
|
||||
seconds since 1970
|
||||
"""
|
||||
location_source: meshtastic.protobuf.mesh_pb2.Position.LocSource.ValueType
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
latitude_i: builtins.int = ...,
|
||||
longitude_i: builtins.int = ...,
|
||||
altitude: builtins.int = ...,
|
||||
time: builtins.int = ...,
|
||||
location_source: meshtastic.protobuf.mesh_pb2.Position.LocSource.ValueType = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "latitude_i", b"latitude_i", "location_source", b"location_source", "longitude_i", b"longitude_i", "time", b"time"]) -> None: ...
|
||||
class NodeDatabase(_message.Message):
|
||||
__slots__ = ["nodes", "version"]
|
||||
NODES_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
nodes: _containers.RepeatedCompositeFieldContainer[NodeInfoLite]
|
||||
version: int
|
||||
def __init__(self, version: _Optional[int] = ..., nodes: _Optional[_Iterable[_Union[NodeInfoLite, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
global___PositionLite = PositionLite
|
||||
class NodeInfoLite(_message.Message):
|
||||
__slots__ = ["bitfield", "channel", "device_metrics", "hops_away", "is_favorite", "is_ignored", "last_heard", "next_hop", "num", "position", "snr", "user", "via_mqtt"]
|
||||
BITFIELD_FIELD_NUMBER: _ClassVar[int]
|
||||
CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
DEVICE_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
HOPS_AWAY_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_FAVORITE_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_IGNORED_FIELD_NUMBER: _ClassVar[int]
|
||||
LAST_HEARD_FIELD_NUMBER: _ClassVar[int]
|
||||
NEXT_HOP_FIELD_NUMBER: _ClassVar[int]
|
||||
NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
SNR_FIELD_NUMBER: _ClassVar[int]
|
||||
USER_FIELD_NUMBER: _ClassVar[int]
|
||||
VIA_MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
bitfield: int
|
||||
channel: int
|
||||
device_metrics: _telemetry_pb2.DeviceMetrics
|
||||
hops_away: int
|
||||
is_favorite: bool
|
||||
is_ignored: bool
|
||||
last_heard: int
|
||||
next_hop: int
|
||||
num: int
|
||||
position: PositionLite
|
||||
snr: float
|
||||
user: UserLite
|
||||
via_mqtt: bool
|
||||
def __init__(self, num: _Optional[int] = ..., user: _Optional[_Union[UserLite, _Mapping]] = ..., position: _Optional[_Union[PositionLite, _Mapping]] = ..., snr: _Optional[float] = ..., last_heard: _Optional[int] = ..., device_metrics: _Optional[_Union[_telemetry_pb2.DeviceMetrics, _Mapping]] = ..., channel: _Optional[int] = ..., via_mqtt: bool = ..., hops_away: _Optional[int] = ..., is_favorite: bool = ..., is_ignored: bool = ..., next_hop: _Optional[int] = ..., bitfield: _Optional[int] = ...) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class UserLite(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
class PositionLite(_message.Message):
|
||||
__slots__ = ["altitude", "latitude_i", "location_source", "longitude_i", "time"]
|
||||
ALTITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
LATITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LOCATION_SOURCE_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
altitude: int
|
||||
latitude_i: int
|
||||
location_source: _mesh_pb2.Position.LocSource
|
||||
longitude_i: int
|
||||
time: int
|
||||
def __init__(self, latitude_i: _Optional[int] = ..., longitude_i: _Optional[int] = ..., altitude: _Optional[int] = ..., time: _Optional[int] = ..., location_source: _Optional[_Union[_mesh_pb2.Position.LocSource, str]] = ...) -> None: ...
|
||||
|
||||
MACADDR_FIELD_NUMBER: builtins.int
|
||||
LONG_NAME_FIELD_NUMBER: builtins.int
|
||||
SHORT_NAME_FIELD_NUMBER: builtins.int
|
||||
HW_MODEL_FIELD_NUMBER: builtins.int
|
||||
IS_LICENSED_FIELD_NUMBER: builtins.int
|
||||
ROLE_FIELD_NUMBER: builtins.int
|
||||
PUBLIC_KEY_FIELD_NUMBER: builtins.int
|
||||
IS_UNMESSAGABLE_FIELD_NUMBER: builtins.int
|
||||
macaddr: builtins.bytes
|
||||
"""
|
||||
This is the addr of the radio.
|
||||
"""
|
||||
long_name: builtins.str
|
||||
"""
|
||||
A full name for this user, i.e. "Kevin Hester"
|
||||
"""
|
||||
short_name: builtins.str
|
||||
"""
|
||||
A VERY short name, ideally two characters.
|
||||
Suitable for a tiny OLED screen
|
||||
"""
|
||||
hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType
|
||||
"""
|
||||
TBEAM, HELTEC, etc...
|
||||
Starting in 1.2.11 moved to hw_model enum in the NodeInfo object.
|
||||
Apps will still need the string here for older builds
|
||||
(so OTA update can find the right image), but if the enum is available it will be used instead.
|
||||
"""
|
||||
is_licensed: builtins.bool
|
||||
"""
|
||||
In some regions Ham radio operators have different bandwidth limitations than others.
|
||||
If this user is a licensed operator, set this flag.
|
||||
Also, "long_name" should be their licence number.
|
||||
"""
|
||||
role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType
|
||||
"""
|
||||
Indicates that the user's role in the mesh
|
||||
"""
|
||||
public_key: builtins.bytes
|
||||
"""
|
||||
The public key of the user's device.
|
||||
This is sent out to other nodes on the mesh to allow them to compute a shared secret key.
|
||||
"""
|
||||
is_unmessagable: builtins.bool
|
||||
"""
|
||||
Whether or not the node can be messaged
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
macaddr: builtins.bytes = ...,
|
||||
long_name: builtins.str = ...,
|
||||
short_name: builtins.str = ...,
|
||||
hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType = ...,
|
||||
is_licensed: builtins.bool = ...,
|
||||
role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ...,
|
||||
public_key: builtins.bytes = ...,
|
||||
is_unmessagable: builtins.bool | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["_is_unmessagable", b"_is_unmessagable", "is_unmessagable", b"is_unmessagable"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["_is_unmessagable", b"_is_unmessagable", "hw_model", b"hw_model", "is_licensed", b"is_licensed", "is_unmessagable", b"is_unmessagable", "long_name", b"long_name", "macaddr", b"macaddr", "public_key", b"public_key", "role", b"role", "short_name", b"short_name"]) -> None: ...
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_is_unmessagable", b"_is_unmessagable"]) -> typing.Literal["is_unmessagable"] | None: ...
|
||||
|
||||
global___UserLite = UserLite
|
||||
|
||||
@typing.final
|
||||
class NodeInfoLite(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
NUM_FIELD_NUMBER: builtins.int
|
||||
USER_FIELD_NUMBER: builtins.int
|
||||
POSITION_FIELD_NUMBER: builtins.int
|
||||
SNR_FIELD_NUMBER: builtins.int
|
||||
LAST_HEARD_FIELD_NUMBER: builtins.int
|
||||
DEVICE_METRICS_FIELD_NUMBER: builtins.int
|
||||
CHANNEL_FIELD_NUMBER: builtins.int
|
||||
VIA_MQTT_FIELD_NUMBER: builtins.int
|
||||
HOPS_AWAY_FIELD_NUMBER: builtins.int
|
||||
IS_FAVORITE_FIELD_NUMBER: builtins.int
|
||||
IS_IGNORED_FIELD_NUMBER: builtins.int
|
||||
NEXT_HOP_FIELD_NUMBER: builtins.int
|
||||
BITFIELD_FIELD_NUMBER: builtins.int
|
||||
num: builtins.int
|
||||
"""
|
||||
The node number
|
||||
"""
|
||||
snr: builtins.float
|
||||
"""
|
||||
Returns the Signal-to-noise ratio (SNR) of the last received message,
|
||||
as measured by the receiver. Return SNR of the last received message in dB
|
||||
"""
|
||||
last_heard: builtins.int
|
||||
"""
|
||||
Set to indicate the last time we received a packet from this node
|
||||
"""
|
||||
channel: builtins.int
|
||||
"""
|
||||
local channel index we heard that node on. Only populated if its not the default channel.
|
||||
"""
|
||||
via_mqtt: builtins.bool
|
||||
"""
|
||||
True if we witnessed the node over MQTT instead of LoRA transport
|
||||
"""
|
||||
hops_away: builtins.int
|
||||
"""
|
||||
Number of hops away from us this node is (0 if direct neighbor)
|
||||
"""
|
||||
is_favorite: builtins.bool
|
||||
"""
|
||||
True if node is in our favorites list
|
||||
Persists between NodeDB internal clean ups
|
||||
"""
|
||||
is_ignored: builtins.bool
|
||||
"""
|
||||
True if node is in our ignored list
|
||||
Persists between NodeDB internal clean ups
|
||||
"""
|
||||
next_hop: builtins.int
|
||||
"""
|
||||
Last byte of the node number of the node that should be used as the next hop to reach this node.
|
||||
"""
|
||||
bitfield: builtins.int
|
||||
"""
|
||||
Bitfield for storing booleans.
|
||||
LSB 0 is_key_manually_verified
|
||||
"""
|
||||
@property
|
||||
def user(self) -> global___UserLite:
|
||||
"""
|
||||
The user info for this node
|
||||
"""
|
||||
|
||||
@property
|
||||
def position(self) -> global___PositionLite:
|
||||
"""
|
||||
This position data. Note: before 1.2.14 we would also store the last time we've heard from this node in position.time, that is no longer true.
|
||||
Position.time now indicates the last time we received a POSITION from that node.
|
||||
"""
|
||||
|
||||
@property
|
||||
def device_metrics(self) -> meshtastic.protobuf.telemetry_pb2.DeviceMetrics:
|
||||
"""
|
||||
The latest device metrics for the node.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
num: builtins.int = ...,
|
||||
user: global___UserLite | None = ...,
|
||||
position: global___PositionLite | None = ...,
|
||||
snr: builtins.float = ...,
|
||||
last_heard: builtins.int = ...,
|
||||
device_metrics: meshtastic.protobuf.telemetry_pb2.DeviceMetrics | None = ...,
|
||||
channel: builtins.int = ...,
|
||||
via_mqtt: builtins.bool = ...,
|
||||
hops_away: builtins.int | None = ...,
|
||||
is_favorite: builtins.bool = ...,
|
||||
is_ignored: builtins.bool = ...,
|
||||
next_hop: builtins.int = ...,
|
||||
bitfield: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "position", b"position", "user", b"user"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["_hops_away", b"_hops_away", "bitfield", b"bitfield", "channel", b"channel", "device_metrics", b"device_metrics", "hops_away", b"hops_away", "is_favorite", b"is_favorite", "is_ignored", b"is_ignored", "last_heard", b"last_heard", "next_hop", b"next_hop", "num", b"num", "position", b"position", "snr", b"snr", "user", b"user", "via_mqtt", b"via_mqtt"]) -> None: ...
|
||||
def WhichOneof(self, oneof_group: typing.Literal["_hops_away", b"_hops_away"]) -> typing.Literal["hops_away"] | None: ...
|
||||
|
||||
global___NodeInfoLite = NodeInfoLite
|
||||
|
||||
@typing.final
|
||||
class DeviceState(google.protobuf.message.Message):
|
||||
"""
|
||||
This message is never sent over the wire, but it is used for serializing DB
|
||||
state to flash in the device code
|
||||
FIXME, since we write this each time we enter deep sleep (and have infinite
|
||||
flash) it would be better to use some sort of append only data structure for
|
||||
the receive queue and use the preferences store for the other stuff
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
MY_NODE_FIELD_NUMBER: builtins.int
|
||||
OWNER_FIELD_NUMBER: builtins.int
|
||||
RECEIVE_QUEUE_FIELD_NUMBER: builtins.int
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
RX_TEXT_MESSAGE_FIELD_NUMBER: builtins.int
|
||||
NO_SAVE_FIELD_NUMBER: builtins.int
|
||||
DID_GPS_RESET_FIELD_NUMBER: builtins.int
|
||||
RX_WAYPOINT_FIELD_NUMBER: builtins.int
|
||||
NODE_REMOTE_HARDWARE_PINS_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code.
|
||||
"""
|
||||
no_save: builtins.bool
|
||||
"""
|
||||
Used only during development.
|
||||
Indicates developer is testing and changes should never be saved to flash.
|
||||
Deprecated in 2.3.1
|
||||
"""
|
||||
did_gps_reset: builtins.bool
|
||||
"""
|
||||
Previously used to manage GPS factory resets.
|
||||
Deprecated in 2.5.23
|
||||
"""
|
||||
@property
|
||||
def my_node(self) -> meshtastic.protobuf.mesh_pb2.MyNodeInfo:
|
||||
"""
|
||||
Read only settings/info about this node
|
||||
"""
|
||||
|
||||
@property
|
||||
def owner(self) -> meshtastic.protobuf.mesh_pb2.User:
|
||||
"""
|
||||
My owner info
|
||||
"""
|
||||
|
||||
@property
|
||||
def receive_queue(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.mesh_pb2.MeshPacket]:
|
||||
"""
|
||||
Received packets saved for delivery to the phone
|
||||
"""
|
||||
|
||||
@property
|
||||
def rx_text_message(self) -> meshtastic.protobuf.mesh_pb2.MeshPacket:
|
||||
"""
|
||||
We keep the last received text message (only) stored in the device flash,
|
||||
so we can show it on the screen.
|
||||
Might be null
|
||||
"""
|
||||
|
||||
@property
|
||||
def rx_waypoint(self) -> meshtastic.protobuf.mesh_pb2.MeshPacket:
|
||||
"""
|
||||
We keep the last received waypoint stored in the device flash,
|
||||
so we can show it on the screen.
|
||||
Might be null
|
||||
"""
|
||||
|
||||
@property
|
||||
def node_remote_hardware_pins(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.mesh_pb2.NodeRemoteHardwarePin]:
|
||||
"""
|
||||
The mesh's nodes with their available gpio pins for RemoteHardware module
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
my_node: meshtastic.protobuf.mesh_pb2.MyNodeInfo | None = ...,
|
||||
owner: meshtastic.protobuf.mesh_pb2.User | None = ...,
|
||||
receive_queue: collections.abc.Iterable[meshtastic.protobuf.mesh_pb2.MeshPacket] | None = ...,
|
||||
version: builtins.int = ...,
|
||||
rx_text_message: meshtastic.protobuf.mesh_pb2.MeshPacket | None = ...,
|
||||
no_save: builtins.bool = ...,
|
||||
did_gps_reset: builtins.bool = ...,
|
||||
rx_waypoint: meshtastic.protobuf.mesh_pb2.MeshPacket | None = ...,
|
||||
node_remote_hardware_pins: collections.abc.Iterable[meshtastic.protobuf.mesh_pb2.NodeRemoteHardwarePin] | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["my_node", b"my_node", "owner", b"owner", "rx_text_message", b"rx_text_message", "rx_waypoint", b"rx_waypoint"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["did_gps_reset", b"did_gps_reset", "my_node", b"my_node", "no_save", b"no_save", "node_remote_hardware_pins", b"node_remote_hardware_pins", "owner", b"owner", "receive_queue", b"receive_queue", "rx_text_message", b"rx_text_message", "rx_waypoint", b"rx_waypoint", "version", b"version"]) -> None: ...
|
||||
|
||||
global___DeviceState = DeviceState
|
||||
|
||||
@typing.final
|
||||
class NodeDatabase(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
NODES_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code.
|
||||
"""
|
||||
@property
|
||||
def nodes(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___NodeInfoLite]:
|
||||
"""
|
||||
New lite version of NodeDB to decrease memory footprint
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
version: builtins.int = ...,
|
||||
nodes: collections.abc.Iterable[global___NodeInfoLite] | None = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["nodes", b"nodes", "version", b"version"]) -> None: ...
|
||||
|
||||
global___NodeDatabase = NodeDatabase
|
||||
|
||||
@typing.final
|
||||
class ChannelFile(google.protobuf.message.Message):
|
||||
"""
|
||||
The on-disk saved channels
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
CHANNELS_FIELD_NUMBER: builtins.int
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code.
|
||||
"""
|
||||
@property
|
||||
def channels(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[meshtastic.protobuf.channel_pb2.Channel]:
|
||||
"""
|
||||
The channels our node knows about
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
channels: collections.abc.Iterable[meshtastic.protobuf.channel_pb2.Channel] | None = ...,
|
||||
version: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["channels", b"channels", "version", b"version"]) -> None: ...
|
||||
|
||||
global___ChannelFile = ChannelFile
|
||||
|
||||
@typing.final
|
||||
class BackupPreferences(google.protobuf.message.Message):
|
||||
"""
|
||||
The on-disk backup of the node's preferences
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
TIMESTAMP_FIELD_NUMBER: builtins.int
|
||||
CONFIG_FIELD_NUMBER: builtins.int
|
||||
MODULE_CONFIG_FIELD_NUMBER: builtins.int
|
||||
CHANNELS_FIELD_NUMBER: builtins.int
|
||||
OWNER_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
The version of the backup
|
||||
"""
|
||||
timestamp: builtins.int
|
||||
"""
|
||||
The timestamp of the backup (if node has time)
|
||||
"""
|
||||
@property
|
||||
def config(self) -> meshtastic.protobuf.localonly_pb2.LocalConfig:
|
||||
"""
|
||||
The node's configuration
|
||||
"""
|
||||
|
||||
@property
|
||||
def module_config(self) -> meshtastic.protobuf.localonly_pb2.LocalModuleConfig:
|
||||
"""
|
||||
The node's module configuration
|
||||
"""
|
||||
|
||||
@property
|
||||
def channels(self) -> global___ChannelFile:
|
||||
"""
|
||||
The node's channels
|
||||
"""
|
||||
|
||||
@property
|
||||
def owner(self) -> meshtastic.protobuf.mesh_pb2.User:
|
||||
"""
|
||||
The node's user (owner) information
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
version: builtins.int = ...,
|
||||
timestamp: builtins.int = ...,
|
||||
config: meshtastic.protobuf.localonly_pb2.LocalConfig | None = ...,
|
||||
module_config: meshtastic.protobuf.localonly_pb2.LocalModuleConfig | None = ...,
|
||||
channels: global___ChannelFile | None = ...,
|
||||
owner: meshtastic.protobuf.mesh_pb2.User | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["channels", b"channels", "config", b"config", "module_config", b"module_config", "owner", b"owner"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["channels", b"channels", "config", b"config", "module_config", b"module_config", "owner", b"owner", "timestamp", b"timestamp", "version", b"version"]) -> None: ...
|
||||
|
||||
global___BackupPreferences = BackupPreferences
|
||||
class UserLite(_message.Message):
|
||||
__slots__ = ["hw_model", "is_licensed", "is_unmessagable", "long_name", "macaddr", "public_key", "role", "short_name"]
|
||||
HW_MODEL_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_LICENSED_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_UNMESSAGABLE_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
MACADDR_FIELD_NUMBER: _ClassVar[int]
|
||||
PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int]
|
||||
ROLE_FIELD_NUMBER: _ClassVar[int]
|
||||
SHORT_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
hw_model: _mesh_pb2.HardwareModel
|
||||
is_licensed: bool
|
||||
is_unmessagable: bool
|
||||
long_name: str
|
||||
macaddr: bytes
|
||||
public_key: bytes
|
||||
role: _config_pb2.Config.DeviceConfig.Role
|
||||
short_name: str
|
||||
def __init__(self, macaddr: _Optional[bytes] = ..., long_name: _Optional[str] = ..., short_name: _Optional[str] = ..., hw_model: _Optional[_Union[_mesh_pb2.HardwareModel, str]] = ..., is_licensed: bool = ..., role: _Optional[_Union[_config_pb2.Config.DeviceConfig.Role, str]] = ..., public_key: _Optional[bytes] = ..., is_unmessagable: bool = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/interdevice.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,16 +15,16 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%meshtastic/protobuf/interdevice.proto\x12\x13meshtastic.protobuf\"s\n\nSensorData\x12.\n\x04type\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.MessageType\x12\x15\n\x0b\x66loat_value\x18\x02 \x01(\x02H\x00\x12\x16\n\x0cuint32_value\x18\x03 \x01(\rH\x00\x42\x06\n\x04\x64\x61ta\"_\n\x12InterdeviceMessage\x12\x0e\n\x04nmea\x18\x01 \x01(\tH\x00\x12\x31\n\x06sensor\x18\x02 \x01(\x0b\x32\x1f.meshtastic.protobuf.SensorDataH\x00\x42\x06\n\x04\x64\x61ta*\xd5\x01\n\x0bMessageType\x12\x07\n\x03\x41\x43K\x10\x00\x12\x15\n\x10\x43OLLECT_INTERVAL\x10\xa0\x01\x12\x0c\n\x07\x42\x45\x45P_ON\x10\xa1\x01\x12\r\n\x08\x42\x45\x45P_OFF\x10\xa2\x01\x12\r\n\x08SHUTDOWN\x10\xa3\x01\x12\r\n\x08POWER_ON\x10\xa4\x01\x12\x0f\n\nSCD41_TEMP\x10\xb0\x01\x12\x13\n\x0eSCD41_HUMIDITY\x10\xb1\x01\x12\x0e\n\tSCD41_CO2\x10\xb2\x01\x12\x0f\n\nAHT20_TEMP\x10\xb3\x01\x12\x13\n\x0e\x41HT20_HUMIDITY\x10\xb4\x01\x12\x0f\n\nTVOC_INDEX\x10\xb5\x01\x42g\n\x14org.meshtastic.protoB\x11InterdeviceProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.interdevice_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.interdevice_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\021InterdeviceProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_MESSAGETYPE']._serialized_start=277
|
||||
_globals['_MESSAGETYPE']._serialized_end=490
|
||||
_globals['_SENSORDATA']._serialized_start=62
|
||||
_globals['_SENSORDATA']._serialized_end=177
|
||||
_globals['_INTERDEVICEMESSAGE']._serialized_start=179
|
||||
_globals['_INTERDEVICEMESSAGE']._serialized_end=274
|
||||
_MESSAGETYPE._serialized_start=277
|
||||
_MESSAGETYPE._serialized_end=490
|
||||
_SENSORDATA._serialized_start=62
|
||||
_SENSORDATA._serialized_end=177
|
||||
_INTERDEVICEMESSAGE._serialized_start=179
|
||||
_INTERDEVICEMESSAGE._serialized_end=274
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,105 +1,39 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
ACK: MessageType
|
||||
AHT20_HUMIDITY: MessageType
|
||||
AHT20_TEMP: MessageType
|
||||
BEEP_OFF: MessageType
|
||||
BEEP_ON: MessageType
|
||||
COLLECT_INTERVAL: MessageType
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
POWER_ON: MessageType
|
||||
SCD41_CO2: MessageType
|
||||
SCD41_HUMIDITY: MessageType
|
||||
SCD41_TEMP: MessageType
|
||||
SHUTDOWN: MessageType
|
||||
TVOC_INDEX: MessageType
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
class InterdeviceMessage(_message.Message):
|
||||
__slots__ = ["nmea", "sensor"]
|
||||
NMEA_FIELD_NUMBER: _ClassVar[int]
|
||||
SENSOR_FIELD_NUMBER: _ClassVar[int]
|
||||
nmea: str
|
||||
sensor: SensorData
|
||||
def __init__(self, nmea: _Optional[str] = ..., sensor: _Optional[_Union[SensorData, _Mapping]] = ...) -> None: ...
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class SensorData(_message.Message):
|
||||
__slots__ = ["float_value", "type", "uint32_value"]
|
||||
FLOAT_VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
UINT32_VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
float_value: float
|
||||
type: MessageType
|
||||
uint32_value: int
|
||||
def __init__(self, type: _Optional[_Union[MessageType, str]] = ..., float_value: _Optional[float] = ..., uint32_value: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class _MessageType:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _MessageTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_MessageType.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
ACK: _MessageType.ValueType # 0
|
||||
COLLECT_INTERVAL: _MessageType.ValueType # 160
|
||||
"""in ms"""
|
||||
BEEP_ON: _MessageType.ValueType # 161
|
||||
"""duration ms"""
|
||||
BEEP_OFF: _MessageType.ValueType # 162
|
||||
"""cancel prematurely"""
|
||||
SHUTDOWN: _MessageType.ValueType # 163
|
||||
POWER_ON: _MessageType.ValueType # 164
|
||||
SCD41_TEMP: _MessageType.ValueType # 176
|
||||
SCD41_HUMIDITY: _MessageType.ValueType # 177
|
||||
SCD41_CO2: _MessageType.ValueType # 178
|
||||
AHT20_TEMP: _MessageType.ValueType # 179
|
||||
AHT20_HUMIDITY: _MessageType.ValueType # 180
|
||||
TVOC_INDEX: _MessageType.ValueType # 181
|
||||
|
||||
class MessageType(_MessageType, metaclass=_MessageTypeEnumTypeWrapper):
|
||||
"""encapsulate up to 1k of NMEA string data"""
|
||||
|
||||
ACK: MessageType.ValueType # 0
|
||||
COLLECT_INTERVAL: MessageType.ValueType # 160
|
||||
"""in ms"""
|
||||
BEEP_ON: MessageType.ValueType # 161
|
||||
"""duration ms"""
|
||||
BEEP_OFF: MessageType.ValueType # 162
|
||||
"""cancel prematurely"""
|
||||
SHUTDOWN: MessageType.ValueType # 163
|
||||
POWER_ON: MessageType.ValueType # 164
|
||||
SCD41_TEMP: MessageType.ValueType # 176
|
||||
SCD41_HUMIDITY: MessageType.ValueType # 177
|
||||
SCD41_CO2: MessageType.ValueType # 178
|
||||
AHT20_TEMP: MessageType.ValueType # 179
|
||||
AHT20_HUMIDITY: MessageType.ValueType # 180
|
||||
TVOC_INDEX: MessageType.ValueType # 181
|
||||
global___MessageType = MessageType
|
||||
|
||||
@typing.final
|
||||
class SensorData(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
TYPE_FIELD_NUMBER: builtins.int
|
||||
FLOAT_VALUE_FIELD_NUMBER: builtins.int
|
||||
UINT32_VALUE_FIELD_NUMBER: builtins.int
|
||||
type: global___MessageType.ValueType
|
||||
"""The message type"""
|
||||
float_value: builtins.float
|
||||
uint32_value: builtins.int
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: global___MessageType.ValueType = ...,
|
||||
float_value: builtins.float = ...,
|
||||
uint32_value: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["data", b"data", "float_value", b"float_value", "uint32_value", b"uint32_value"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["data", b"data", "float_value", b"float_value", "type", b"type", "uint32_value", b"uint32_value"]) -> None: ...
|
||||
def WhichOneof(self, oneof_group: typing.Literal["data", b"data"]) -> typing.Literal["float_value", "uint32_value"] | None: ...
|
||||
|
||||
global___SensorData = SensorData
|
||||
|
||||
@typing.final
|
||||
class InterdeviceMessage(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
NMEA_FIELD_NUMBER: builtins.int
|
||||
SENSOR_FIELD_NUMBER: builtins.int
|
||||
nmea: builtins.str
|
||||
@property
|
||||
def sensor(self) -> global___SensorData: ...
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
nmea: builtins.str = ...,
|
||||
sensor: global___SensorData | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["data", b"data", "nmea", b"nmea", "sensor", b"sensor"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["data", b"data", "nmea", b"nmea", "sensor", b"sensor"]) -> None: ...
|
||||
def WhichOneof(self, oneof_group: typing.Literal["data", b"data"]) -> typing.Literal["nmea", "sensor"] | None: ...
|
||||
|
||||
global___InterdeviceMessage = InterdeviceMessage
|
||||
class MessageType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/localonly.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,16 +15,16 @@ from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config
|
||||
from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xf0\x07\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/localonly.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xfa\x03\n\x0bLocalConfig\x12\x38\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfig\x12<\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfig\x12\x36\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfig\x12:\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfig\x12:\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfig\x12\x34\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfig\x12>\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfig\x12\x0f\n\x07version\x18\x08 \x01(\r\x12<\n\x08security\x18\t \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfig\"\xcf\t\n\x11LocalModuleConfig\x12:\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfig\x12>\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfig\x12[\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfig\x12K\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfig\x12\x45\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfig\x12\x44\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfig\x12M\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfig\x12<\n\x05\x61udio\x18\t \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfig\x12O\n\x0fremote_hardware\x18\n \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfig\x12K\n\rneighbor_info\x18\x0b \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfig\x12Q\n\x10\x61mbient_lighting\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfig\x12Q\n\x10\x64\x65tection_sensor\x18\r \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig\x12\x46\n\npaxcounter\x18\x0e \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfig\x12L\n\rstatusmessage\x18\x0f \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfig\x12U\n\x12traffic_management\x18\x10 \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfig\x12\x38\n\x03tak\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.ModuleConfig.TAKConfig\x12\x0f\n\x07version\x18\x08 \x01(\rBe\n\x14org.meshtastic.protoB\x0fLocalOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.localonly_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.localonly_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\017LocalOnlyProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_LOCALCONFIG']._serialized_start=136
|
||||
_globals['_LOCALCONFIG']._serialized_end=642
|
||||
_globals['_LOCALMODULECONFIG']._serialized_start=645
|
||||
_globals['_LOCALMODULECONFIG']._serialized_end=1653
|
||||
_LOCALCONFIG._serialized_start=136
|
||||
_LOCALCONFIG._serialized_end=642
|
||||
_LOCALMODULECONFIG._serialized_start=645
|
||||
_LOCALMODULECONFIG._serialized_end=1876
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,228 +1,67 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from meshtastic.protobuf import config_pb2 as _config_pb2
|
||||
from meshtastic.protobuf import module_config_pb2 as _module_config_pb2
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import meshtastic.protobuf.config_pb2
|
||||
import meshtastic.protobuf.module_config_pb2
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class LocalConfig(_message.Message):
|
||||
__slots__ = ["bluetooth", "device", "display", "lora", "network", "position", "power", "security", "version"]
|
||||
BLUETOOTH_FIELD_NUMBER: _ClassVar[int]
|
||||
DEVICE_FIELD_NUMBER: _ClassVar[int]
|
||||
DISPLAY_FIELD_NUMBER: _ClassVar[int]
|
||||
LORA_FIELD_NUMBER: _ClassVar[int]
|
||||
NETWORK_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
POWER_FIELD_NUMBER: _ClassVar[int]
|
||||
SECURITY_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
bluetooth: _config_pb2.Config.BluetoothConfig
|
||||
device: _config_pb2.Config.DeviceConfig
|
||||
display: _config_pb2.Config.DisplayConfig
|
||||
lora: _config_pb2.Config.LoRaConfig
|
||||
network: _config_pb2.Config.NetworkConfig
|
||||
position: _config_pb2.Config.PositionConfig
|
||||
power: _config_pb2.Config.PowerConfig
|
||||
security: _config_pb2.Config.SecurityConfig
|
||||
version: int
|
||||
def __init__(self, device: _Optional[_Union[_config_pb2.Config.DeviceConfig, _Mapping]] = ..., position: _Optional[_Union[_config_pb2.Config.PositionConfig, _Mapping]] = ..., power: _Optional[_Union[_config_pb2.Config.PowerConfig, _Mapping]] = ..., network: _Optional[_Union[_config_pb2.Config.NetworkConfig, _Mapping]] = ..., display: _Optional[_Union[_config_pb2.Config.DisplayConfig, _Mapping]] = ..., lora: _Optional[_Union[_config_pb2.Config.LoRaConfig, _Mapping]] = ..., bluetooth: _Optional[_Union[_config_pb2.Config.BluetoothConfig, _Mapping]] = ..., version: _Optional[int] = ..., security: _Optional[_Union[_config_pb2.Config.SecurityConfig, _Mapping]] = ...) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class LocalConfig(google.protobuf.message.Message):
|
||||
"""
|
||||
Protobuf structures common to apponly.proto and deviceonly.proto
|
||||
This is never sent over the wire, only for local use
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
DEVICE_FIELD_NUMBER: builtins.int
|
||||
POSITION_FIELD_NUMBER: builtins.int
|
||||
POWER_FIELD_NUMBER: builtins.int
|
||||
NETWORK_FIELD_NUMBER: builtins.int
|
||||
DISPLAY_FIELD_NUMBER: builtins.int
|
||||
LORA_FIELD_NUMBER: builtins.int
|
||||
BLUETOOTH_FIELD_NUMBER: builtins.int
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
SECURITY_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code.
|
||||
"""
|
||||
@property
|
||||
def device(self) -> meshtastic.protobuf.config_pb2.Config.DeviceConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Device
|
||||
"""
|
||||
|
||||
@property
|
||||
def position(self) -> meshtastic.protobuf.config_pb2.Config.PositionConfig:
|
||||
"""
|
||||
The part of the config that is specific to the GPS Position
|
||||
"""
|
||||
|
||||
@property
|
||||
def power(self) -> meshtastic.protobuf.config_pb2.Config.PowerConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Power settings
|
||||
"""
|
||||
|
||||
@property
|
||||
def network(self) -> meshtastic.protobuf.config_pb2.Config.NetworkConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Wifi Settings
|
||||
"""
|
||||
|
||||
@property
|
||||
def display(self) -> meshtastic.protobuf.config_pb2.Config.DisplayConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Display
|
||||
"""
|
||||
|
||||
@property
|
||||
def lora(self) -> meshtastic.protobuf.config_pb2.Config.LoRaConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Lora Radio
|
||||
"""
|
||||
|
||||
@property
|
||||
def bluetooth(self) -> meshtastic.protobuf.config_pb2.Config.BluetoothConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Bluetooth settings
|
||||
"""
|
||||
|
||||
@property
|
||||
def security(self) -> meshtastic.protobuf.config_pb2.Config.SecurityConfig:
|
||||
"""
|
||||
The part of the config that is specific to Security settings
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
device: meshtastic.protobuf.config_pb2.Config.DeviceConfig | None = ...,
|
||||
position: meshtastic.protobuf.config_pb2.Config.PositionConfig | None = ...,
|
||||
power: meshtastic.protobuf.config_pb2.Config.PowerConfig | None = ...,
|
||||
network: meshtastic.protobuf.config_pb2.Config.NetworkConfig | None = ...,
|
||||
display: meshtastic.protobuf.config_pb2.Config.DisplayConfig | None = ...,
|
||||
lora: meshtastic.protobuf.config_pb2.Config.LoRaConfig | None = ...,
|
||||
bluetooth: meshtastic.protobuf.config_pb2.Config.BluetoothConfig | None = ...,
|
||||
version: builtins.int = ...,
|
||||
security: meshtastic.protobuf.config_pb2.Config.SecurityConfig | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "security", b"security"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["bluetooth", b"bluetooth", "device", b"device", "display", b"display", "lora", b"lora", "network", b"network", "position", b"position", "power", b"power", "security", b"security", "version", b"version"]) -> None: ...
|
||||
|
||||
global___LocalConfig = LocalConfig
|
||||
|
||||
@typing.final
|
||||
class LocalModuleConfig(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
MQTT_FIELD_NUMBER: builtins.int
|
||||
SERIAL_FIELD_NUMBER: builtins.int
|
||||
EXTERNAL_NOTIFICATION_FIELD_NUMBER: builtins.int
|
||||
STORE_FORWARD_FIELD_NUMBER: builtins.int
|
||||
RANGE_TEST_FIELD_NUMBER: builtins.int
|
||||
TELEMETRY_FIELD_NUMBER: builtins.int
|
||||
CANNED_MESSAGE_FIELD_NUMBER: builtins.int
|
||||
AUDIO_FIELD_NUMBER: builtins.int
|
||||
REMOTE_HARDWARE_FIELD_NUMBER: builtins.int
|
||||
NEIGHBOR_INFO_FIELD_NUMBER: builtins.int
|
||||
AMBIENT_LIGHTING_FIELD_NUMBER: builtins.int
|
||||
DETECTION_SENSOR_FIELD_NUMBER: builtins.int
|
||||
PAXCOUNTER_FIELD_NUMBER: builtins.int
|
||||
VERSION_FIELD_NUMBER: builtins.int
|
||||
version: builtins.int
|
||||
"""
|
||||
A version integer used to invalidate old save files when we make
|
||||
incompatible changes This integer is set at build time and is private to
|
||||
NodeDB.cpp in the device code.
|
||||
"""
|
||||
@property
|
||||
def mqtt(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.MQTTConfig:
|
||||
"""
|
||||
The part of the config that is specific to the MQTT module
|
||||
"""
|
||||
|
||||
@property
|
||||
def serial(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.SerialConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Serial module
|
||||
"""
|
||||
|
||||
@property
|
||||
def external_notification(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.ExternalNotificationConfig:
|
||||
"""
|
||||
The part of the config that is specific to the ExternalNotification module
|
||||
"""
|
||||
|
||||
@property
|
||||
def store_forward(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.StoreForwardConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Store & Forward module
|
||||
"""
|
||||
|
||||
@property
|
||||
def range_test(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.RangeTestConfig:
|
||||
"""
|
||||
The part of the config that is specific to the RangeTest module
|
||||
"""
|
||||
|
||||
@property
|
||||
def telemetry(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.TelemetryConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Telemetry module
|
||||
"""
|
||||
|
||||
@property
|
||||
def canned_message(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.CannedMessageConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Canned Message module
|
||||
"""
|
||||
|
||||
@property
|
||||
def audio(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.AudioConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Audio module
|
||||
"""
|
||||
|
||||
@property
|
||||
def remote_hardware(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.RemoteHardwareConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Remote Hardware module
|
||||
"""
|
||||
|
||||
@property
|
||||
def neighbor_info(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.NeighborInfoConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Neighbor Info module
|
||||
"""
|
||||
|
||||
@property
|
||||
def ambient_lighting(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.AmbientLightingConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Ambient Lighting module
|
||||
"""
|
||||
|
||||
@property
|
||||
def detection_sensor(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.DetectionSensorConfig:
|
||||
"""
|
||||
The part of the config that is specific to the Detection Sensor module
|
||||
"""
|
||||
|
||||
@property
|
||||
def paxcounter(self) -> meshtastic.protobuf.module_config_pb2.ModuleConfig.PaxcounterConfig:
|
||||
"""
|
||||
Paxcounter Config
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
mqtt: meshtastic.protobuf.module_config_pb2.ModuleConfig.MQTTConfig | None = ...,
|
||||
serial: meshtastic.protobuf.module_config_pb2.ModuleConfig.SerialConfig | None = ...,
|
||||
external_notification: meshtastic.protobuf.module_config_pb2.ModuleConfig.ExternalNotificationConfig | None = ...,
|
||||
store_forward: meshtastic.protobuf.module_config_pb2.ModuleConfig.StoreForwardConfig | None = ...,
|
||||
range_test: meshtastic.protobuf.module_config_pb2.ModuleConfig.RangeTestConfig | None = ...,
|
||||
telemetry: meshtastic.protobuf.module_config_pb2.ModuleConfig.TelemetryConfig | None = ...,
|
||||
canned_message: meshtastic.protobuf.module_config_pb2.ModuleConfig.CannedMessageConfig | None = ...,
|
||||
audio: meshtastic.protobuf.module_config_pb2.ModuleConfig.AudioConfig | None = ...,
|
||||
remote_hardware: meshtastic.protobuf.module_config_pb2.ModuleConfig.RemoteHardwareConfig | None = ...,
|
||||
neighbor_info: meshtastic.protobuf.module_config_pb2.ModuleConfig.NeighborInfoConfig | None = ...,
|
||||
ambient_lighting: meshtastic.protobuf.module_config_pb2.ModuleConfig.AmbientLightingConfig | None = ...,
|
||||
detection_sensor: meshtastic.protobuf.module_config_pb2.ModuleConfig.DetectionSensorConfig | None = ...,
|
||||
paxcounter: meshtastic.protobuf.module_config_pb2.ModuleConfig.PaxcounterConfig | None = ...,
|
||||
version: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["ambient_lighting", b"ambient_lighting", "audio", b"audio", "canned_message", b"canned_message", "detection_sensor", b"detection_sensor", "external_notification", b"external_notification", "mqtt", b"mqtt", "neighbor_info", b"neighbor_info", "paxcounter", b"paxcounter", "range_test", b"range_test", "remote_hardware", b"remote_hardware", "serial", b"serial", "store_forward", b"store_forward", "telemetry", b"telemetry", "version", b"version"]) -> None: ...
|
||||
|
||||
global___LocalModuleConfig = LocalModuleConfig
|
||||
class LocalModuleConfig(_message.Message):
|
||||
__slots__ = ["ambient_lighting", "audio", "canned_message", "detection_sensor", "external_notification", "mqtt", "neighbor_info", "paxcounter", "range_test", "remote_hardware", "serial", "statusmessage", "store_forward", "tak", "telemetry", "traffic_management", "version"]
|
||||
AMBIENT_LIGHTING_FIELD_NUMBER: _ClassVar[int]
|
||||
AUDIO_FIELD_NUMBER: _ClassVar[int]
|
||||
CANNED_MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
DETECTION_SENSOR_FIELD_NUMBER: _ClassVar[int]
|
||||
EXTERNAL_NOTIFICATION_FIELD_NUMBER: _ClassVar[int]
|
||||
MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
NEIGHBOR_INFO_FIELD_NUMBER: _ClassVar[int]
|
||||
PAXCOUNTER_FIELD_NUMBER: _ClassVar[int]
|
||||
RANGE_TEST_FIELD_NUMBER: _ClassVar[int]
|
||||
REMOTE_HARDWARE_FIELD_NUMBER: _ClassVar[int]
|
||||
SERIAL_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUSMESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
STORE_FORWARD_FIELD_NUMBER: _ClassVar[int]
|
||||
TAK_FIELD_NUMBER: _ClassVar[int]
|
||||
TELEMETRY_FIELD_NUMBER: _ClassVar[int]
|
||||
TRAFFIC_MANAGEMENT_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
ambient_lighting: _module_config_pb2.ModuleConfig.AmbientLightingConfig
|
||||
audio: _module_config_pb2.ModuleConfig.AudioConfig
|
||||
canned_message: _module_config_pb2.ModuleConfig.CannedMessageConfig
|
||||
detection_sensor: _module_config_pb2.ModuleConfig.DetectionSensorConfig
|
||||
external_notification: _module_config_pb2.ModuleConfig.ExternalNotificationConfig
|
||||
mqtt: _module_config_pb2.ModuleConfig.MQTTConfig
|
||||
neighbor_info: _module_config_pb2.ModuleConfig.NeighborInfoConfig
|
||||
paxcounter: _module_config_pb2.ModuleConfig.PaxcounterConfig
|
||||
range_test: _module_config_pb2.ModuleConfig.RangeTestConfig
|
||||
remote_hardware: _module_config_pb2.ModuleConfig.RemoteHardwareConfig
|
||||
serial: _module_config_pb2.ModuleConfig.SerialConfig
|
||||
statusmessage: _module_config_pb2.ModuleConfig.StatusMessageConfig
|
||||
store_forward: _module_config_pb2.ModuleConfig.StoreForwardConfig
|
||||
tak: _module_config_pb2.ModuleConfig.TAKConfig
|
||||
telemetry: _module_config_pb2.ModuleConfig.TelemetryConfig
|
||||
traffic_management: _module_config_pb2.ModuleConfig.TrafficManagementConfig
|
||||
version: int
|
||||
def __init__(self, mqtt: _Optional[_Union[_module_config_pb2.ModuleConfig.MQTTConfig, _Mapping]] = ..., serial: _Optional[_Union[_module_config_pb2.ModuleConfig.SerialConfig, _Mapping]] = ..., external_notification: _Optional[_Union[_module_config_pb2.ModuleConfig.ExternalNotificationConfig, _Mapping]] = ..., store_forward: _Optional[_Union[_module_config_pb2.ModuleConfig.StoreForwardConfig, _Mapping]] = ..., range_test: _Optional[_Union[_module_config_pb2.ModuleConfig.RangeTestConfig, _Mapping]] = ..., telemetry: _Optional[_Union[_module_config_pb2.ModuleConfig.TelemetryConfig, _Mapping]] = ..., canned_message: _Optional[_Union[_module_config_pb2.ModuleConfig.CannedMessageConfig, _Mapping]] = ..., audio: _Optional[_Union[_module_config_pb2.ModuleConfig.AudioConfig, _Mapping]] = ..., remote_hardware: _Optional[_Union[_module_config_pb2.ModuleConfig.RemoteHardwareConfig, _Mapping]] = ..., neighbor_info: _Optional[_Union[_module_config_pb2.ModuleConfig.NeighborInfoConfig, _Mapping]] = ..., ambient_lighting: _Optional[_Union[_module_config_pb2.ModuleConfig.AmbientLightingConfig, _Mapping]] = ..., detection_sensor: _Optional[_Union[_module_config_pb2.ModuleConfig.DetectionSensorConfig, _Mapping]] = ..., paxcounter: _Optional[_Union[_module_config_pb2.ModuleConfig.PaxcounterConfig, _Mapping]] = ..., statusmessage: _Optional[_Union[_module_config_pb2.ModuleConfig.StatusMessageConfig, _Mapping]] = ..., traffic_management: _Optional[_Union[_module_config_pb2.ModuleConfig.TrafficManagementConfig, _Mapping]] = ..., tak: _Optional[_Union[_module_config_pb2.ModuleConfig.TAKConfig, _Mapping]] = ..., version: _Optional[int] = ...) -> None: ...
|
||||
|
||||
+105
-91
File diff suppressed because one or more lines are too long
+875
-3796
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/mqtt.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -17,14 +17,14 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mqtt.proto\x12\x13meshtastic.protobuf\x1a meshtastic/protobuf/config.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"j\n\x0fServiceEnvelope\x12/\n\x06packet\x18\x01 \x01(\x0b\x32\x1f.meshtastic.protobuf.MeshPacket\x12\x12\n\nchannel_id\x18\x02 \x01(\t\x12\x12\n\ngateway_id\x18\x03 \x01(\t\"\x83\x04\n\tMapReport\x12\x11\n\tlong_name\x18\x01 \x01(\t\x12\x12\n\nshort_name\x18\x02 \x01(\t\x12;\n\x04role\x18\x03 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x34\n\x08hw_model\x18\x04 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x18\n\x10\x66irmware_version\x18\x05 \x01(\t\x12\x41\n\x06region\x18\x06 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12H\n\x0cmodem_preset\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPreset\x12\x1b\n\x13has_default_channel\x18\x08 \x01(\x08\x12\x12\n\nlatitude_i\x18\t \x01(\x0f\x12\x13\n\x0blongitude_i\x18\n \x01(\x0f\x12\x10\n\x08\x61ltitude\x18\x0b \x01(\x05\x12\x1a\n\x12position_precision\x18\x0c \x01(\r\x12\x1e\n\x16num_online_local_nodes\x18\r \x01(\r\x12!\n\x19has_opted_report_location\x18\x0e \x01(\x08\x42`\n\x14org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mqtt_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mqtt_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nMQTTProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_SERVICEENVELOPE']._serialized_start=121
|
||||
_globals['_SERVICEENVELOPE']._serialized_end=227
|
||||
_globals['_MAPREPORT']._serialized_start=230
|
||||
_globals['_MAPREPORT']._serialized_end=745
|
||||
_SERVICEENVELOPE._serialized_start=121
|
||||
_SERVICEENVELOPE._serialized_end=227
|
||||
_MAPREPORT._serialized_start=230
|
||||
_MAPREPORT._serialized_end=745
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,155 +1,49 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from meshtastic.protobuf import config_pb2 as _config_pb2
|
||||
from meshtastic.protobuf import mesh_pb2 as _mesh_pb2
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import meshtastic.protobuf.config_pb2
|
||||
import meshtastic.protobuf.mesh_pb2
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class MapReport(_message.Message):
|
||||
__slots__ = ["altitude", "firmware_version", "has_default_channel", "has_opted_report_location", "hw_model", "latitude_i", "long_name", "longitude_i", "modem_preset", "num_online_local_nodes", "position_precision", "region", "role", "short_name"]
|
||||
ALTITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
FIRMWARE_VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
HAS_DEFAULT_CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
HAS_OPTED_REPORT_LOCATION_FIELD_NUMBER: _ClassVar[int]
|
||||
HW_MODEL_FIELD_NUMBER: _ClassVar[int]
|
||||
LATITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
MODEM_PRESET_FIELD_NUMBER: _ClassVar[int]
|
||||
NUM_ONLINE_LOCAL_NODES_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_PRECISION_FIELD_NUMBER: _ClassVar[int]
|
||||
REGION_FIELD_NUMBER: _ClassVar[int]
|
||||
ROLE_FIELD_NUMBER: _ClassVar[int]
|
||||
SHORT_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
altitude: int
|
||||
firmware_version: str
|
||||
has_default_channel: bool
|
||||
has_opted_report_location: bool
|
||||
hw_model: _mesh_pb2.HardwareModel
|
||||
latitude_i: int
|
||||
long_name: str
|
||||
longitude_i: int
|
||||
modem_preset: _config_pb2.Config.LoRaConfig.ModemPreset
|
||||
num_online_local_nodes: int
|
||||
position_precision: int
|
||||
region: _config_pb2.Config.LoRaConfig.RegionCode
|
||||
role: _config_pb2.Config.DeviceConfig.Role
|
||||
short_name: str
|
||||
def __init__(self, long_name: _Optional[str] = ..., short_name: _Optional[str] = ..., role: _Optional[_Union[_config_pb2.Config.DeviceConfig.Role, str]] = ..., hw_model: _Optional[_Union[_mesh_pb2.HardwareModel, str]] = ..., firmware_version: _Optional[str] = ..., region: _Optional[_Union[_config_pb2.Config.LoRaConfig.RegionCode, str]] = ..., modem_preset: _Optional[_Union[_config_pb2.Config.LoRaConfig.ModemPreset, str]] = ..., has_default_channel: bool = ..., latitude_i: _Optional[int] = ..., longitude_i: _Optional[int] = ..., altitude: _Optional[int] = ..., position_precision: _Optional[int] = ..., num_online_local_nodes: _Optional[int] = ..., has_opted_report_location: bool = ...) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class ServiceEnvelope(google.protobuf.message.Message):
|
||||
"""
|
||||
This message wraps a MeshPacket with extra metadata about the sender and how it arrived.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
PACKET_FIELD_NUMBER: builtins.int
|
||||
CHANNEL_ID_FIELD_NUMBER: builtins.int
|
||||
GATEWAY_ID_FIELD_NUMBER: builtins.int
|
||||
channel_id: builtins.str
|
||||
"""
|
||||
The global channel ID it was sent on
|
||||
"""
|
||||
gateway_id: builtins.str
|
||||
"""
|
||||
The sending gateway node ID. Can we use this to authenticate/prevent fake
|
||||
nodeid impersonation for senders? - i.e. use gateway/mesh id (which is authenticated) + local node id as
|
||||
the globally trusted nodenum
|
||||
"""
|
||||
@property
|
||||
def packet(self) -> meshtastic.protobuf.mesh_pb2.MeshPacket:
|
||||
"""
|
||||
The (probably encrypted) packet
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
packet: meshtastic.protobuf.mesh_pb2.MeshPacket | None = ...,
|
||||
channel_id: builtins.str = ...,
|
||||
gateway_id: builtins.str = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["packet", b"packet"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["channel_id", b"channel_id", "gateway_id", b"gateway_id", "packet", b"packet"]) -> None: ...
|
||||
|
||||
global___ServiceEnvelope = ServiceEnvelope
|
||||
|
||||
@typing.final
|
||||
class MapReport(google.protobuf.message.Message):
|
||||
"""
|
||||
Information about a node intended to be reported unencrypted to a map using MQTT.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
LONG_NAME_FIELD_NUMBER: builtins.int
|
||||
SHORT_NAME_FIELD_NUMBER: builtins.int
|
||||
ROLE_FIELD_NUMBER: builtins.int
|
||||
HW_MODEL_FIELD_NUMBER: builtins.int
|
||||
FIRMWARE_VERSION_FIELD_NUMBER: builtins.int
|
||||
REGION_FIELD_NUMBER: builtins.int
|
||||
MODEM_PRESET_FIELD_NUMBER: builtins.int
|
||||
HAS_DEFAULT_CHANNEL_FIELD_NUMBER: builtins.int
|
||||
LATITUDE_I_FIELD_NUMBER: builtins.int
|
||||
LONGITUDE_I_FIELD_NUMBER: builtins.int
|
||||
ALTITUDE_FIELD_NUMBER: builtins.int
|
||||
POSITION_PRECISION_FIELD_NUMBER: builtins.int
|
||||
NUM_ONLINE_LOCAL_NODES_FIELD_NUMBER: builtins.int
|
||||
HAS_OPTED_REPORT_LOCATION_FIELD_NUMBER: builtins.int
|
||||
long_name: builtins.str
|
||||
"""
|
||||
A full name for this user, i.e. "Kevin Hester"
|
||||
"""
|
||||
short_name: builtins.str
|
||||
"""
|
||||
A VERY short name, ideally two characters.
|
||||
Suitable for a tiny OLED screen
|
||||
"""
|
||||
role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType
|
||||
"""
|
||||
Role of the node that applies specific settings for a particular use-case
|
||||
"""
|
||||
hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType
|
||||
"""
|
||||
Hardware model of the node, i.e. T-Beam, Heltec V3, etc...
|
||||
"""
|
||||
firmware_version: builtins.str
|
||||
"""
|
||||
Device firmware version string
|
||||
"""
|
||||
region: meshtastic.protobuf.config_pb2.Config.LoRaConfig.RegionCode.ValueType
|
||||
"""
|
||||
The region code for the radio (US, CN, EU433, etc...)
|
||||
"""
|
||||
modem_preset: meshtastic.protobuf.config_pb2.Config.LoRaConfig.ModemPreset.ValueType
|
||||
"""
|
||||
Modem preset used by the radio (LongFast, MediumSlow, etc...)
|
||||
"""
|
||||
has_default_channel: builtins.bool
|
||||
"""
|
||||
Whether the node has a channel with default PSK and name (LongFast, MediumSlow, etc...)
|
||||
and it uses the default frequency slot given the region and modem preset.
|
||||
"""
|
||||
latitude_i: builtins.int
|
||||
"""
|
||||
Latitude: multiply by 1e-7 to get degrees in floating point
|
||||
"""
|
||||
longitude_i: builtins.int
|
||||
"""
|
||||
Longitude: multiply by 1e-7 to get degrees in floating point
|
||||
"""
|
||||
altitude: builtins.int
|
||||
"""
|
||||
Altitude in meters above MSL
|
||||
"""
|
||||
position_precision: builtins.int
|
||||
"""
|
||||
Indicates the bits of precision for latitude and longitude set by the sending node
|
||||
"""
|
||||
num_online_local_nodes: builtins.int
|
||||
"""
|
||||
Number of online nodes (heard in the last 2 hours) this node has in its list that were received locally (not via MQTT)
|
||||
"""
|
||||
has_opted_report_location: builtins.bool
|
||||
"""
|
||||
User has opted in to share their location (map report) with the mqtt server
|
||||
Controlled by map_report.should_report_location
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
long_name: builtins.str = ...,
|
||||
short_name: builtins.str = ...,
|
||||
role: meshtastic.protobuf.config_pb2.Config.DeviceConfig.Role.ValueType = ...,
|
||||
hw_model: meshtastic.protobuf.mesh_pb2.HardwareModel.ValueType = ...,
|
||||
firmware_version: builtins.str = ...,
|
||||
region: meshtastic.protobuf.config_pb2.Config.LoRaConfig.RegionCode.ValueType = ...,
|
||||
modem_preset: meshtastic.protobuf.config_pb2.Config.LoRaConfig.ModemPreset.ValueType = ...,
|
||||
has_default_channel: builtins.bool = ...,
|
||||
latitude_i: builtins.int = ...,
|
||||
longitude_i: builtins.int = ...,
|
||||
altitude: builtins.int = ...,
|
||||
position_precision: builtins.int = ...,
|
||||
num_online_local_nodes: builtins.int = ...,
|
||||
has_opted_report_location: builtins.bool = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["altitude", b"altitude", "firmware_version", b"firmware_version", "has_default_channel", b"has_default_channel", "has_opted_report_location", b"has_opted_report_location", "hw_model", b"hw_model", "latitude_i", b"latitude_i", "long_name", b"long_name", "longitude_i", b"longitude_i", "modem_preset", b"modem_preset", "num_online_local_nodes", b"num_online_local_nodes", "position_precision", b"position_precision", "region", b"region", "role", b"role", "short_name", b"short_name"]) -> None: ...
|
||||
|
||||
global___MapReport = MapReport
|
||||
class ServiceEnvelope(_message.Message):
|
||||
__slots__ = ["channel_id", "gateway_id", "packet"]
|
||||
CHANNEL_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
GATEWAY_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
PACKET_FIELD_NUMBER: _ClassVar[int]
|
||||
channel_id: str
|
||||
gateway_id: str
|
||||
packet: _mesh_pb2.MeshPacket
|
||||
def __init__(self, packet: _Optional[_Union[_mesh_pb2.MeshPacket, _Mapping]] = ..., channel_id: _Optional[str] = ..., gateway_id: _Optional[str] = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/nanopb.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -16,20 +16,24 @@ from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/nanopb.proto\x1a google/protobuf/descriptor.proto\"\xa4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB>\n\x18\x66i.kapsi.koti.jpa.nanopbZ\"github.com/meshtastic/go/generated')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.nanopb_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.nanopb_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt)
|
||||
google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt)
|
||||
google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt)
|
||||
google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb)
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\030fi.kapsi.koti.jpa.nanopbZ\"github.com/meshtastic/go/generated'
|
||||
_globals['_FIELDTYPE']._serialized_start=1005
|
||||
_globals['_FIELDTYPE']._serialized_end=1110
|
||||
_globals['_INTSIZE']._serialized_start=1112
|
||||
_globals['_INTSIZE']._serialized_end=1180
|
||||
_globals['_TYPENAMEMANGLING']._serialized_start=1182
|
||||
_globals['_TYPENAMEMANGLING']._serialized_end=1272
|
||||
_globals['_DESCRIPTORSIZE']._serialized_start=1274
|
||||
_globals['_DESCRIPTORSIZE']._serialized_end=1343
|
||||
_globals['_NANOPBOPTIONS']._serialized_start=71
|
||||
_globals['_NANOPBOPTIONS']._serialized_end=1003
|
||||
_FIELDTYPE._serialized_start=1005
|
||||
_FIELDTYPE._serialized_end=1110
|
||||
_INTSIZE._serialized_start=1112
|
||||
_INTSIZE._serialized_end=1180
|
||||
_TYPENAMEMANGLING._serialized_start=1182
|
||||
_TYPENAMEMANGLING._serialized_end=1272
|
||||
_DESCRIPTORSIZE._serialized_start=1274
|
||||
_DESCRIPTORSIZE._serialized_end=1343
|
||||
_NANOPBOPTIONS._serialized_start=71
|
||||
_NANOPBOPTIONS._serialized_end=1003
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
+104
-318
@@ -1,324 +1,110 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
Custom options for defining:
|
||||
- Maximum size of string/bytes
|
||||
- Maximum number of elements in array
|
||||
from google.protobuf import descriptor_pb2 as _descriptor_pb2
|
||||
from google.protobuf.internal import containers as _containers
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Iterable as _Iterable, Optional as _Optional, Union as _Union
|
||||
|
||||
These are used by nanopb to generate statically allocable structures
|
||||
for memory-limited environments.
|
||||
"""
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
DS_1: DescriptorSize
|
||||
DS_2: DescriptorSize
|
||||
DS_4: DescriptorSize
|
||||
DS_8: DescriptorSize
|
||||
DS_AUTO: DescriptorSize
|
||||
FT_CALLBACK: FieldType
|
||||
FT_DEFAULT: FieldType
|
||||
FT_IGNORE: FieldType
|
||||
FT_INLINE: FieldType
|
||||
FT_POINTER: FieldType
|
||||
FT_STATIC: FieldType
|
||||
IS_16: IntSize
|
||||
IS_32: IntSize
|
||||
IS_64: IntSize
|
||||
IS_8: IntSize
|
||||
IS_DEFAULT: IntSize
|
||||
M_FLATTEN: TypenameMangling
|
||||
M_NONE: TypenameMangling
|
||||
M_PACKAGE_INITIALS: TypenameMangling
|
||||
M_STRIP_PACKAGE: TypenameMangling
|
||||
NANOPB_ENUMOPT_FIELD_NUMBER: _ClassVar[int]
|
||||
NANOPB_FIELD_NUMBER: _ClassVar[int]
|
||||
NANOPB_FILEOPT_FIELD_NUMBER: _ClassVar[int]
|
||||
NANOPB_MSGOPT_FIELD_NUMBER: _ClassVar[int]
|
||||
nanopb: _descriptor.FieldDescriptor
|
||||
nanopb_enumopt: _descriptor.FieldDescriptor
|
||||
nanopb_fileopt: _descriptor.FieldDescriptor
|
||||
nanopb_msgopt: _descriptor.FieldDescriptor
|
||||
|
||||
import builtins
|
||||
import collections.abc
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.descriptor_pb2
|
||||
import google.protobuf.internal.containers
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.internal.extension_dict
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
class NanoPBOptions(_message.Message):
|
||||
__slots__ = ["anonymous_oneof", "callback_datatype", "callback_function", "default_has", "descriptorsize", "enum_to_string", "exclude", "fallback_type", "fixed_count", "fixed_length", "include", "int_size", "long_names", "mangle_names", "max_count", "max_length", "max_size", "msgid", "no_unions", "package", "packed_enum", "packed_struct", "proto3", "proto3_singular_msgs", "skip_message", "sort_by_tag", "submsg_callback", "type", "type_override"]
|
||||
ANONYMOUS_ONEOF_FIELD_NUMBER: _ClassVar[int]
|
||||
CALLBACK_DATATYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
CALLBACK_FUNCTION_FIELD_NUMBER: _ClassVar[int]
|
||||
DEFAULT_HAS_FIELD_NUMBER: _ClassVar[int]
|
||||
DESCRIPTORSIZE_FIELD_NUMBER: _ClassVar[int]
|
||||
ENUM_TO_STRING_FIELD_NUMBER: _ClassVar[int]
|
||||
EXCLUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
FALLBACK_TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
FIXED_COUNT_FIELD_NUMBER: _ClassVar[int]
|
||||
FIXED_LENGTH_FIELD_NUMBER: _ClassVar[int]
|
||||
INCLUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
INT_SIZE_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAMES_FIELD_NUMBER: _ClassVar[int]
|
||||
MANGLE_NAMES_FIELD_NUMBER: _ClassVar[int]
|
||||
MAX_COUNT_FIELD_NUMBER: _ClassVar[int]
|
||||
MAX_LENGTH_FIELD_NUMBER: _ClassVar[int]
|
||||
MAX_SIZE_FIELD_NUMBER: _ClassVar[int]
|
||||
MSGID_FIELD_NUMBER: _ClassVar[int]
|
||||
NO_UNIONS_FIELD_NUMBER: _ClassVar[int]
|
||||
PACKAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
PACKED_ENUM_FIELD_NUMBER: _ClassVar[int]
|
||||
PACKED_STRUCT_FIELD_NUMBER: _ClassVar[int]
|
||||
PROTO3_FIELD_NUMBER: _ClassVar[int]
|
||||
PROTO3_SINGULAR_MSGS_FIELD_NUMBER: _ClassVar[int]
|
||||
SKIP_MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
SORT_BY_TAG_FIELD_NUMBER: _ClassVar[int]
|
||||
SUBMSG_CALLBACK_FIELD_NUMBER: _ClassVar[int]
|
||||
TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
TYPE_OVERRIDE_FIELD_NUMBER: _ClassVar[int]
|
||||
anonymous_oneof: bool
|
||||
callback_datatype: str
|
||||
callback_function: str
|
||||
default_has: bool
|
||||
descriptorsize: DescriptorSize
|
||||
enum_to_string: bool
|
||||
exclude: _containers.RepeatedScalarFieldContainer[str]
|
||||
fallback_type: FieldType
|
||||
fixed_count: bool
|
||||
fixed_length: bool
|
||||
include: _containers.RepeatedScalarFieldContainer[str]
|
||||
int_size: IntSize
|
||||
long_names: bool
|
||||
mangle_names: TypenameMangling
|
||||
max_count: int
|
||||
max_length: int
|
||||
max_size: int
|
||||
msgid: int
|
||||
no_unions: bool
|
||||
package: str
|
||||
packed_enum: bool
|
||||
packed_struct: bool
|
||||
proto3: bool
|
||||
proto3_singular_msgs: bool
|
||||
skip_message: bool
|
||||
sort_by_tag: bool
|
||||
submsg_callback: bool
|
||||
type: FieldType
|
||||
type_override: _descriptor_pb2.FieldDescriptorProto.Type
|
||||
def __init__(self, max_size: _Optional[int] = ..., max_length: _Optional[int] = ..., max_count: _Optional[int] = ..., int_size: _Optional[_Union[IntSize, str]] = ..., type: _Optional[_Union[FieldType, str]] = ..., long_names: bool = ..., packed_struct: bool = ..., packed_enum: bool = ..., skip_message: bool = ..., no_unions: bool = ..., msgid: _Optional[int] = ..., anonymous_oneof: bool = ..., proto3: bool = ..., proto3_singular_msgs: bool = ..., enum_to_string: bool = ..., fixed_length: bool = ..., fixed_count: bool = ..., submsg_callback: bool = ..., mangle_names: _Optional[_Union[TypenameMangling, str]] = ..., callback_datatype: _Optional[str] = ..., callback_function: _Optional[str] = ..., descriptorsize: _Optional[_Union[DescriptorSize, str]] = ..., default_has: bool = ..., include: _Optional[_Iterable[str]] = ..., exclude: _Optional[_Iterable[str]] = ..., package: _Optional[str] = ..., type_override: _Optional[_Union[_descriptor_pb2.FieldDescriptorProto.Type, str]] = ..., sort_by_tag: bool = ..., fallback_type: _Optional[_Union[FieldType, str]] = ...) -> None: ...
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
class FieldType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
class IntSize(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class _FieldType:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
class TypenameMangling(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class _FieldTypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FieldType.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
FT_DEFAULT: _FieldType.ValueType # 0
|
||||
"""Automatically decide field type, generate static field if possible."""
|
||||
FT_CALLBACK: _FieldType.ValueType # 1
|
||||
"""Always generate a callback field."""
|
||||
FT_POINTER: _FieldType.ValueType # 4
|
||||
"""Always generate a dynamically allocated field."""
|
||||
FT_STATIC: _FieldType.ValueType # 2
|
||||
"""Generate a static field or raise an exception if not possible."""
|
||||
FT_IGNORE: _FieldType.ValueType # 3
|
||||
"""Ignore the field completely."""
|
||||
FT_INLINE: _FieldType.ValueType # 5
|
||||
"""Legacy option, use the separate 'fixed_length' option instead"""
|
||||
|
||||
class FieldType(_FieldType, metaclass=_FieldTypeEnumTypeWrapper): ...
|
||||
|
||||
FT_DEFAULT: FieldType.ValueType # 0
|
||||
"""Automatically decide field type, generate static field if possible."""
|
||||
FT_CALLBACK: FieldType.ValueType # 1
|
||||
"""Always generate a callback field."""
|
||||
FT_POINTER: FieldType.ValueType # 4
|
||||
"""Always generate a dynamically allocated field."""
|
||||
FT_STATIC: FieldType.ValueType # 2
|
||||
"""Generate a static field or raise an exception if not possible."""
|
||||
FT_IGNORE: FieldType.ValueType # 3
|
||||
"""Ignore the field completely."""
|
||||
FT_INLINE: FieldType.ValueType # 5
|
||||
"""Legacy option, use the separate 'fixed_length' option instead"""
|
||||
global___FieldType = FieldType
|
||||
|
||||
class _IntSize:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _IntSizeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_IntSize.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
IS_DEFAULT: _IntSize.ValueType # 0
|
||||
"""Default, 32/64bit based on type in .proto"""
|
||||
IS_8: _IntSize.ValueType # 8
|
||||
IS_16: _IntSize.ValueType # 16
|
||||
IS_32: _IntSize.ValueType # 32
|
||||
IS_64: _IntSize.ValueType # 64
|
||||
|
||||
class IntSize(_IntSize, metaclass=_IntSizeEnumTypeWrapper): ...
|
||||
|
||||
IS_DEFAULT: IntSize.ValueType # 0
|
||||
"""Default, 32/64bit based on type in .proto"""
|
||||
IS_8: IntSize.ValueType # 8
|
||||
IS_16: IntSize.ValueType # 16
|
||||
IS_32: IntSize.ValueType # 32
|
||||
IS_64: IntSize.ValueType # 64
|
||||
global___IntSize = IntSize
|
||||
|
||||
class _TypenameMangling:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _TypenameManglingEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TypenameMangling.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
M_NONE: _TypenameMangling.ValueType # 0
|
||||
"""Default, no typename mangling"""
|
||||
M_STRIP_PACKAGE: _TypenameMangling.ValueType # 1
|
||||
"""Strip current package name"""
|
||||
M_FLATTEN: _TypenameMangling.ValueType # 2
|
||||
"""Only use last path component"""
|
||||
M_PACKAGE_INITIALS: _TypenameMangling.ValueType # 3
|
||||
"""Replace the package name by the initials"""
|
||||
|
||||
class TypenameMangling(_TypenameMangling, metaclass=_TypenameManglingEnumTypeWrapper): ...
|
||||
|
||||
M_NONE: TypenameMangling.ValueType # 0
|
||||
"""Default, no typename mangling"""
|
||||
M_STRIP_PACKAGE: TypenameMangling.ValueType # 1
|
||||
"""Strip current package name"""
|
||||
M_FLATTEN: TypenameMangling.ValueType # 2
|
||||
"""Only use last path component"""
|
||||
M_PACKAGE_INITIALS: TypenameMangling.ValueType # 3
|
||||
"""Replace the package name by the initials"""
|
||||
global___TypenameMangling = TypenameMangling
|
||||
|
||||
class _DescriptorSize:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _DescriptorSizeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_DescriptorSize.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
DS_AUTO: _DescriptorSize.ValueType # 0
|
||||
"""Select minimal size based on field type"""
|
||||
DS_1: _DescriptorSize.ValueType # 1
|
||||
"""1 word; up to 15 byte fields, no arrays"""
|
||||
DS_2: _DescriptorSize.ValueType # 2
|
||||
"""2 words; up to 4095 byte fields, 4095 entry arrays"""
|
||||
DS_4: _DescriptorSize.ValueType # 4
|
||||
"""4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays"""
|
||||
DS_8: _DescriptorSize.ValueType # 8
|
||||
"""8 words; up to 2^32-1 entry arrays"""
|
||||
|
||||
class DescriptorSize(_DescriptorSize, metaclass=_DescriptorSizeEnumTypeWrapper): ...
|
||||
|
||||
DS_AUTO: DescriptorSize.ValueType # 0
|
||||
"""Select minimal size based on field type"""
|
||||
DS_1: DescriptorSize.ValueType # 1
|
||||
"""1 word; up to 15 byte fields, no arrays"""
|
||||
DS_2: DescriptorSize.ValueType # 2
|
||||
"""2 words; up to 4095 byte fields, 4095 entry arrays"""
|
||||
DS_4: DescriptorSize.ValueType # 4
|
||||
"""4 words; up to 2^32-1 byte fields, 2^16-1 entry arrays"""
|
||||
DS_8: DescriptorSize.ValueType # 8
|
||||
"""8 words; up to 2^32-1 entry arrays"""
|
||||
global___DescriptorSize = DescriptorSize
|
||||
|
||||
@typing.final
|
||||
class NanoPBOptions(google.protobuf.message.Message):
|
||||
"""This is the inner options message, which basically defines options for
|
||||
a field. When it is used in message or file scope, it applies to all
|
||||
fields.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
MAX_SIZE_FIELD_NUMBER: builtins.int
|
||||
MAX_LENGTH_FIELD_NUMBER: builtins.int
|
||||
MAX_COUNT_FIELD_NUMBER: builtins.int
|
||||
INT_SIZE_FIELD_NUMBER: builtins.int
|
||||
TYPE_FIELD_NUMBER: builtins.int
|
||||
LONG_NAMES_FIELD_NUMBER: builtins.int
|
||||
PACKED_STRUCT_FIELD_NUMBER: builtins.int
|
||||
PACKED_ENUM_FIELD_NUMBER: builtins.int
|
||||
SKIP_MESSAGE_FIELD_NUMBER: builtins.int
|
||||
NO_UNIONS_FIELD_NUMBER: builtins.int
|
||||
MSGID_FIELD_NUMBER: builtins.int
|
||||
ANONYMOUS_ONEOF_FIELD_NUMBER: builtins.int
|
||||
PROTO3_FIELD_NUMBER: builtins.int
|
||||
PROTO3_SINGULAR_MSGS_FIELD_NUMBER: builtins.int
|
||||
ENUM_TO_STRING_FIELD_NUMBER: builtins.int
|
||||
FIXED_LENGTH_FIELD_NUMBER: builtins.int
|
||||
FIXED_COUNT_FIELD_NUMBER: builtins.int
|
||||
SUBMSG_CALLBACK_FIELD_NUMBER: builtins.int
|
||||
MANGLE_NAMES_FIELD_NUMBER: builtins.int
|
||||
CALLBACK_DATATYPE_FIELD_NUMBER: builtins.int
|
||||
CALLBACK_FUNCTION_FIELD_NUMBER: builtins.int
|
||||
DESCRIPTORSIZE_FIELD_NUMBER: builtins.int
|
||||
DEFAULT_HAS_FIELD_NUMBER: builtins.int
|
||||
INCLUDE_FIELD_NUMBER: builtins.int
|
||||
EXCLUDE_FIELD_NUMBER: builtins.int
|
||||
PACKAGE_FIELD_NUMBER: builtins.int
|
||||
TYPE_OVERRIDE_FIELD_NUMBER: builtins.int
|
||||
SORT_BY_TAG_FIELD_NUMBER: builtins.int
|
||||
FALLBACK_TYPE_FIELD_NUMBER: builtins.int
|
||||
max_size: builtins.int
|
||||
"""Allocated size for 'bytes' and 'string' fields.
|
||||
For string fields, this should include the space for null terminator.
|
||||
"""
|
||||
max_length: builtins.int
|
||||
"""Maximum length for 'string' fields. Setting this is equivalent
|
||||
to setting max_size to a value of length+1.
|
||||
"""
|
||||
max_count: builtins.int
|
||||
"""Allocated number of entries in arrays ('repeated' fields)"""
|
||||
int_size: global___IntSize.ValueType
|
||||
"""Size of integer fields. Can save some memory if you don't need
|
||||
full 32 bits for the value.
|
||||
"""
|
||||
type: global___FieldType.ValueType
|
||||
"""Force type of field (callback or static allocation)"""
|
||||
long_names: builtins.bool
|
||||
"""Use long names for enums, i.e. EnumName_EnumValue."""
|
||||
packed_struct: builtins.bool
|
||||
"""Add 'packed' attribute to generated structs.
|
||||
Note: this cannot be used on CPUs that break on unaligned
|
||||
accesses to variables.
|
||||
"""
|
||||
packed_enum: builtins.bool
|
||||
"""Add 'packed' attribute to generated enums."""
|
||||
skip_message: builtins.bool
|
||||
"""Skip this message"""
|
||||
no_unions: builtins.bool
|
||||
"""Generate oneof fields as normal optional fields instead of union."""
|
||||
msgid: builtins.int
|
||||
"""integer type tag for a message"""
|
||||
anonymous_oneof: builtins.bool
|
||||
"""decode oneof as anonymous union"""
|
||||
proto3: builtins.bool
|
||||
"""Proto3 singular field does not generate a "has_" flag"""
|
||||
proto3_singular_msgs: builtins.bool
|
||||
"""Force proto3 messages to have no "has_" flag.
|
||||
This was default behavior until nanopb-0.4.0.
|
||||
"""
|
||||
enum_to_string: builtins.bool
|
||||
"""Generate an enum->string mapping function (can take up lots of space)."""
|
||||
fixed_length: builtins.bool
|
||||
"""Generate bytes arrays with fixed length"""
|
||||
fixed_count: builtins.bool
|
||||
"""Generate repeated field with fixed count"""
|
||||
submsg_callback: builtins.bool
|
||||
"""Generate message-level callback that is called before decoding submessages.
|
||||
This can be used to set callback fields for submsgs inside oneofs.
|
||||
"""
|
||||
mangle_names: global___TypenameMangling.ValueType
|
||||
"""Shorten or remove package names from type names.
|
||||
This option applies only on the file level.
|
||||
"""
|
||||
callback_datatype: builtins.str
|
||||
"""Data type for storage associated with callback fields."""
|
||||
callback_function: builtins.str
|
||||
"""Callback function used for encoding and decoding.
|
||||
Prior to nanopb-0.4.0, the callback was specified in per-field pb_callback_t
|
||||
structure. This is still supported, but does not work inside e.g. oneof or pointer
|
||||
fields. Instead, a new method allows specifying a per-message callback that
|
||||
will be called for all callback fields in a message type.
|
||||
"""
|
||||
descriptorsize: global___DescriptorSize.ValueType
|
||||
"""Select the size of field descriptors. This option has to be defined
|
||||
for the whole message, not per-field. Usually automatic selection is
|
||||
ok, but if it results in compilation errors you can increase the field
|
||||
size here.
|
||||
"""
|
||||
default_has: builtins.bool
|
||||
"""Set default value for has_ fields."""
|
||||
package: builtins.str
|
||||
"""Package name that applies only for nanopb."""
|
||||
type_override: google.protobuf.descriptor_pb2.FieldDescriptorProto.Type.ValueType
|
||||
"""Override type of the field in generated C code. Only to be used with related field types"""
|
||||
sort_by_tag: builtins.bool
|
||||
"""Due to historical reasons, nanopb orders fields in structs by their tag number
|
||||
instead of the order in .proto. Set this to false to keep the .proto order.
|
||||
The default value will probably change to false in nanopb-0.5.0.
|
||||
"""
|
||||
fallback_type: global___FieldType.ValueType
|
||||
"""Set the FT_DEFAULT field conversion strategy.
|
||||
A field that can become a static member of a c struct (e.g. int, bool, etc)
|
||||
will be a a static field.
|
||||
Fields with dynamic length are converted to either a pointer or a callback.
|
||||
"""
|
||||
@property
|
||||
def include(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
|
||||
"""Extra files to include in generated `.pb.h`"""
|
||||
|
||||
@property
|
||||
def exclude(self) -> google.protobuf.internal.containers.RepeatedScalarFieldContainer[builtins.str]:
|
||||
"""Automatic includes to exclude from generated `.pb.h`
|
||||
Same as nanopb_generator.py command line flag -x.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
max_size: builtins.int | None = ...,
|
||||
max_length: builtins.int | None = ...,
|
||||
max_count: builtins.int | None = ...,
|
||||
int_size: global___IntSize.ValueType | None = ...,
|
||||
type: global___FieldType.ValueType | None = ...,
|
||||
long_names: builtins.bool | None = ...,
|
||||
packed_struct: builtins.bool | None = ...,
|
||||
packed_enum: builtins.bool | None = ...,
|
||||
skip_message: builtins.bool | None = ...,
|
||||
no_unions: builtins.bool | None = ...,
|
||||
msgid: builtins.int | None = ...,
|
||||
anonymous_oneof: builtins.bool | None = ...,
|
||||
proto3: builtins.bool | None = ...,
|
||||
proto3_singular_msgs: builtins.bool | None = ...,
|
||||
enum_to_string: builtins.bool | None = ...,
|
||||
fixed_length: builtins.bool | None = ...,
|
||||
fixed_count: builtins.bool | None = ...,
|
||||
submsg_callback: builtins.bool | None = ...,
|
||||
mangle_names: global___TypenameMangling.ValueType | None = ...,
|
||||
callback_datatype: builtins.str | None = ...,
|
||||
callback_function: builtins.str | None = ...,
|
||||
descriptorsize: global___DescriptorSize.ValueType | None = ...,
|
||||
default_has: builtins.bool | None = ...,
|
||||
include: collections.abc.Iterable[builtins.str] | None = ...,
|
||||
exclude: collections.abc.Iterable[builtins.str] | None = ...,
|
||||
package: builtins.str | None = ...,
|
||||
type_override: google.protobuf.descriptor_pb2.FieldDescriptorProto.Type.ValueType | None = ...,
|
||||
sort_by_tag: builtins.bool | None = ...,
|
||||
fallback_type: global___FieldType.ValueType | None = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["anonymous_oneof", b"anonymous_oneof", "callback_datatype", b"callback_datatype", "callback_function", b"callback_function", "default_has", b"default_has", "descriptorsize", b"descriptorsize", "enum_to_string", b"enum_to_string", "fallback_type", b"fallback_type", "fixed_count", b"fixed_count", "fixed_length", b"fixed_length", "int_size", b"int_size", "long_names", b"long_names", "mangle_names", b"mangle_names", "max_count", b"max_count", "max_length", b"max_length", "max_size", b"max_size", "msgid", b"msgid", "no_unions", b"no_unions", "package", b"package", "packed_enum", b"packed_enum", "packed_struct", b"packed_struct", "proto3", b"proto3", "proto3_singular_msgs", b"proto3_singular_msgs", "skip_message", b"skip_message", "sort_by_tag", b"sort_by_tag", "submsg_callback", b"submsg_callback", "type", b"type", "type_override", b"type_override"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["anonymous_oneof", b"anonymous_oneof", "callback_datatype", b"callback_datatype", "callback_function", b"callback_function", "default_has", b"default_has", "descriptorsize", b"descriptorsize", "enum_to_string", b"enum_to_string", "exclude", b"exclude", "fallback_type", b"fallback_type", "fixed_count", b"fixed_count", "fixed_length", b"fixed_length", "include", b"include", "int_size", b"int_size", "long_names", b"long_names", "mangle_names", b"mangle_names", "max_count", b"max_count", "max_length", b"max_length", "max_size", b"max_size", "msgid", b"msgid", "no_unions", b"no_unions", "package", b"package", "packed_enum", b"packed_enum", "packed_struct", b"packed_struct", "proto3", b"proto3", "proto3_singular_msgs", b"proto3_singular_msgs", "skip_message", b"skip_message", "sort_by_tag", b"sort_by_tag", "submsg_callback", b"submsg_callback", "type", b"type", "type_override", b"type_override"]) -> None: ...
|
||||
|
||||
global___NanoPBOptions = NanoPBOptions
|
||||
|
||||
NANOPB_FILEOPT_FIELD_NUMBER: builtins.int
|
||||
NANOPB_MSGOPT_FIELD_NUMBER: builtins.int
|
||||
NANOPB_ENUMOPT_FIELD_NUMBER: builtins.int
|
||||
NANOPB_FIELD_NUMBER: builtins.int
|
||||
nanopb_fileopt: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FileOptions, global___NanoPBOptions]
|
||||
nanopb_msgopt: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.MessageOptions, global___NanoPBOptions]
|
||||
nanopb_enumopt: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.EnumOptions, global___NanoPBOptions]
|
||||
nanopb: google.protobuf.internal.extension_dict._ExtensionFieldDescriptor[google.protobuf.descriptor_pb2.FieldOptions, global___NanoPBOptions]
|
||||
class DescriptorSize(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/paxcount.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,12 +15,12 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/paxcount.proto\x12\x13meshtastic.protobuf\"5\n\x08Paxcount\x12\x0c\n\x04wifi\x18\x01 \x01(\r\x12\x0b\n\x03\x62le\x18\x02 \x01(\r\x12\x0e\n\x06uptime\x18\x03 \x01(\rBd\n\x14org.meshtastic.protoB\x0ePaxcountProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.paxcount_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.paxcount_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016PaxcountProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_PAXCOUNT']._serialized_start=59
|
||||
_globals['_PAXCOUNT']._serialized_end=112
|
||||
_PAXCOUNT._serialized_start=59
|
||||
_PAXCOUNT._serialized_end=112
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,45 +1,15 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class Paxcount(google.protobuf.message.Message):
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
WIFI_FIELD_NUMBER: builtins.int
|
||||
BLE_FIELD_NUMBER: builtins.int
|
||||
UPTIME_FIELD_NUMBER: builtins.int
|
||||
wifi: builtins.int
|
||||
"""
|
||||
seen Wifi devices
|
||||
"""
|
||||
ble: builtins.int
|
||||
"""
|
||||
Seen BLE devices
|
||||
"""
|
||||
uptime: builtins.int
|
||||
"""
|
||||
Uptime in seconds
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
wifi: builtins.int = ...,
|
||||
ble: builtins.int = ...,
|
||||
uptime: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["ble", b"ble", "uptime", b"uptime", "wifi", b"wifi"]) -> None: ...
|
||||
|
||||
global___Paxcount = Paxcount
|
||||
class Paxcount(_message.Message):
|
||||
__slots__ = ["ble", "uptime", "wifi"]
|
||||
BLE_FIELD_NUMBER: _ClassVar[int]
|
||||
UPTIME_FIELD_NUMBER: _ClassVar[int]
|
||||
WIFI_FIELD_NUMBER: _ClassVar[int]
|
||||
ble: int
|
||||
uptime: int
|
||||
wifi: int
|
||||
def __init__(self, wifi: _Optional[int] = ..., ble: _Optional[int] = ..., uptime: _Optional[int] = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/portnums.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -13,14 +13,14 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xf6\x04\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tALERT_APP\x10\x0b\x12\x18\n\x14KEY_VERIFICATION_APP\x10\x0c\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x12\n\x0ePAXCOUNTER_APP\x10\"\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x0f\n\x0b\x41TAK_PLUGIN\x10H\x12\x12\n\x0eMAP_REPORT_APP\x10I\x12\x13\n\x0fPOWERSTRESS_APP\x10J\x12\x18\n\x14RETICULUM_TUNNEL_APP\x10L\x12\x0f\n\x0b\x43\x41YENNE_APP\x10M\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42^\n\x14org.meshtastic.protoB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xfd\x05\n\x07PortNum\x12\x0f\n\x0bUNKNOWN_APP\x10\x00\x12\x14\n\x10TEXT_MESSAGE_APP\x10\x01\x12\x17\n\x13REMOTE_HARDWARE_APP\x10\x02\x12\x10\n\x0cPOSITION_APP\x10\x03\x12\x10\n\x0cNODEINFO_APP\x10\x04\x12\x0f\n\x0bROUTING_APP\x10\x05\x12\r\n\tADMIN_APP\x10\x06\x12\x1f\n\x1bTEXT_MESSAGE_COMPRESSED_APP\x10\x07\x12\x10\n\x0cWAYPOINT_APP\x10\x08\x12\r\n\tAUDIO_APP\x10\t\x12\x18\n\x14\x44\x45TECTION_SENSOR_APP\x10\n\x12\r\n\tALERT_APP\x10\x0b\x12\x18\n\x14KEY_VERIFICATION_APP\x10\x0c\x12\x14\n\x10REMOTE_SHELL_APP\x10\r\x12\r\n\tREPLY_APP\x10 \x12\x11\n\rIP_TUNNEL_APP\x10!\x12\x12\n\x0ePAXCOUNTER_APP\x10\"\x12\x1e\n\x1aSTORE_FORWARD_PLUSPLUS_APP\x10#\x12\x13\n\x0fNODE_STATUS_APP\x10$\x12\x0e\n\nSERIAL_APP\x10@\x12\x15\n\x11STORE_FORWARD_APP\x10\x41\x12\x12\n\x0eRANGE_TEST_APP\x10\x42\x12\x11\n\rTELEMETRY_APP\x10\x43\x12\x0b\n\x07ZPS_APP\x10\x44\x12\x11\n\rSIMULATOR_APP\x10\x45\x12\x12\n\x0eTRACEROUTE_APP\x10\x46\x12\x14\n\x10NEIGHBORINFO_APP\x10G\x12\x0f\n\x0b\x41TAK_PLUGIN\x10H\x12\x12\n\x0eMAP_REPORT_APP\x10I\x12\x13\n\x0fPOWERSTRESS_APP\x10J\x12\x12\n\x0eLORAWAN_BRIDGE\x10K\x12\x18\n\x14RETICULUM_TUNNEL_APP\x10L\x12\x0f\n\x0b\x43\x41YENNE_APP\x10M\x12\x12\n\x0e\x41TAK_PLUGIN_V2\x10N\x12\x12\n\x0eGROUPALARM_APP\x10p\x12\x10\n\x0bPRIVATE_APP\x10\x80\x02\x12\x13\n\x0e\x41TAK_FORWARDER\x10\x81\x02\x12\x08\n\x03MAX\x10\xff\x03\x42^\n\x14org.meshtastic.protoB\x08PortnumsZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.portnums_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.portnums_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\010PortnumsZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_PORTNUM']._serialized_start=60
|
||||
_globals['_PORTNUM']._serialized_end=690
|
||||
_PORTNUM._serialized_start=60
|
||||
_PORTNUM._serialized_end=825
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,416 +1,46 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from typing import ClassVar as _ClassVar
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import sys
|
||||
import typing
|
||||
ADMIN_APP: PortNum
|
||||
ALERT_APP: PortNum
|
||||
ATAK_FORWARDER: PortNum
|
||||
ATAK_PLUGIN: PortNum
|
||||
ATAK_PLUGIN_V2: PortNum
|
||||
AUDIO_APP: PortNum
|
||||
CAYENNE_APP: PortNum
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
DETECTION_SENSOR_APP: PortNum
|
||||
GROUPALARM_APP: PortNum
|
||||
IP_TUNNEL_APP: PortNum
|
||||
KEY_VERIFICATION_APP: PortNum
|
||||
LORAWAN_BRIDGE: PortNum
|
||||
MAP_REPORT_APP: PortNum
|
||||
MAX: PortNum
|
||||
NEIGHBORINFO_APP: PortNum
|
||||
NODEINFO_APP: PortNum
|
||||
NODE_STATUS_APP: PortNum
|
||||
PAXCOUNTER_APP: PortNum
|
||||
POSITION_APP: PortNum
|
||||
POWERSTRESS_APP: PortNum
|
||||
PRIVATE_APP: PortNum
|
||||
RANGE_TEST_APP: PortNum
|
||||
REMOTE_HARDWARE_APP: PortNum
|
||||
REMOTE_SHELL_APP: PortNum
|
||||
REPLY_APP: PortNum
|
||||
RETICULUM_TUNNEL_APP: PortNum
|
||||
ROUTING_APP: PortNum
|
||||
SERIAL_APP: PortNum
|
||||
SIMULATOR_APP: PortNum
|
||||
STORE_FORWARD_APP: PortNum
|
||||
STORE_FORWARD_PLUSPLUS_APP: PortNum
|
||||
TELEMETRY_APP: PortNum
|
||||
TEXT_MESSAGE_APP: PortNum
|
||||
TEXT_MESSAGE_COMPRESSED_APP: PortNum
|
||||
TRACEROUTE_APP: PortNum
|
||||
UNKNOWN_APP: PortNum
|
||||
WAYPOINT_APP: PortNum
|
||||
ZPS_APP: PortNum
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
class _PortNum:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _PortNumEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_PortNum.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
UNKNOWN_APP: _PortNum.ValueType # 0
|
||||
"""
|
||||
Deprecated: do not use in new code (formerly called OPAQUE)
|
||||
A message sent from a device outside of the mesh, in a form the mesh does not understand
|
||||
NOTE: This must be 0, because it is documented in IMeshService.aidl to be so
|
||||
ENCODING: binary undefined
|
||||
"""
|
||||
TEXT_MESSAGE_APP: _PortNum.ValueType # 1
|
||||
"""
|
||||
A simple UTF-8 text message, which even the little micros in the mesh
|
||||
can understand and show on their screen eventually in some circumstances
|
||||
even signal might send messages in this form (see below)
|
||||
ENCODING: UTF-8 Plaintext (?)
|
||||
"""
|
||||
REMOTE_HARDWARE_APP: _PortNum.ValueType # 2
|
||||
"""
|
||||
Reserved for built-in GPIO/example app.
|
||||
See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
POSITION_APP: _PortNum.ValueType # 3
|
||||
"""
|
||||
The built-in position messaging app.
|
||||
Payload is a Position message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
NODEINFO_APP: _PortNum.ValueType # 4
|
||||
"""
|
||||
The built-in user info app.
|
||||
Payload is a User message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ROUTING_APP: _PortNum.ValueType # 5
|
||||
"""
|
||||
Protocol control packets for mesh protocol use.
|
||||
Payload is a Routing message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ADMIN_APP: _PortNum.ValueType # 6
|
||||
"""
|
||||
Admin control packets.
|
||||
Payload is a AdminMessage message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
TEXT_MESSAGE_COMPRESSED_APP: _PortNum.ValueType # 7
|
||||
"""
|
||||
Compressed TEXT_MESSAGE payloads.
|
||||
ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression
|
||||
NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed
|
||||
payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress
|
||||
any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP.
|
||||
"""
|
||||
WAYPOINT_APP: _PortNum.ValueType # 8
|
||||
"""
|
||||
Waypoint payloads.
|
||||
Payload is a Waypoint message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
AUDIO_APP: _PortNum.ValueType # 9
|
||||
"""
|
||||
Audio Payloads.
|
||||
Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now
|
||||
ENCODING: codec2 audio frames
|
||||
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
|
||||
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one.
|
||||
"""
|
||||
DETECTION_SENSOR_APP: _PortNum.ValueType # 10
|
||||
"""
|
||||
Same as Text Message but originating from Detection Sensor Module.
|
||||
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9
|
||||
"""
|
||||
ALERT_APP: _PortNum.ValueType # 11
|
||||
"""
|
||||
Same as Text Message but used for critical alerts.
|
||||
"""
|
||||
KEY_VERIFICATION_APP: _PortNum.ValueType # 12
|
||||
"""
|
||||
Module/port for handling key verification requests.
|
||||
"""
|
||||
REPLY_APP: _PortNum.ValueType # 32
|
||||
"""
|
||||
Provides a 'ping' service that replies to any packet it receives.
|
||||
Also serves as a small example module.
|
||||
ENCODING: ASCII Plaintext
|
||||
"""
|
||||
IP_TUNNEL_APP: _PortNum.ValueType # 33
|
||||
"""
|
||||
Used for the python IP tunnel feature
|
||||
ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on.
|
||||
"""
|
||||
PAXCOUNTER_APP: _PortNum.ValueType # 34
|
||||
"""
|
||||
Paxcounter lib included in the firmware
|
||||
ENCODING: protobuf
|
||||
"""
|
||||
SERIAL_APP: _PortNum.ValueType # 64
|
||||
"""
|
||||
Provides a hardware serial interface to send and receive from the Meshtastic network.
|
||||
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
||||
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
||||
Maximum packet size of 240 bytes.
|
||||
Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp.
|
||||
ENCODING: binary undefined
|
||||
"""
|
||||
STORE_FORWARD_APP: _PortNum.ValueType # 65
|
||||
"""
|
||||
STORE_FORWARD_APP (Work in Progress)
|
||||
Maintained by Jm Casler (MC Hamster) : jm@casler.org
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
RANGE_TEST_APP: _PortNum.ValueType # 66
|
||||
"""
|
||||
Optional port for messages for the range test module.
|
||||
ENCODING: ASCII Plaintext
|
||||
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9
|
||||
"""
|
||||
TELEMETRY_APP: _PortNum.ValueType # 67
|
||||
"""
|
||||
Provides a format to send and receive telemetry data from the Meshtastic network.
|
||||
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ZPS_APP: _PortNum.ValueType # 68
|
||||
"""
|
||||
Experimental tools for estimating node position without a GPS
|
||||
Maintained by Github user a-f-G-U-C (a Meshtastic contributor)
|
||||
Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS
|
||||
ENCODING: arrays of int64 fields
|
||||
"""
|
||||
SIMULATOR_APP: _PortNum.ValueType # 69
|
||||
"""
|
||||
Used to let multiple instances of Linux native applications communicate
|
||||
as if they did using their LoRa chip.
|
||||
Maintained by GitHub user GUVWAF.
|
||||
Project files at https://github.com/GUVWAF/Meshtasticator
|
||||
ENCODING: Protobuf (?)
|
||||
"""
|
||||
TRACEROUTE_APP: _PortNum.ValueType # 70
|
||||
"""
|
||||
Provides a traceroute functionality to show the route a packet towards
|
||||
a certain destination would take on the mesh. Contains a RouteDiscovery message as payload.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
NEIGHBORINFO_APP: _PortNum.ValueType # 71
|
||||
"""
|
||||
Aggregates edge info for the network by sending out a list of each node's neighbors
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ATAK_PLUGIN: _PortNum.ValueType # 72
|
||||
"""
|
||||
ATAK Plugin
|
||||
Portnum for payloads from the official Meshtastic ATAK plugin
|
||||
"""
|
||||
MAP_REPORT_APP: _PortNum.ValueType # 73
|
||||
"""
|
||||
Provides unencrypted information about a node for consumption by a map via MQTT
|
||||
"""
|
||||
POWERSTRESS_APP: _PortNum.ValueType # 74
|
||||
"""
|
||||
PowerStress based monitoring support (for automated power consumption testing)
|
||||
"""
|
||||
RETICULUM_TUNNEL_APP: _PortNum.ValueType # 76
|
||||
"""
|
||||
Reticulum Network Stack Tunnel App
|
||||
ENCODING: Fragmented RNS Packet. Handled by Meshtastic RNS interface
|
||||
"""
|
||||
CAYENNE_APP: _PortNum.ValueType # 77
|
||||
"""
|
||||
App for transporting Cayenne Low Power Payload, popular for LoRaWAN sensor nodes. Offers ability to send
|
||||
arbitrary telemetry over meshtastic that is not covered by telemetry.proto
|
||||
ENCODING: CayenneLLP
|
||||
"""
|
||||
PRIVATE_APP: _PortNum.ValueType # 256
|
||||
"""
|
||||
Private applications should use portnums >= 256.
|
||||
To simplify initial development and testing you can use "PRIVATE_APP"
|
||||
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh))
|
||||
"""
|
||||
ATAK_FORWARDER: _PortNum.ValueType # 257
|
||||
"""
|
||||
ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder
|
||||
ENCODING: libcotshrink
|
||||
"""
|
||||
MAX: _PortNum.ValueType # 511
|
||||
"""
|
||||
Currently we limit port nums to no higher than this value
|
||||
"""
|
||||
|
||||
class PortNum(_PortNum, metaclass=_PortNumEnumTypeWrapper):
|
||||
"""
|
||||
For any new 'apps' that run on the device or via sister apps on phones/PCs they should pick and use a
|
||||
unique 'portnum' for their application.
|
||||
If you are making a new app using meshtastic, please send in a pull request to add your 'portnum' to this
|
||||
master table.
|
||||
PortNums should be assigned in the following range:
|
||||
0-63 Core Meshtastic use, do not use for third party apps
|
||||
64-127 Registered 3rd party apps, send in a pull request that adds a new entry to portnums.proto to register your application
|
||||
256-511 Use one of these portnums for your private applications that you don't want to register publically
|
||||
All other values are reserved.
|
||||
Note: This was formerly a Type enum named 'typ' with the same id #
|
||||
We have change to this 'portnum' based scheme for specifying app handlers for particular payloads.
|
||||
This change is backwards compatible by treating the legacy OPAQUE/CLEAR_TEXT values identically.
|
||||
"""
|
||||
|
||||
UNKNOWN_APP: PortNum.ValueType # 0
|
||||
"""
|
||||
Deprecated: do not use in new code (formerly called OPAQUE)
|
||||
A message sent from a device outside of the mesh, in a form the mesh does not understand
|
||||
NOTE: This must be 0, because it is documented in IMeshService.aidl to be so
|
||||
ENCODING: binary undefined
|
||||
"""
|
||||
TEXT_MESSAGE_APP: PortNum.ValueType # 1
|
||||
"""
|
||||
A simple UTF-8 text message, which even the little micros in the mesh
|
||||
can understand and show on their screen eventually in some circumstances
|
||||
even signal might send messages in this form (see below)
|
||||
ENCODING: UTF-8 Plaintext (?)
|
||||
"""
|
||||
REMOTE_HARDWARE_APP: PortNum.ValueType # 2
|
||||
"""
|
||||
Reserved for built-in GPIO/example app.
|
||||
See remote_hardware.proto/HardwareMessage for details on the message sent/received to this port number
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
POSITION_APP: PortNum.ValueType # 3
|
||||
"""
|
||||
The built-in position messaging app.
|
||||
Payload is a Position message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
NODEINFO_APP: PortNum.ValueType # 4
|
||||
"""
|
||||
The built-in user info app.
|
||||
Payload is a User message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ROUTING_APP: PortNum.ValueType # 5
|
||||
"""
|
||||
Protocol control packets for mesh protocol use.
|
||||
Payload is a Routing message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ADMIN_APP: PortNum.ValueType # 6
|
||||
"""
|
||||
Admin control packets.
|
||||
Payload is a AdminMessage message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
TEXT_MESSAGE_COMPRESSED_APP: PortNum.ValueType # 7
|
||||
"""
|
||||
Compressed TEXT_MESSAGE payloads.
|
||||
ENCODING: UTF-8 Plaintext (?) with Unishox2 Compression
|
||||
NOTE: The Device Firmware converts a TEXT_MESSAGE_APP to TEXT_MESSAGE_COMPRESSED_APP if the compressed
|
||||
payload is shorter. There's no need for app developers to do this themselves. Also the firmware will decompress
|
||||
any incoming TEXT_MESSAGE_COMPRESSED_APP payload and convert to TEXT_MESSAGE_APP.
|
||||
"""
|
||||
WAYPOINT_APP: PortNum.ValueType # 8
|
||||
"""
|
||||
Waypoint payloads.
|
||||
Payload is a Waypoint message.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
AUDIO_APP: PortNum.ValueType # 9
|
||||
"""
|
||||
Audio Payloads.
|
||||
Encapsulated codec2 packets. On 2.4 GHZ Bandwidths only for now
|
||||
ENCODING: codec2 audio frames
|
||||
NOTE: audio frames contain a 3 byte header (0xc0 0xde 0xc2) and a one byte marker for the decompressed bitrate.
|
||||
This marker comes from the 'moduleConfig.audio.bitrate' enum minus one.
|
||||
"""
|
||||
DETECTION_SENSOR_APP: PortNum.ValueType # 10
|
||||
"""
|
||||
Same as Text Message but originating from Detection Sensor Module.
|
||||
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9
|
||||
"""
|
||||
ALERT_APP: PortNum.ValueType # 11
|
||||
"""
|
||||
Same as Text Message but used for critical alerts.
|
||||
"""
|
||||
KEY_VERIFICATION_APP: PortNum.ValueType # 12
|
||||
"""
|
||||
Module/port for handling key verification requests.
|
||||
"""
|
||||
REPLY_APP: PortNum.ValueType # 32
|
||||
"""
|
||||
Provides a 'ping' service that replies to any packet it receives.
|
||||
Also serves as a small example module.
|
||||
ENCODING: ASCII Plaintext
|
||||
"""
|
||||
IP_TUNNEL_APP: PortNum.ValueType # 33
|
||||
"""
|
||||
Used for the python IP tunnel feature
|
||||
ENCODING: IP Packet. Handled by the python API, firmware ignores this one and pases on.
|
||||
"""
|
||||
PAXCOUNTER_APP: PortNum.ValueType # 34
|
||||
"""
|
||||
Paxcounter lib included in the firmware
|
||||
ENCODING: protobuf
|
||||
"""
|
||||
SERIAL_APP: PortNum.ValueType # 64
|
||||
"""
|
||||
Provides a hardware serial interface to send and receive from the Meshtastic network.
|
||||
Connect to the RX/TX pins of a device with 38400 8N1. Packets received from the Meshtastic
|
||||
network is forwarded to the RX pin while sending a packet to TX will go out to the Mesh network.
|
||||
Maximum packet size of 240 bytes.
|
||||
Module is disabled by default can be turned on by setting SERIAL_MODULE_ENABLED = 1 in SerialPlugh.cpp.
|
||||
ENCODING: binary undefined
|
||||
"""
|
||||
STORE_FORWARD_APP: PortNum.ValueType # 65
|
||||
"""
|
||||
STORE_FORWARD_APP (Work in Progress)
|
||||
Maintained by Jm Casler (MC Hamster) : jm@casler.org
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
RANGE_TEST_APP: PortNum.ValueType # 66
|
||||
"""
|
||||
Optional port for messages for the range test module.
|
||||
ENCODING: ASCII Plaintext
|
||||
NOTE: This portnum traffic is not sent to the public MQTT starting at firmware version 2.2.9
|
||||
"""
|
||||
TELEMETRY_APP: PortNum.ValueType # 67
|
||||
"""
|
||||
Provides a format to send and receive telemetry data from the Meshtastic network.
|
||||
Maintained by Charles Crossan (crossan007) : crossan007@gmail.com
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ZPS_APP: PortNum.ValueType # 68
|
||||
"""
|
||||
Experimental tools for estimating node position without a GPS
|
||||
Maintained by Github user a-f-G-U-C (a Meshtastic contributor)
|
||||
Project files at https://github.com/a-f-G-U-C/Meshtastic-ZPS
|
||||
ENCODING: arrays of int64 fields
|
||||
"""
|
||||
SIMULATOR_APP: PortNum.ValueType # 69
|
||||
"""
|
||||
Used to let multiple instances of Linux native applications communicate
|
||||
as if they did using their LoRa chip.
|
||||
Maintained by GitHub user GUVWAF.
|
||||
Project files at https://github.com/GUVWAF/Meshtasticator
|
||||
ENCODING: Protobuf (?)
|
||||
"""
|
||||
TRACEROUTE_APP: PortNum.ValueType # 70
|
||||
"""
|
||||
Provides a traceroute functionality to show the route a packet towards
|
||||
a certain destination would take on the mesh. Contains a RouteDiscovery message as payload.
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
NEIGHBORINFO_APP: PortNum.ValueType # 71
|
||||
"""
|
||||
Aggregates edge info for the network by sending out a list of each node's neighbors
|
||||
ENCODING: Protobuf
|
||||
"""
|
||||
ATAK_PLUGIN: PortNum.ValueType # 72
|
||||
"""
|
||||
ATAK Plugin
|
||||
Portnum for payloads from the official Meshtastic ATAK plugin
|
||||
"""
|
||||
MAP_REPORT_APP: PortNum.ValueType # 73
|
||||
"""
|
||||
Provides unencrypted information about a node for consumption by a map via MQTT
|
||||
"""
|
||||
POWERSTRESS_APP: PortNum.ValueType # 74
|
||||
"""
|
||||
PowerStress based monitoring support (for automated power consumption testing)
|
||||
"""
|
||||
RETICULUM_TUNNEL_APP: PortNum.ValueType # 76
|
||||
"""
|
||||
Reticulum Network Stack Tunnel App
|
||||
ENCODING: Fragmented RNS Packet. Handled by Meshtastic RNS interface
|
||||
"""
|
||||
CAYENNE_APP: PortNum.ValueType # 77
|
||||
"""
|
||||
App for transporting Cayenne Low Power Payload, popular for LoRaWAN sensor nodes. Offers ability to send
|
||||
arbitrary telemetry over meshtastic that is not covered by telemetry.proto
|
||||
ENCODING: CayenneLLP
|
||||
"""
|
||||
PRIVATE_APP: PortNum.ValueType # 256
|
||||
"""
|
||||
Private applications should use portnums >= 256.
|
||||
To simplify initial development and testing you can use "PRIVATE_APP"
|
||||
in your code without needing to rebuild protobuf files (via [regen-protos.sh](https://github.com/meshtastic/firmware/blob/master/bin/regen-protos.sh))
|
||||
"""
|
||||
ATAK_FORWARDER: PortNum.ValueType # 257
|
||||
"""
|
||||
ATAK Forwarder Module https://github.com/paulmandal/atak-forwarder
|
||||
ENCODING: libcotshrink
|
||||
"""
|
||||
MAX: PortNum.ValueType # 511
|
||||
"""
|
||||
Currently we limit port nums to no higher than this value
|
||||
"""
|
||||
global___PortNum = PortNum
|
||||
class PortNum(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/powermon.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,18 +15,18 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/powermon.proto\x12\x13meshtastic.protobuf\"\xe0\x01\n\x08PowerMon\"\xd3\x01\n\x05State\x12\x08\n\x04None\x10\x00\x12\x11\n\rCPU_DeepSleep\x10\x01\x12\x12\n\x0e\x43PU_LightSleep\x10\x02\x12\x0c\n\x08Vext1_On\x10\x04\x12\r\n\tLora_RXOn\x10\x08\x12\r\n\tLora_TXOn\x10\x10\x12\x11\n\rLora_RXActive\x10 \x12\t\n\x05\x42T_On\x10@\x12\x0b\n\x06LED_On\x10\x80\x01\x12\x0e\n\tScreen_On\x10\x80\x02\x12\x13\n\x0eScreen_Drawing\x10\x80\x04\x12\x0c\n\x07Wifi_On\x10\x80\x08\x12\x0f\n\nGPS_Active\x10\x80\x10\"\x88\x03\n\x12PowerStressMessage\x12;\n\x03\x63md\x18\x01 \x01(\x0e\x32..meshtastic.protobuf.PowerStressMessage.Opcode\x12\x13\n\x0bnum_seconds\x18\x02 \x01(\x02\"\x9f\x02\n\x06Opcode\x12\t\n\x05UNSET\x10\x00\x12\x0e\n\nPRINT_INFO\x10\x01\x12\x0f\n\x0b\x46ORCE_QUIET\x10\x02\x12\r\n\tEND_QUIET\x10\x03\x12\r\n\tSCREEN_ON\x10\x10\x12\x0e\n\nSCREEN_OFF\x10\x11\x12\x0c\n\x08\x43PU_IDLE\x10 \x12\x11\n\rCPU_DEEPSLEEP\x10!\x12\x0e\n\nCPU_FULLON\x10\"\x12\n\n\x06LED_ON\x10\x30\x12\x0b\n\x07LED_OFF\x10\x31\x12\x0c\n\x08LORA_OFF\x10@\x12\x0b\n\x07LORA_TX\x10\x41\x12\x0b\n\x07LORA_RX\x10\x42\x12\n\n\x06\x42T_OFF\x10P\x12\t\n\x05\x42T_ON\x10Q\x12\x0c\n\x08WIFI_OFF\x10`\x12\x0b\n\x07WIFI_ON\x10\x61\x12\x0b\n\x07GPS_OFF\x10p\x12\n\n\x06GPS_ON\x10qBd\n\x14org.meshtastic.protoB\x0ePowerMonProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.powermon_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.powermon_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016PowerMonProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_POWERMON']._serialized_start=60
|
||||
_globals['_POWERMON']._serialized_end=284
|
||||
_globals['_POWERMON_STATE']._serialized_start=73
|
||||
_globals['_POWERMON_STATE']._serialized_end=284
|
||||
_globals['_POWERSTRESSMESSAGE']._serialized_start=287
|
||||
_globals['_POWERSTRESSMESSAGE']._serialized_end=679
|
||||
_globals['_POWERSTRESSMESSAGE_OPCODE']._serialized_start=392
|
||||
_globals['_POWERSTRESSMESSAGE_OPCODE']._serialized_end=679
|
||||
_POWERMON._serialized_start=60
|
||||
_POWERMON._serialized_end=284
|
||||
_POWERMON_STATE._serialized_start=73
|
||||
_POWERMON_STATE._serialized_end=284
|
||||
_POWERSTRESSMESSAGE._serialized_start=287
|
||||
_POWERSTRESSMESSAGE._serialized_end=679
|
||||
_POWERSTRESSMESSAGE_OPCODE._serialized_start=392
|
||||
_POWERSTRESSMESSAGE_OPCODE._serialized_end=679
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,221 +1,55 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
class PowerMon(_message.Message):
|
||||
__slots__ = []
|
||||
class State(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
BT_On: PowerMon.State
|
||||
CPU_DeepSleep: PowerMon.State
|
||||
CPU_LightSleep: PowerMon.State
|
||||
GPS_Active: PowerMon.State
|
||||
LED_On: PowerMon.State
|
||||
Lora_RXActive: PowerMon.State
|
||||
Lora_RXOn: PowerMon.State
|
||||
Lora_TXOn: PowerMon.State
|
||||
None: PowerMon.State
|
||||
Screen_Drawing: PowerMon.State
|
||||
Screen_On: PowerMon.State
|
||||
Vext1_On: PowerMon.State
|
||||
Wifi_On: PowerMon.State
|
||||
def __init__(self) -> None: ...
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class PowerMon(google.protobuf.message.Message):
|
||||
"""Note: There are no 'PowerMon' messages normally in use (PowerMons are sent only as structured logs - slogs).
|
||||
But we wrap our State enum in this message to effectively nest a namespace (without our linter yelling at us)
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _State:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _StateEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PowerMon._State.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
CPU_DeepSleep: PowerMon._State.ValueType # 1
|
||||
CPU_LightSleep: PowerMon._State.ValueType # 2
|
||||
Vext1_On: PowerMon._State.ValueType # 4
|
||||
"""
|
||||
The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only
|
||||
occasionally. In cases where that rail has multiple devices on it we usually want to have logging on
|
||||
the state of that rail as an independent record.
|
||||
For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen.
|
||||
|
||||
The log messages will be short and complete (see PowerMon.Event in the protobufs for details).
|
||||
something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states.
|
||||
(We use a bitmask for states so that if a log message gets lost it won't be fatal)
|
||||
"""
|
||||
Lora_RXOn: PowerMon._State.ValueType # 8
|
||||
Lora_TXOn: PowerMon._State.ValueType # 16
|
||||
Lora_RXActive: PowerMon._State.ValueType # 32
|
||||
BT_On: PowerMon._State.ValueType # 64
|
||||
LED_On: PowerMon._State.ValueType # 128
|
||||
Screen_On: PowerMon._State.ValueType # 256
|
||||
Screen_Drawing: PowerMon._State.ValueType # 512
|
||||
Wifi_On: PowerMon._State.ValueType # 1024
|
||||
GPS_Active: PowerMon._State.ValueType # 2048
|
||||
"""
|
||||
GPS is actively trying to find our location
|
||||
See GPSPowerState for more details
|
||||
"""
|
||||
|
||||
class State(_State, metaclass=_StateEnumTypeWrapper):
|
||||
"""Any significant power changing event in meshtastic should be tagged with a powermon state transition.
|
||||
If you are making new meshtastic features feel free to add new entries at the end of this definition.
|
||||
"""
|
||||
|
||||
CPU_DeepSleep: PowerMon.State.ValueType # 1
|
||||
CPU_LightSleep: PowerMon.State.ValueType # 2
|
||||
Vext1_On: PowerMon.State.ValueType # 4
|
||||
"""
|
||||
The external Vext1 power is on. Many boards have auxillary power rails that the CPU turns on only
|
||||
occasionally. In cases where that rail has multiple devices on it we usually want to have logging on
|
||||
the state of that rail as an independent record.
|
||||
For instance on the Heltec Tracker 1.1 board, this rail is the power source for the GPS and screen.
|
||||
|
||||
The log messages will be short and complete (see PowerMon.Event in the protobufs for details).
|
||||
something like "S:PM:C,0x00001234,REASON" where the hex number is the bitmask of all current states.
|
||||
(We use a bitmask for states so that if a log message gets lost it won't be fatal)
|
||||
"""
|
||||
Lora_RXOn: PowerMon.State.ValueType # 8
|
||||
Lora_TXOn: PowerMon.State.ValueType # 16
|
||||
Lora_RXActive: PowerMon.State.ValueType # 32
|
||||
BT_On: PowerMon.State.ValueType # 64
|
||||
LED_On: PowerMon.State.ValueType # 128
|
||||
Screen_On: PowerMon.State.ValueType # 256
|
||||
Screen_Drawing: PowerMon.State.ValueType # 512
|
||||
Wifi_On: PowerMon.State.ValueType # 1024
|
||||
GPS_Active: PowerMon.State.ValueType # 2048
|
||||
"""
|
||||
GPS is actively trying to find our location
|
||||
See GPSPowerState for more details
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
) -> None: ...
|
||||
|
||||
global___PowerMon = PowerMon
|
||||
|
||||
@typing.final
|
||||
class PowerStressMessage(google.protobuf.message.Message):
|
||||
"""
|
||||
PowerStress testing support via the C++ PowerStress module
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _Opcode:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _OpcodeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[PowerStressMessage._Opcode.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
UNSET: PowerStressMessage._Opcode.ValueType # 0
|
||||
"""
|
||||
Unset/unused
|
||||
"""
|
||||
PRINT_INFO: PowerStressMessage._Opcode.ValueType # 1
|
||||
"""Print board version slog and send an ack that we are alive and ready to process commands"""
|
||||
FORCE_QUIET: PowerStressMessage._Opcode.ValueType # 2
|
||||
"""Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation)"""
|
||||
END_QUIET: PowerStressMessage._Opcode.ValueType # 3
|
||||
"""Stop powerstress processing - probably by just rebooting the board"""
|
||||
SCREEN_ON: PowerStressMessage._Opcode.ValueType # 16
|
||||
"""Turn the screen on"""
|
||||
SCREEN_OFF: PowerStressMessage._Opcode.ValueType # 17
|
||||
"""Turn the screen off"""
|
||||
CPU_IDLE: PowerStressMessage._Opcode.ValueType # 32
|
||||
"""Let the CPU run but we assume mostly idling for num_seconds"""
|
||||
CPU_DEEPSLEEP: PowerStressMessage._Opcode.ValueType # 33
|
||||
"""Force deep sleep for FIXME seconds"""
|
||||
CPU_FULLON: PowerStressMessage._Opcode.ValueType # 34
|
||||
"""Spin the CPU as fast as possible for num_seconds"""
|
||||
LED_ON: PowerStressMessage._Opcode.ValueType # 48
|
||||
"""Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes)"""
|
||||
LED_OFF: PowerStressMessage._Opcode.ValueType # 49
|
||||
"""Force the LED off for num_seconds"""
|
||||
LORA_OFF: PowerStressMessage._Opcode.ValueType # 64
|
||||
"""Completely turn off the LORA radio for num_seconds"""
|
||||
LORA_TX: PowerStressMessage._Opcode.ValueType # 65
|
||||
"""Send Lora packets for num_seconds"""
|
||||
LORA_RX: PowerStressMessage._Opcode.ValueType # 66
|
||||
"""Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel)"""
|
||||
BT_OFF: PowerStressMessage._Opcode.ValueType # 80
|
||||
"""Turn off the BT radio for num_seconds"""
|
||||
BT_ON: PowerStressMessage._Opcode.ValueType # 81
|
||||
"""Turn on the BT radio for num_seconds"""
|
||||
WIFI_OFF: PowerStressMessage._Opcode.ValueType # 96
|
||||
"""Turn off the WIFI radio for num_seconds"""
|
||||
WIFI_ON: PowerStressMessage._Opcode.ValueType # 97
|
||||
"""Turn on the WIFI radio for num_seconds"""
|
||||
GPS_OFF: PowerStressMessage._Opcode.ValueType # 112
|
||||
"""Turn off the GPS radio for num_seconds"""
|
||||
GPS_ON: PowerStressMessage._Opcode.ValueType # 113
|
||||
"""Turn on the GPS radio for num_seconds"""
|
||||
|
||||
class Opcode(_Opcode, metaclass=_OpcodeEnumTypeWrapper):
|
||||
"""
|
||||
What operation would we like the UUT to perform.
|
||||
note: senders should probably set want_response in their request packets, so that they can know when the state
|
||||
machine has started processing their request
|
||||
"""
|
||||
|
||||
UNSET: PowerStressMessage.Opcode.ValueType # 0
|
||||
"""
|
||||
Unset/unused
|
||||
"""
|
||||
PRINT_INFO: PowerStressMessage.Opcode.ValueType # 1
|
||||
"""Print board version slog and send an ack that we are alive and ready to process commands"""
|
||||
FORCE_QUIET: PowerStressMessage.Opcode.ValueType # 2
|
||||
"""Try to turn off all automatic processing of packets, screen, sleeping, etc (to make it easier to measure in isolation)"""
|
||||
END_QUIET: PowerStressMessage.Opcode.ValueType # 3
|
||||
"""Stop powerstress processing - probably by just rebooting the board"""
|
||||
SCREEN_ON: PowerStressMessage.Opcode.ValueType # 16
|
||||
"""Turn the screen on"""
|
||||
SCREEN_OFF: PowerStressMessage.Opcode.ValueType # 17
|
||||
"""Turn the screen off"""
|
||||
CPU_IDLE: PowerStressMessage.Opcode.ValueType # 32
|
||||
"""Let the CPU run but we assume mostly idling for num_seconds"""
|
||||
CPU_DEEPSLEEP: PowerStressMessage.Opcode.ValueType # 33
|
||||
"""Force deep sleep for FIXME seconds"""
|
||||
CPU_FULLON: PowerStressMessage.Opcode.ValueType # 34
|
||||
"""Spin the CPU as fast as possible for num_seconds"""
|
||||
LED_ON: PowerStressMessage.Opcode.ValueType # 48
|
||||
"""Turn the LED on for num_seconds (and leave it on - for baseline power measurement purposes)"""
|
||||
LED_OFF: PowerStressMessage.Opcode.ValueType # 49
|
||||
"""Force the LED off for num_seconds"""
|
||||
LORA_OFF: PowerStressMessage.Opcode.ValueType # 64
|
||||
"""Completely turn off the LORA radio for num_seconds"""
|
||||
LORA_TX: PowerStressMessage.Opcode.ValueType # 65
|
||||
"""Send Lora packets for num_seconds"""
|
||||
LORA_RX: PowerStressMessage.Opcode.ValueType # 66
|
||||
"""Receive Lora packets for num_seconds (node will be mostly just listening, unless an external agent is helping stress this by sending packets on the current channel)"""
|
||||
BT_OFF: PowerStressMessage.Opcode.ValueType # 80
|
||||
"""Turn off the BT radio for num_seconds"""
|
||||
BT_ON: PowerStressMessage.Opcode.ValueType # 81
|
||||
"""Turn on the BT radio for num_seconds"""
|
||||
WIFI_OFF: PowerStressMessage.Opcode.ValueType # 96
|
||||
"""Turn off the WIFI radio for num_seconds"""
|
||||
WIFI_ON: PowerStressMessage.Opcode.ValueType # 97
|
||||
"""Turn on the WIFI radio for num_seconds"""
|
||||
GPS_OFF: PowerStressMessage.Opcode.ValueType # 112
|
||||
"""Turn off the GPS radio for num_seconds"""
|
||||
GPS_ON: PowerStressMessage.Opcode.ValueType # 113
|
||||
"""Turn on the GPS radio for num_seconds"""
|
||||
|
||||
CMD_FIELD_NUMBER: builtins.int
|
||||
NUM_SECONDS_FIELD_NUMBER: builtins.int
|
||||
cmd: global___PowerStressMessage.Opcode.ValueType
|
||||
"""
|
||||
What type of HardwareMessage is this?
|
||||
"""
|
||||
num_seconds: builtins.float
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
cmd: global___PowerStressMessage.Opcode.ValueType = ...,
|
||||
num_seconds: builtins.float = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["cmd", b"cmd", "num_seconds", b"num_seconds"]) -> None: ...
|
||||
|
||||
global___PowerStressMessage = PowerStressMessage
|
||||
class PowerStressMessage(_message.Message):
|
||||
__slots__ = ["cmd", "num_seconds"]
|
||||
class Opcode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
BT_OFF: PowerStressMessage.Opcode
|
||||
BT_ON: PowerStressMessage.Opcode
|
||||
CMD_FIELD_NUMBER: _ClassVar[int]
|
||||
CPU_DEEPSLEEP: PowerStressMessage.Opcode
|
||||
CPU_FULLON: PowerStressMessage.Opcode
|
||||
CPU_IDLE: PowerStressMessage.Opcode
|
||||
END_QUIET: PowerStressMessage.Opcode
|
||||
FORCE_QUIET: PowerStressMessage.Opcode
|
||||
GPS_OFF: PowerStressMessage.Opcode
|
||||
GPS_ON: PowerStressMessage.Opcode
|
||||
LED_OFF: PowerStressMessage.Opcode
|
||||
LED_ON: PowerStressMessage.Opcode
|
||||
LORA_OFF: PowerStressMessage.Opcode
|
||||
LORA_RX: PowerStressMessage.Opcode
|
||||
LORA_TX: PowerStressMessage.Opcode
|
||||
NUM_SECONDS_FIELD_NUMBER: _ClassVar[int]
|
||||
PRINT_INFO: PowerStressMessage.Opcode
|
||||
SCREEN_OFF: PowerStressMessage.Opcode
|
||||
SCREEN_ON: PowerStressMessage.Opcode
|
||||
UNSET: PowerStressMessage.Opcode
|
||||
WIFI_OFF: PowerStressMessage.Opcode
|
||||
WIFI_ON: PowerStressMessage.Opcode
|
||||
cmd: PowerStressMessage.Opcode
|
||||
num_seconds: float
|
||||
def __init__(self, cmd: _Optional[_Union[PowerStressMessage.Opcode, str]] = ..., num_seconds: _Optional[float] = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/remote_hardware.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,14 +15,14 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n)meshtastic/protobuf/remote_hardware.proto\x12\x13meshtastic.protobuf\"\xdf\x01\n\x0fHardwareMessage\x12\x37\n\x04type\x18\x01 \x01(\x0e\x32).meshtastic.protobuf.HardwareMessage.Type\x12\x11\n\tgpio_mask\x18\x02 \x01(\x04\x12\x12\n\ngpio_value\x18\x03 \x01(\x04\"l\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0f\n\x0bWRITE_GPIOS\x10\x01\x12\x0f\n\x0bWATCH_GPIOS\x10\x02\x12\x11\n\rGPIOS_CHANGED\x10\x03\x12\x0e\n\nREAD_GPIOS\x10\x04\x12\x14\n\x10READ_GPIOS_REPLY\x10\x05\x42\x64\n\x14org.meshtastic.protoB\x0eRemoteHardwareZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.remote_hardware_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.remote_hardware_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\016RemoteHardwareZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_HARDWAREMESSAGE']._serialized_start=67
|
||||
_globals['_HARDWAREMESSAGE']._serialized_end=290
|
||||
_globals['_HARDWAREMESSAGE_TYPE']._serialized_start=182
|
||||
_globals['_HARDWAREMESSAGE_TYPE']._serialized_end=290
|
||||
_HARDWAREMESSAGE._serialized_start=67
|
||||
_HARDWAREMESSAGE._serialized_end=290
|
||||
_HARDWAREMESSAGE_TYPE._serialized_start=182
|
||||
_HARDWAREMESSAGE_TYPE._serialized_end=290
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,126 +1,24 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class HardwareMessage(google.protobuf.message.Message):
|
||||
"""
|
||||
An example app to show off the module system. This message is used for
|
||||
REMOTE_HARDWARE_APP PortNums.
|
||||
Also provides easy remote access to any GPIO.
|
||||
In the future other remote hardware operations can be added based on user interest
|
||||
(i.e. serial output, spi/i2c input/output).
|
||||
FIXME - currently this feature is turned on by default which is dangerous
|
||||
because no security yet (beyond the channel mechanism).
|
||||
It should be off by default and then protected based on some TBD mechanism
|
||||
(a special channel once multichannel support is included?)
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _Type:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _TypeEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[HardwareMessage._Type.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
UNSET: HardwareMessage._Type.ValueType # 0
|
||||
"""
|
||||
Unset/unused
|
||||
"""
|
||||
WRITE_GPIOS: HardwareMessage._Type.ValueType # 1
|
||||
"""
|
||||
Set gpio gpios based on gpio_mask/gpio_value
|
||||
"""
|
||||
WATCH_GPIOS: HardwareMessage._Type.ValueType # 2
|
||||
"""
|
||||
We are now interested in watching the gpio_mask gpios.
|
||||
If the selected gpios change, please broadcast GPIOS_CHANGED.
|
||||
Will implicitly change the gpios requested to be INPUT gpios.
|
||||
"""
|
||||
GPIOS_CHANGED: HardwareMessage._Type.ValueType # 3
|
||||
"""
|
||||
The gpios listed in gpio_mask have changed, the new values are listed in gpio_value
|
||||
"""
|
||||
READ_GPIOS: HardwareMessage._Type.ValueType # 4
|
||||
"""
|
||||
Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated
|
||||
"""
|
||||
READ_GPIOS_REPLY: HardwareMessage._Type.ValueType # 5
|
||||
"""
|
||||
A reply to READ_GPIOS. gpio_mask and gpio_value will be populated
|
||||
"""
|
||||
|
||||
class Type(_Type, metaclass=_TypeEnumTypeWrapper):
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
UNSET: HardwareMessage.Type.ValueType # 0
|
||||
"""
|
||||
Unset/unused
|
||||
"""
|
||||
WRITE_GPIOS: HardwareMessage.Type.ValueType # 1
|
||||
"""
|
||||
Set gpio gpios based on gpio_mask/gpio_value
|
||||
"""
|
||||
WATCH_GPIOS: HardwareMessage.Type.ValueType # 2
|
||||
"""
|
||||
We are now interested in watching the gpio_mask gpios.
|
||||
If the selected gpios change, please broadcast GPIOS_CHANGED.
|
||||
Will implicitly change the gpios requested to be INPUT gpios.
|
||||
"""
|
||||
GPIOS_CHANGED: HardwareMessage.Type.ValueType # 3
|
||||
"""
|
||||
The gpios listed in gpio_mask have changed, the new values are listed in gpio_value
|
||||
"""
|
||||
READ_GPIOS: HardwareMessage.Type.ValueType # 4
|
||||
"""
|
||||
Read the gpios specified in gpio_mask, send back a READ_GPIOS_REPLY reply with gpio_value populated
|
||||
"""
|
||||
READ_GPIOS_REPLY: HardwareMessage.Type.ValueType # 5
|
||||
"""
|
||||
A reply to READ_GPIOS. gpio_mask and gpio_value will be populated
|
||||
"""
|
||||
|
||||
TYPE_FIELD_NUMBER: builtins.int
|
||||
GPIO_MASK_FIELD_NUMBER: builtins.int
|
||||
GPIO_VALUE_FIELD_NUMBER: builtins.int
|
||||
type: global___HardwareMessage.Type.ValueType
|
||||
"""
|
||||
What type of HardwareMessage is this?
|
||||
"""
|
||||
gpio_mask: builtins.int
|
||||
"""
|
||||
What gpios are we changing. Not used for all MessageTypes, see MessageType for details
|
||||
"""
|
||||
gpio_value: builtins.int
|
||||
"""
|
||||
For gpios that were listed in gpio_mask as valid, what are the signal levels for those gpios.
|
||||
Not used for all MessageTypes, see MessageType for details
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
type: global___HardwareMessage.Type.ValueType = ...,
|
||||
gpio_mask: builtins.int = ...,
|
||||
gpio_value: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["gpio_mask", b"gpio_mask", "gpio_value", b"gpio_value", "type", b"type"]) -> None: ...
|
||||
|
||||
global___HardwareMessage = HardwareMessage
|
||||
class HardwareMessage(_message.Message):
|
||||
__slots__ = ["gpio_mask", "gpio_value", "type"]
|
||||
class Type(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
GPIOS_CHANGED: HardwareMessage.Type
|
||||
GPIO_MASK_FIELD_NUMBER: _ClassVar[int]
|
||||
GPIO_VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
READ_GPIOS: HardwareMessage.Type
|
||||
READ_GPIOS_REPLY: HardwareMessage.Type
|
||||
TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
UNSET: HardwareMessage.Type
|
||||
WATCH_GPIOS: HardwareMessage.Type
|
||||
WRITE_GPIOS: HardwareMessage.Type
|
||||
gpio_mask: int
|
||||
gpio_value: int
|
||||
type: HardwareMessage.Type
|
||||
def __init__(self, type: _Optional[_Union[HardwareMessage.Type, str]] = ..., gpio_mask: _Optional[int] = ..., gpio_value: _Optional[int] = ...) -> None: ...
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/rtttl.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,12 +15,12 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/rtttl.proto\x12\x13meshtastic.protobuf\"\x1f\n\x0bRTTTLConfig\x12\x10\n\x08ringtone\x18\x01 \x01(\tBg\n\x14org.meshtastic.protoB\x11RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.rtttl_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.rtttl_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\021RTTTLConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_RTTTLCONFIG']._serialized_start=56
|
||||
_globals['_RTTTLCONFIG']._serialized_end=87
|
||||
_RTTTLCONFIG._serialized_start=56
|
||||
_RTTTLCONFIG._serialized_end=87
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,33 +1,11 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.message
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class RTTTLConfig(google.protobuf.message.Message):
|
||||
"""
|
||||
Canned message module configuration.
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
RINGTONE_FIELD_NUMBER: builtins.int
|
||||
ringtone: builtins.str
|
||||
"""
|
||||
Ringtone for PWM Buzzer in RTTTL Format.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
ringtone: builtins.str = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["ringtone", b"ringtone"]) -> None: ...
|
||||
|
||||
global___RTTTLConfig = RTTTLConfig
|
||||
class RTTTLConfig(_message.Message):
|
||||
__slots__ = ["ringtone"]
|
||||
RINGTONE_FIELD_NUMBER: _ClassVar[int]
|
||||
ringtone: str
|
||||
def __init__(self, ringtone: _Optional[str] = ...) -> None: ...
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/serial_hal.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/serial_hal.proto\x12\x13meshtastic.protobuf\"\xab\x02\n\x10SerialHalCommand\x12\x16\n\x0etransaction_id\x18\x01 \x01(\r\x12\x38\n\x04type\x18\x02 \x01(\x0e\x32*.meshtastic.protobuf.SerialHalCommand.Type\x12\x0b\n\x03pin\x18\x03 \x01(\r\x12\r\n\x05value\x18\x04 \x01(\r\x12\x0c\n\x04mode\x18\x05 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x06 \x01(\x0c\"\x8c\x01\n\x04Type\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08PIN_MODE\x10\x01\x12\x11\n\rDIGITAL_WRITE\x10\x02\x12\x10\n\x0c\x44IGITAL_READ\x10\x03\x12\x14\n\x10\x41TTACH_INTERRUPT\x10\x04\x12\x14\n\x10\x44\x45TACH_INTERRUPT\x10\x05\x12\x10\n\x0cSPI_TRANSFER\x10\x06\x12\x08\n\x04NOOP\x10\x07\"\xd5\x01\n\x11SerialHalResponse\x12\x16\n\x0etransaction_id\x18\x01 \x01(\r\x12=\n\x06result\x18\x02 \x01(\x0e\x32-.meshtastic.protobuf.SerialHalResponse.Result\x12\r\n\x05value\x18\x03 \x01(\r\x12\x0c\n\x04\x64\x61ta\x18\x04 \x01(\x0c\x12\r\n\x05\x65rror\x18\x05 \x01(\t\"=\n\x06Result\x12\x06\n\x02OK\x10\x00\x12\t\n\x05\x45RROR\x10\x01\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10\x02\x12\x0f\n\x0bUNSUPPORTED\x10\x03\x42_\n\x14org.meshtastic.protoB\tSerialHalZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.serial_hal_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\tSerialHalZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_SERIALHALCOMMAND._serialized_start=62
|
||||
_SERIALHALCOMMAND._serialized_end=361
|
||||
_SERIALHALCOMMAND_TYPE._serialized_start=221
|
||||
_SERIALHALCOMMAND_TYPE._serialized_end=361
|
||||
_SERIALHALRESPONSE._serialized_start=364
|
||||
_SERIALHALRESPONSE._serialized_end=577
|
||||
_SERIALHALRESPONSE_RESULT._serialized_start=516
|
||||
_SERIALHALRESPONSE_RESULT._serialized_end=577
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -0,0 +1,52 @@
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
||||
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class SerialHalCommand(_message.Message):
|
||||
__slots__ = ["data", "mode", "pin", "transaction_id", "type", "value"]
|
||||
class Type(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
ATTACH_INTERRUPT: SerialHalCommand.Type
|
||||
DATA_FIELD_NUMBER: _ClassVar[int]
|
||||
DETACH_INTERRUPT: SerialHalCommand.Type
|
||||
DIGITAL_READ: SerialHalCommand.Type
|
||||
DIGITAL_WRITE: SerialHalCommand.Type
|
||||
MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
NOOP: SerialHalCommand.Type
|
||||
PIN_FIELD_NUMBER: _ClassVar[int]
|
||||
PIN_MODE: SerialHalCommand.Type
|
||||
SPI_TRANSFER: SerialHalCommand.Type
|
||||
TRANSACTION_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
UNSET: SerialHalCommand.Type
|
||||
VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
data: bytes
|
||||
mode: int
|
||||
pin: int
|
||||
transaction_id: int
|
||||
type: SerialHalCommand.Type
|
||||
value: int
|
||||
def __init__(self, transaction_id: _Optional[int] = ..., type: _Optional[_Union[SerialHalCommand.Type, str]] = ..., pin: _Optional[int] = ..., value: _Optional[int] = ..., mode: _Optional[int] = ..., data: _Optional[bytes] = ...) -> None: ...
|
||||
|
||||
class SerialHalResponse(_message.Message):
|
||||
__slots__ = ["data", "error", "result", "transaction_id", "value"]
|
||||
class Result(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
BAD_REQUEST: SerialHalResponse.Result
|
||||
DATA_FIELD_NUMBER: _ClassVar[int]
|
||||
ERROR: SerialHalResponse.Result
|
||||
ERROR_FIELD_NUMBER: _ClassVar[int]
|
||||
OK: SerialHalResponse.Result
|
||||
RESULT_FIELD_NUMBER: _ClassVar[int]
|
||||
TRANSACTION_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
UNSUPPORTED: SerialHalResponse.Result
|
||||
VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
data: bytes
|
||||
error: str
|
||||
result: SerialHalResponse.Result
|
||||
transaction_id: int
|
||||
value: int
|
||||
def __init__(self, transaction_id: _Optional[int] = ..., result: _Optional[_Union[SerialHalResponse.Result, str]] = ..., value: _Optional[int] = ..., data: _Optional[bytes] = ..., error: _Optional[str] = ...) -> None: ...
|
||||
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/storeforward.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,20 +15,20 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&meshtastic/protobuf/storeforward.proto\x12\x13meshtastic.protobuf\"\xc0\x07\n\x0fStoreAndForward\x12@\n\x02rr\x18\x01 \x01(\x0e\x32\x34.meshtastic.protobuf.StoreAndForward.RequestResponse\x12@\n\x05stats\x18\x02 \x01(\x0b\x32/.meshtastic.protobuf.StoreAndForward.StatisticsH\x00\x12?\n\x07history\x18\x03 \x01(\x0b\x32,.meshtastic.protobuf.StoreAndForward.HistoryH\x00\x12\x43\n\theartbeat\x18\x04 \x01(\x0b\x32..meshtastic.protobuf.StoreAndForward.HeartbeatH\x00\x12\x0e\n\x04text\x18\x05 \x01(\x0cH\x00\x1a\xcd\x01\n\nStatistics\x12\x16\n\x0emessages_total\x18\x01 \x01(\r\x12\x16\n\x0emessages_saved\x18\x02 \x01(\r\x12\x14\n\x0cmessages_max\x18\x03 \x01(\r\x12\x0f\n\x07up_time\x18\x04 \x01(\r\x12\x10\n\x08requests\x18\x05 \x01(\r\x12\x18\n\x10requests_history\x18\x06 \x01(\r\x12\x11\n\theartbeat\x18\x07 \x01(\x08\x12\x12\n\nreturn_max\x18\x08 \x01(\r\x12\x15\n\rreturn_window\x18\t \x01(\r\x1aI\n\x07History\x12\x18\n\x10history_messages\x18\x01 \x01(\r\x12\x0e\n\x06window\x18\x02 \x01(\r\x12\x14\n\x0clast_request\x18\x03 \x01(\r\x1a.\n\tHeartbeat\x12\x0e\n\x06period\x18\x01 \x01(\r\x12\x11\n\tsecondary\x18\x02 \x01(\r\"\xbc\x02\n\x0fRequestResponse\x12\t\n\x05UNSET\x10\x00\x12\x10\n\x0cROUTER_ERROR\x10\x01\x12\x14\n\x10ROUTER_HEARTBEAT\x10\x02\x12\x0f\n\x0bROUTER_PING\x10\x03\x12\x0f\n\x0bROUTER_PONG\x10\x04\x12\x0f\n\x0bROUTER_BUSY\x10\x05\x12\x12\n\x0eROUTER_HISTORY\x10\x06\x12\x10\n\x0cROUTER_STATS\x10\x07\x12\x16\n\x12ROUTER_TEXT_DIRECT\x10\x08\x12\x19\n\x15ROUTER_TEXT_BROADCAST\x10\t\x12\x10\n\x0c\x43LIENT_ERROR\x10@\x12\x12\n\x0e\x43LIENT_HISTORY\x10\x41\x12\x10\n\x0c\x43LIENT_STATS\x10\x42\x12\x0f\n\x0b\x43LIENT_PING\x10\x43\x12\x0f\n\x0b\x43LIENT_PONG\x10\x44\x12\x10\n\x0c\x43LIENT_ABORT\x10jB\t\n\x07variantBk\n\x14org.meshtastic.protoB\x15StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.storeforward_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.storeforward_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\025StoreAndForwardProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_STOREANDFORWARD']._serialized_start=64
|
||||
_globals['_STOREANDFORWARD']._serialized_end=1024
|
||||
_globals['_STOREANDFORWARD_STATISTICS']._serialized_start=366
|
||||
_globals['_STOREANDFORWARD_STATISTICS']._serialized_end=571
|
||||
_globals['_STOREANDFORWARD_HISTORY']._serialized_start=573
|
||||
_globals['_STOREANDFORWARD_HISTORY']._serialized_end=646
|
||||
_globals['_STOREANDFORWARD_HEARTBEAT']._serialized_start=648
|
||||
_globals['_STOREANDFORWARD_HEARTBEAT']._serialized_end=694
|
||||
_globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_start=697
|
||||
_globals['_STOREANDFORWARD_REQUESTRESPONSE']._serialized_end=1013
|
||||
_STOREANDFORWARD._serialized_start=64
|
||||
_STOREANDFORWARD._serialized_end=1024
|
||||
_STOREANDFORWARD_STATISTICS._serialized_start=366
|
||||
_STOREANDFORWARD_STATISTICS._serialized_end=571
|
||||
_STOREANDFORWARD_HISTORY._serialized_start=573
|
||||
_STOREANDFORWARD_HISTORY._serialized_end=646
|
||||
_STOREANDFORWARD_HEARTBEAT._serialized_start=648
|
||||
_STOREANDFORWARD_HEARTBEAT._serialized_end=694
|
||||
_STOREANDFORWARD_REQUESTRESPONSE._serialized_start=697
|
||||
_STOREANDFORWARD_REQUESTRESPONSE._serialized_end=1013
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,345 +1,75 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class StoreAndForward(google.protobuf.message.Message):
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _RequestResponse:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _RequestResponseEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[StoreAndForward._RequestResponse.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
UNSET: StoreAndForward._RequestResponse.ValueType # 0
|
||||
"""
|
||||
Unset/unused
|
||||
"""
|
||||
ROUTER_ERROR: StoreAndForward._RequestResponse.ValueType # 1
|
||||
"""
|
||||
Router is an in error state.
|
||||
"""
|
||||
ROUTER_HEARTBEAT: StoreAndForward._RequestResponse.ValueType # 2
|
||||
"""
|
||||
Router heartbeat
|
||||
"""
|
||||
ROUTER_PING: StoreAndForward._RequestResponse.ValueType # 3
|
||||
"""
|
||||
Router has requested the client respond. This can work as a
|
||||
"are you there" message.
|
||||
"""
|
||||
ROUTER_PONG: StoreAndForward._RequestResponse.ValueType # 4
|
||||
"""
|
||||
The response to a "Ping"
|
||||
"""
|
||||
ROUTER_BUSY: StoreAndForward._RequestResponse.ValueType # 5
|
||||
"""
|
||||
Router is currently busy. Please try again later.
|
||||
"""
|
||||
ROUTER_HISTORY: StoreAndForward._RequestResponse.ValueType # 6
|
||||
"""
|
||||
Router is responding to a request for history.
|
||||
"""
|
||||
ROUTER_STATS: StoreAndForward._RequestResponse.ValueType # 7
|
||||
"""
|
||||
Router is responding to a request for stats.
|
||||
"""
|
||||
ROUTER_TEXT_DIRECT: StoreAndForward._RequestResponse.ValueType # 8
|
||||
"""
|
||||
Router sends a text message from its history that was a direct message.
|
||||
"""
|
||||
ROUTER_TEXT_BROADCAST: StoreAndForward._RequestResponse.ValueType # 9
|
||||
"""
|
||||
Router sends a text message from its history that was a broadcast.
|
||||
"""
|
||||
CLIENT_ERROR: StoreAndForward._RequestResponse.ValueType # 64
|
||||
"""
|
||||
Client is an in error state.
|
||||
"""
|
||||
CLIENT_HISTORY: StoreAndForward._RequestResponse.ValueType # 65
|
||||
"""
|
||||
Client has requested a replay from the router.
|
||||
"""
|
||||
CLIENT_STATS: StoreAndForward._RequestResponse.ValueType # 66
|
||||
"""
|
||||
Client has requested stats from the router.
|
||||
"""
|
||||
CLIENT_PING: StoreAndForward._RequestResponse.ValueType # 67
|
||||
"""
|
||||
Client has requested the router respond. This can work as a
|
||||
"are you there" message.
|
||||
"""
|
||||
CLIENT_PONG: StoreAndForward._RequestResponse.ValueType # 68
|
||||
"""
|
||||
The response to a "Ping"
|
||||
"""
|
||||
CLIENT_ABORT: StoreAndForward._RequestResponse.ValueType # 106
|
||||
"""
|
||||
Client has requested that the router abort processing the client's request
|
||||
"""
|
||||
|
||||
class RequestResponse(_RequestResponse, metaclass=_RequestResponseEnumTypeWrapper):
|
||||
"""
|
||||
001 - 063 = From Router
|
||||
064 - 127 = From Client
|
||||
"""
|
||||
|
||||
UNSET: StoreAndForward.RequestResponse.ValueType # 0
|
||||
"""
|
||||
Unset/unused
|
||||
"""
|
||||
ROUTER_ERROR: StoreAndForward.RequestResponse.ValueType # 1
|
||||
"""
|
||||
Router is an in error state.
|
||||
"""
|
||||
ROUTER_HEARTBEAT: StoreAndForward.RequestResponse.ValueType # 2
|
||||
"""
|
||||
Router heartbeat
|
||||
"""
|
||||
ROUTER_PING: StoreAndForward.RequestResponse.ValueType # 3
|
||||
"""
|
||||
Router has requested the client respond. This can work as a
|
||||
"are you there" message.
|
||||
"""
|
||||
ROUTER_PONG: StoreAndForward.RequestResponse.ValueType # 4
|
||||
"""
|
||||
The response to a "Ping"
|
||||
"""
|
||||
ROUTER_BUSY: StoreAndForward.RequestResponse.ValueType # 5
|
||||
"""
|
||||
Router is currently busy. Please try again later.
|
||||
"""
|
||||
ROUTER_HISTORY: StoreAndForward.RequestResponse.ValueType # 6
|
||||
"""
|
||||
Router is responding to a request for history.
|
||||
"""
|
||||
ROUTER_STATS: StoreAndForward.RequestResponse.ValueType # 7
|
||||
"""
|
||||
Router is responding to a request for stats.
|
||||
"""
|
||||
ROUTER_TEXT_DIRECT: StoreAndForward.RequestResponse.ValueType # 8
|
||||
"""
|
||||
Router sends a text message from its history that was a direct message.
|
||||
"""
|
||||
ROUTER_TEXT_BROADCAST: StoreAndForward.RequestResponse.ValueType # 9
|
||||
"""
|
||||
Router sends a text message from its history that was a broadcast.
|
||||
"""
|
||||
CLIENT_ERROR: StoreAndForward.RequestResponse.ValueType # 64
|
||||
"""
|
||||
Client is an in error state.
|
||||
"""
|
||||
CLIENT_HISTORY: StoreAndForward.RequestResponse.ValueType # 65
|
||||
"""
|
||||
Client has requested a replay from the router.
|
||||
"""
|
||||
CLIENT_STATS: StoreAndForward.RequestResponse.ValueType # 66
|
||||
"""
|
||||
Client has requested stats from the router.
|
||||
"""
|
||||
CLIENT_PING: StoreAndForward.RequestResponse.ValueType # 67
|
||||
"""
|
||||
Client has requested the router respond. This can work as a
|
||||
"are you there" message.
|
||||
"""
|
||||
CLIENT_PONG: StoreAndForward.RequestResponse.ValueType # 68
|
||||
"""
|
||||
The response to a "Ping"
|
||||
"""
|
||||
CLIENT_ABORT: StoreAndForward.RequestResponse.ValueType # 106
|
||||
"""
|
||||
Client has requested that the router abort processing the client's request
|
||||
"""
|
||||
|
||||
@typing.final
|
||||
class Statistics(google.protobuf.message.Message):
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
MESSAGES_TOTAL_FIELD_NUMBER: builtins.int
|
||||
MESSAGES_SAVED_FIELD_NUMBER: builtins.int
|
||||
MESSAGES_MAX_FIELD_NUMBER: builtins.int
|
||||
UP_TIME_FIELD_NUMBER: builtins.int
|
||||
REQUESTS_FIELD_NUMBER: builtins.int
|
||||
REQUESTS_HISTORY_FIELD_NUMBER: builtins.int
|
||||
HEARTBEAT_FIELD_NUMBER: builtins.int
|
||||
RETURN_MAX_FIELD_NUMBER: builtins.int
|
||||
RETURN_WINDOW_FIELD_NUMBER: builtins.int
|
||||
messages_total: builtins.int
|
||||
"""
|
||||
Number of messages we have ever seen
|
||||
"""
|
||||
messages_saved: builtins.int
|
||||
"""
|
||||
Number of messages we have currently saved our history.
|
||||
"""
|
||||
messages_max: builtins.int
|
||||
"""
|
||||
Maximum number of messages we will save
|
||||
"""
|
||||
up_time: builtins.int
|
||||
"""
|
||||
Router uptime in seconds
|
||||
"""
|
||||
requests: builtins.int
|
||||
"""
|
||||
Number of times any client sent a request to the S&F.
|
||||
"""
|
||||
requests_history: builtins.int
|
||||
"""
|
||||
Number of times the history was requested.
|
||||
"""
|
||||
heartbeat: builtins.bool
|
||||
"""
|
||||
Is the heartbeat enabled on the server?
|
||||
"""
|
||||
return_max: builtins.int
|
||||
"""
|
||||
Maximum number of messages the server will return.
|
||||
"""
|
||||
return_window: builtins.int
|
||||
"""
|
||||
Maximum history window in minutes the server will return messages from.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
messages_total: builtins.int = ...,
|
||||
messages_saved: builtins.int = ...,
|
||||
messages_max: builtins.int = ...,
|
||||
up_time: builtins.int = ...,
|
||||
requests: builtins.int = ...,
|
||||
requests_history: builtins.int = ...,
|
||||
heartbeat: builtins.bool = ...,
|
||||
return_max: builtins.int = ...,
|
||||
return_window: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["heartbeat", b"heartbeat", "messages_max", b"messages_max", "messages_saved", b"messages_saved", "messages_total", b"messages_total", "requests", b"requests", "requests_history", b"requests_history", "return_max", b"return_max", "return_window", b"return_window", "up_time", b"up_time"]) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class History(google.protobuf.message.Message):
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
HISTORY_MESSAGES_FIELD_NUMBER: builtins.int
|
||||
WINDOW_FIELD_NUMBER: builtins.int
|
||||
LAST_REQUEST_FIELD_NUMBER: builtins.int
|
||||
history_messages: builtins.int
|
||||
"""
|
||||
Number of that will be sent to the client
|
||||
"""
|
||||
window: builtins.int
|
||||
"""
|
||||
The window of messages that was used to filter the history client requested
|
||||
"""
|
||||
last_request: builtins.int
|
||||
"""
|
||||
Index in the packet history of the last message sent in a previous request to the server.
|
||||
Will be sent to the client before sending the history and can be set in a subsequent request to avoid getting packets the server already sent to the client.
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
history_messages: builtins.int = ...,
|
||||
window: builtins.int = ...,
|
||||
last_request: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["history_messages", b"history_messages", "last_request", b"last_request", "window", b"window"]) -> None: ...
|
||||
|
||||
@typing.final
|
||||
class Heartbeat(google.protobuf.message.Message):
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
PERIOD_FIELD_NUMBER: builtins.int
|
||||
SECONDARY_FIELD_NUMBER: builtins.int
|
||||
period: builtins.int
|
||||
"""
|
||||
Period in seconds that the heartbeat is sent out that will be sent to the client
|
||||
"""
|
||||
secondary: builtins.int
|
||||
"""
|
||||
If set, this is not the primary Store & Forward router on the mesh
|
||||
"""
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
period: builtins.int = ...,
|
||||
secondary: builtins.int = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["period", b"period", "secondary", b"secondary"]) -> None: ...
|
||||
|
||||
RR_FIELD_NUMBER: builtins.int
|
||||
STATS_FIELD_NUMBER: builtins.int
|
||||
HISTORY_FIELD_NUMBER: builtins.int
|
||||
HEARTBEAT_FIELD_NUMBER: builtins.int
|
||||
TEXT_FIELD_NUMBER: builtins.int
|
||||
rr: global___StoreAndForward.RequestResponse.ValueType
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
text: builtins.bytes
|
||||
"""
|
||||
Text from history message.
|
||||
"""
|
||||
@property
|
||||
def stats(self) -> global___StoreAndForward.Statistics:
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
@property
|
||||
def history(self) -> global___StoreAndForward.History:
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
@property
|
||||
def heartbeat(self) -> global___StoreAndForward.Heartbeat:
|
||||
"""
|
||||
TODO: REPLACE
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
rr: global___StoreAndForward.RequestResponse.ValueType = ...,
|
||||
stats: global___StoreAndForward.Statistics | None = ...,
|
||||
history: global___StoreAndForward.History | None = ...,
|
||||
heartbeat: global___StoreAndForward.Heartbeat | None = ...,
|
||||
text: builtins.bytes = ...,
|
||||
) -> None: ...
|
||||
def HasField(self, field_name: typing.Literal["heartbeat", b"heartbeat", "history", b"history", "stats", b"stats", "text", b"text", "variant", b"variant"]) -> builtins.bool: ...
|
||||
def ClearField(self, field_name: typing.Literal["heartbeat", b"heartbeat", "history", b"history", "rr", b"rr", "stats", b"stats", "text", b"text", "variant", b"variant"]) -> None: ...
|
||||
def WhichOneof(self, oneof_group: typing.Literal["variant", b"variant"]) -> typing.Literal["stats", "history", "heartbeat", "text"] | None: ...
|
||||
|
||||
global___StoreAndForward = StoreAndForward
|
||||
class StoreAndForward(_message.Message):
|
||||
__slots__ = ["heartbeat", "history", "rr", "stats", "text"]
|
||||
class RequestResponse(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class Heartbeat(_message.Message):
|
||||
__slots__ = ["period", "secondary"]
|
||||
PERIOD_FIELD_NUMBER: _ClassVar[int]
|
||||
SECONDARY_FIELD_NUMBER: _ClassVar[int]
|
||||
period: int
|
||||
secondary: int
|
||||
def __init__(self, period: _Optional[int] = ..., secondary: _Optional[int] = ...) -> None: ...
|
||||
class History(_message.Message):
|
||||
__slots__ = ["history_messages", "last_request", "window"]
|
||||
HISTORY_MESSAGES_FIELD_NUMBER: _ClassVar[int]
|
||||
LAST_REQUEST_FIELD_NUMBER: _ClassVar[int]
|
||||
WINDOW_FIELD_NUMBER: _ClassVar[int]
|
||||
history_messages: int
|
||||
last_request: int
|
||||
window: int
|
||||
def __init__(self, history_messages: _Optional[int] = ..., window: _Optional[int] = ..., last_request: _Optional[int] = ...) -> None: ...
|
||||
class Statistics(_message.Message):
|
||||
__slots__ = ["heartbeat", "messages_max", "messages_saved", "messages_total", "requests", "requests_history", "return_max", "return_window", "up_time"]
|
||||
HEARTBEAT_FIELD_NUMBER: _ClassVar[int]
|
||||
MESSAGES_MAX_FIELD_NUMBER: _ClassVar[int]
|
||||
MESSAGES_SAVED_FIELD_NUMBER: _ClassVar[int]
|
||||
MESSAGES_TOTAL_FIELD_NUMBER: _ClassVar[int]
|
||||
REQUESTS_FIELD_NUMBER: _ClassVar[int]
|
||||
REQUESTS_HISTORY_FIELD_NUMBER: _ClassVar[int]
|
||||
RETURN_MAX_FIELD_NUMBER: _ClassVar[int]
|
||||
RETURN_WINDOW_FIELD_NUMBER: _ClassVar[int]
|
||||
UP_TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
heartbeat: bool
|
||||
messages_max: int
|
||||
messages_saved: int
|
||||
messages_total: int
|
||||
requests: int
|
||||
requests_history: int
|
||||
return_max: int
|
||||
return_window: int
|
||||
up_time: int
|
||||
def __init__(self, messages_total: _Optional[int] = ..., messages_saved: _Optional[int] = ..., messages_max: _Optional[int] = ..., up_time: _Optional[int] = ..., requests: _Optional[int] = ..., requests_history: _Optional[int] = ..., heartbeat: bool = ..., return_max: _Optional[int] = ..., return_window: _Optional[int] = ...) -> None: ...
|
||||
CLIENT_ABORT: StoreAndForward.RequestResponse
|
||||
CLIENT_ERROR: StoreAndForward.RequestResponse
|
||||
CLIENT_HISTORY: StoreAndForward.RequestResponse
|
||||
CLIENT_PING: StoreAndForward.RequestResponse
|
||||
CLIENT_PONG: StoreAndForward.RequestResponse
|
||||
CLIENT_STATS: StoreAndForward.RequestResponse
|
||||
HEARTBEAT_FIELD_NUMBER: _ClassVar[int]
|
||||
HISTORY_FIELD_NUMBER: _ClassVar[int]
|
||||
ROUTER_BUSY: StoreAndForward.RequestResponse
|
||||
ROUTER_ERROR: StoreAndForward.RequestResponse
|
||||
ROUTER_HEARTBEAT: StoreAndForward.RequestResponse
|
||||
ROUTER_HISTORY: StoreAndForward.RequestResponse
|
||||
ROUTER_PING: StoreAndForward.RequestResponse
|
||||
ROUTER_PONG: StoreAndForward.RequestResponse
|
||||
ROUTER_STATS: StoreAndForward.RequestResponse
|
||||
ROUTER_TEXT_BROADCAST: StoreAndForward.RequestResponse
|
||||
ROUTER_TEXT_DIRECT: StoreAndForward.RequestResponse
|
||||
RR_FIELD_NUMBER: _ClassVar[int]
|
||||
STATS_FIELD_NUMBER: _ClassVar[int]
|
||||
TEXT_FIELD_NUMBER: _ClassVar[int]
|
||||
UNSET: StoreAndForward.RequestResponse
|
||||
heartbeat: StoreAndForward.Heartbeat
|
||||
history: StoreAndForward.History
|
||||
rr: StoreAndForward.RequestResponse
|
||||
stats: StoreAndForward.Statistics
|
||||
text: bytes
|
||||
def __init__(self, rr: _Optional[_Union[StoreAndForward.RequestResponse, str]] = ..., stats: _Optional[_Union[StoreAndForward.Statistics, _Mapping]] = ..., history: _Optional[_Union[StoreAndForward.History, _Mapping]] = ..., heartbeat: _Optional[_Union[StoreAndForward.Heartbeat, _Mapping]] = ..., text: _Optional[bytes] = ...) -> None: ...
|
||||
|
||||
File diff suppressed because one or more lines are too long
+335
-1330
File diff suppressed because it is too large
Load Diff
@@ -2,10 +2,10 @@
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/xmodem.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
from google.protobuf.internal import builder as _builder
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
@@ -15,14 +15,14 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/xmodem.proto\x12\x13meshtastic.protobuf\"\xbf\x01\n\x06XModem\x12\x34\n\x07\x63ontrol\x18\x01 \x01(\x0e\x32#.meshtastic.protobuf.XModem.Control\x12\x0b\n\x03seq\x18\x02 \x01(\r\x12\r\n\x05\x63rc16\x18\x03 \x01(\r\x12\x0e\n\x06\x62uffer\x18\x04 \x01(\x0c\"S\n\x07\x43ontrol\x12\x07\n\x03NUL\x10\x00\x12\x07\n\x03SOH\x10\x01\x12\x07\n\x03STX\x10\x02\x12\x07\n\x03\x45OT\x10\x04\x12\x07\n\x03\x41\x43K\x10\x06\x12\x07\n\x03NAK\x10\x15\x12\x07\n\x03\x43\x41N\x10\x18\x12\t\n\x05\x43TRLZ\x10\x1a\x42\x62\n\x14org.meshtastic.protoB\x0cXmodemProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_globals = globals()
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.xmodem_pb2', _globals)
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.xmodem_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\014XmodemProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_globals['_XMODEM']._serialized_start=58
|
||||
_globals['_XMODEM']._serialized_end=249
|
||||
_globals['_XMODEM_CONTROL']._serialized_start=166
|
||||
_globals['_XMODEM_CONTROL']._serialized_end=249
|
||||
_XMODEM._serialized_start=58
|
||||
_XMODEM._serialized_end=249
|
||||
_XMODEM_CONTROL._serialized_start=166
|
||||
_XMODEM_CONTROL._serialized_end=249
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
|
||||
@@ -1,67 +1,28 @@
|
||||
"""
|
||||
@generated by mypy-protobuf. Do not edit manually!
|
||||
isort:skip_file
|
||||
"""
|
||||
from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
|
||||
|
||||
import builtins
|
||||
import google.protobuf.descriptor
|
||||
import google.protobuf.internal.enum_type_wrapper
|
||||
import google.protobuf.message
|
||||
import sys
|
||||
import typing
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
if sys.version_info >= (3, 10):
|
||||
import typing as typing_extensions
|
||||
else:
|
||||
import typing_extensions
|
||||
|
||||
DESCRIPTOR: google.protobuf.descriptor.FileDescriptor
|
||||
|
||||
@typing.final
|
||||
class XModem(google.protobuf.message.Message):
|
||||
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
||||
|
||||
class _Control:
|
||||
ValueType = typing.NewType("ValueType", builtins.int)
|
||||
V: typing_extensions.TypeAlias = ValueType
|
||||
|
||||
class _ControlEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[XModem._Control.ValueType], builtins.type):
|
||||
DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
|
||||
NUL: XModem._Control.ValueType # 0
|
||||
SOH: XModem._Control.ValueType # 1
|
||||
STX: XModem._Control.ValueType # 2
|
||||
EOT: XModem._Control.ValueType # 4
|
||||
ACK: XModem._Control.ValueType # 6
|
||||
NAK: XModem._Control.ValueType # 21
|
||||
CAN: XModem._Control.ValueType # 24
|
||||
CTRLZ: XModem._Control.ValueType # 26
|
||||
|
||||
class Control(_Control, metaclass=_ControlEnumTypeWrapper): ...
|
||||
NUL: XModem.Control.ValueType # 0
|
||||
SOH: XModem.Control.ValueType # 1
|
||||
STX: XModem.Control.ValueType # 2
|
||||
EOT: XModem.Control.ValueType # 4
|
||||
ACK: XModem.Control.ValueType # 6
|
||||
NAK: XModem.Control.ValueType # 21
|
||||
CAN: XModem.Control.ValueType # 24
|
||||
CTRLZ: XModem.Control.ValueType # 26
|
||||
|
||||
CONTROL_FIELD_NUMBER: builtins.int
|
||||
SEQ_FIELD_NUMBER: builtins.int
|
||||
CRC16_FIELD_NUMBER: builtins.int
|
||||
BUFFER_FIELD_NUMBER: builtins.int
|
||||
control: global___XModem.Control.ValueType
|
||||
seq: builtins.int
|
||||
crc16: builtins.int
|
||||
buffer: builtins.bytes
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
control: global___XModem.Control.ValueType = ...,
|
||||
seq: builtins.int = ...,
|
||||
crc16: builtins.int = ...,
|
||||
buffer: builtins.bytes = ...,
|
||||
) -> None: ...
|
||||
def ClearField(self, field_name: typing.Literal["buffer", b"buffer", "control", b"control", "crc16", b"crc16", "seq", b"seq"]) -> None: ...
|
||||
|
||||
global___XModem = XModem
|
||||
class XModem(_message.Message):
|
||||
__slots__ = ["buffer", "control", "crc16", "seq"]
|
||||
class Control(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
ACK: XModem.Control
|
||||
BUFFER_FIELD_NUMBER: _ClassVar[int]
|
||||
CAN: XModem.Control
|
||||
CONTROL_FIELD_NUMBER: _ClassVar[int]
|
||||
CRC16_FIELD_NUMBER: _ClassVar[int]
|
||||
CTRLZ: XModem.Control
|
||||
EOT: XModem.Control
|
||||
NAK: XModem.Control
|
||||
NUL: XModem.Control
|
||||
SEQ_FIELD_NUMBER: _ClassVar[int]
|
||||
SOH: XModem.Control
|
||||
STX: XModem.Control
|
||||
buffer: bytes
|
||||
control: XModem.Control
|
||||
crc16: int
|
||||
seq: int
|
||||
def __init__(self, control: _Optional[_Union[XModem.Control, str]] = ..., seq: _Optional[int] = ..., crc16: _Optional[int] = ..., buffer: _Optional[bytes] = ...) -> None: ...
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
__version__ = "3.0.6"
|
||||
__release_date__ = "2026-3-6"
|
||||
__version__ = "3.0.8"
|
||||
__release_date__ = "2026-5-12"
|
||||
|
||||
|
||||
def get_git_revision():
|
||||
|
||||
@@ -159,6 +159,7 @@
|
||||
"times_seen": "Seen (24h)",
|
||||
"avg_gateways": "Avg Gateways",
|
||||
"showing_nodes": "Showing",
|
||||
"all_channels": "All Channels",
|
||||
"nodes_suffix": "nodes"
|
||||
},
|
||||
|
||||
@@ -243,7 +244,6 @@
|
||||
"share_contact_qr": "Share Contact QR",
|
||||
"copy_url": "Copy URL",
|
||||
"copied": "Copied!",
|
||||
"potential_impersonation": "Potential Impersonation Detected",
|
||||
"scan_qr_to_add": "Scan this QR code to add this node as a contact on another device."
|
||||
},
|
||||
"packet": {
|
||||
|
||||
@@ -155,6 +155,7 @@
|
||||
"times_seen": "Visto (24h)",
|
||||
"avg_gateways": "Promedio de Gateways",
|
||||
"showing_nodes": "Mostrando",
|
||||
"all_channels": "Todos los Canales",
|
||||
"nodes_suffix": "nodos"
|
||||
},
|
||||
|
||||
@@ -229,7 +230,6 @@
|
||||
"share_contact_qr": "Compartir contacto QR",
|
||||
"copy_url": "Copiar URL",
|
||||
"copied": "¡Copiado!",
|
||||
"potential_impersonation": "Posible suplantación detectada",
|
||||
"scan_qr_to_add": "Escanea este código QR para agregar este nodo como contacto en otro dispositivo."
|
||||
},
|
||||
|
||||
|
||||
@@ -145,6 +145,7 @@
|
||||
"times_seen": "Принято (24ч)",
|
||||
"avg_gateways": "Среднее количество шлюзов",
|
||||
"showing_nodes": "Показать",
|
||||
"all_channels": "Все каналы",
|
||||
"nodes_suffix": "ноды"
|
||||
},
|
||||
"nodegraph": {
|
||||
@@ -224,7 +225,6 @@
|
||||
"share_contact_qr": "Поделиться QR контакта",
|
||||
"copy_url": "Копировать URL",
|
||||
"copied": "Скопировано!",
|
||||
"potential_impersonation": "Обнаружено возможное самозванство",
|
||||
"scan_qr_to_add": "Отсканируйте этот QR-код, чтобы добавить эту ноду в качестве контакта на другом устройстве."
|
||||
},
|
||||
"packet": {
|
||||
|
||||
@@ -108,21 +108,6 @@ class Traceroute(Base):
|
||||
)
|
||||
|
||||
|
||||
class NodePublicKey(Base):
|
||||
__tablename__ = "node_public_key"
|
||||
|
||||
id: Mapped[int] = mapped_column(primary_key=True, autoincrement=True)
|
||||
node_id: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
||||
public_key: Mapped[str] = mapped_column(nullable=False)
|
||||
first_seen_us: Mapped[int] = mapped_column(BigInteger, nullable=True)
|
||||
last_seen_us: Mapped[int] = mapped_column(BigInteger, nullable=True)
|
||||
|
||||
__table_args__ = (
|
||||
Index("idx_node_public_key_node_id", "node_id"),
|
||||
Index("idx_node_public_key_public_key", "public_key"),
|
||||
)
|
||||
|
||||
|
||||
class DailySnapshot(Base):
|
||||
__tablename__ = "daily_snapshot"
|
||||
|
||||
|
||||
+43
-32
@@ -12,11 +12,39 @@ from meshtastic.protobuf.config_pb2 import Config
|
||||
from meshtastic.protobuf.mesh_pb2 import HardwareModel
|
||||
from meshtastic.protobuf.portnums_pb2 import PortNum
|
||||
from meshview import decode_payload, mqtt_database
|
||||
from meshview.models import DailySnapshot, Node, NodePublicKey, Packet, PacketSeen, Traceroute
|
||||
from meshview.models import DailySnapshot, Node, Packet, PacketSeen, Traceroute
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
MQTT_GATEWAY_CACHE: set[int] = set()
|
||||
UNKNOWN_NODE_NAME = "unknown name"
|
||||
NODE_NAME_CONTROL_CHARS = re.compile(r"[\x00-\x1f\x7f]")
|
||||
MQTT_DIRECT_NODE_ID = 1
|
||||
|
||||
|
||||
def normalize_node_name(name: str) -> str:
|
||||
name = name.strip()
|
||||
if not name or NODE_NAME_CONTROL_CHARS.search(name):
|
||||
return UNKNOWN_NODE_NAME
|
||||
return name
|
||||
|
||||
|
||||
def storage_packet_id(packet) -> int | None:
|
||||
if packet.id:
|
||||
return packet.id
|
||||
|
||||
if packet.decoded.portnum != PortNum.MAP_REPORT_APP:
|
||||
return None
|
||||
|
||||
from_node_id = getattr(packet, "from", 0) or 0
|
||||
now_us = int(time.time() * 1_000_000)
|
||||
return -(now_us * 2048 + (from_node_id & 0x7FF))
|
||||
|
||||
|
||||
def storage_to_node_id(packet) -> int:
|
||||
if packet.decoded.portnum == PortNum.MAP_REPORT_APP:
|
||||
return MQTT_DIRECT_NODE_ID
|
||||
return packet.to
|
||||
|
||||
|
||||
async def capture_daily_snapshot() -> None:
|
||||
@@ -109,7 +137,8 @@ async def process_envelope(topic, env):
|
||||
node.short_name = map_report.short_name
|
||||
node.hw_model = hw_model
|
||||
node.role = role
|
||||
node.channel = env.channel_id
|
||||
if not node.channel:
|
||||
node.channel = env.channel_id
|
||||
node.last_lat = map_report.latitude_i
|
||||
node.last_long = map_report.longitude_i
|
||||
node.firmware = map_report.firmware_version
|
||||
@@ -137,20 +166,21 @@ async def process_envelope(topic, env):
|
||||
|
||||
await session.commit()
|
||||
|
||||
if not env.packet.id:
|
||||
packet_id = storage_packet_id(env.packet)
|
||||
if packet_id is None:
|
||||
return
|
||||
|
||||
async with mqtt_database.async_session() as session:
|
||||
# --- Packet insert with ON CONFLICT DO NOTHING
|
||||
result = await session.execute(select(Packet).where(Packet.id == env.packet.id))
|
||||
result = await session.execute(select(Packet).where(Packet.id == packet_id))
|
||||
packet = result.scalar_one_or_none()
|
||||
if not packet:
|
||||
now_us = int(time.time() * 1_000_000)
|
||||
packet_values = {
|
||||
"id": env.packet.id,
|
||||
"id": packet_id,
|
||||
"portnum": env.packet.decoded.portnum,
|
||||
"from_node_id": getattr(env.packet, "from"),
|
||||
"to_node_id": env.packet.to,
|
||||
"to_node_id": storage_to_node_id(env.packet),
|
||||
"payload": env.packet.SerializeToString(),
|
||||
"import_time_us": now_us,
|
||||
"channel": env.channel_id,
|
||||
@@ -198,7 +228,7 @@ async def process_envelope(topic, env):
|
||||
|
||||
now_us = int(time.time() * 1_000_000)
|
||||
seen_values = {
|
||||
"packet_id": env.packet.id,
|
||||
"packet_id": packet_id,
|
||||
"node_id": int(env.gateway_id[1:], 16),
|
||||
"channel": env.channel_id,
|
||||
"rx_time": env.packet.rx_time,
|
||||
@@ -267,11 +297,13 @@ async def process_envelope(topic, env):
|
||||
).scalar_one_or_none()
|
||||
|
||||
now_us = int(time.time() * 1_000_000)
|
||||
long_name = normalize_node_name(user.long_name)
|
||||
short_name = normalize_node_name(user.short_name)
|
||||
|
||||
if node:
|
||||
node.node_id = node_id
|
||||
node.long_name = user.long_name
|
||||
node.short_name = user.short_name
|
||||
node.long_name = long_name
|
||||
node.short_name = short_name
|
||||
node.hw_model = hw_model
|
||||
node.role = role
|
||||
node.channel = env.channel_id
|
||||
@@ -282,8 +314,8 @@ async def process_envelope(topic, env):
|
||||
node = Node(
|
||||
id=user.id,
|
||||
node_id=node_id,
|
||||
long_name=user.long_name,
|
||||
short_name=user.short_name,
|
||||
long_name=long_name,
|
||||
short_name=short_name,
|
||||
hw_model=hw_model,
|
||||
role=role,
|
||||
channel=env.channel_id,
|
||||
@@ -292,27 +324,6 @@ async def process_envelope(topic, env):
|
||||
)
|
||||
session.add(node)
|
||||
|
||||
if user.public_key:
|
||||
public_key_hex = user.public_key.hex()
|
||||
existing_key = (
|
||||
await session.execute(
|
||||
select(NodePublicKey).where(
|
||||
NodePublicKey.node_id == node_id,
|
||||
NodePublicKey.public_key == public_key_hex,
|
||||
)
|
||||
)
|
||||
).scalar_one_or_none()
|
||||
|
||||
if existing_key:
|
||||
existing_key.last_seen_us = now_us
|
||||
else:
|
||||
new_key = NodePublicKey(
|
||||
node_id=node_id,
|
||||
public_key=public_key_hex,
|
||||
first_seen_us=now_us,
|
||||
last_seen_us=now_us,
|
||||
)
|
||||
session.add(new_key)
|
||||
except Exception as e:
|
||||
print(f"Error processing NODEINFO_APP: {e}")
|
||||
|
||||
|
||||
@@ -241,7 +241,7 @@ function logPacketTimes(packet) {
|
||||
const times = formatTimes(packet.import_time_us);
|
||||
console.log(
|
||||
"[firehose] packet time",
|
||||
"id=" + packet.id,
|
||||
"id=" + (packet.packet_id ?? packet.id),
|
||||
"epoch_us=" + times.epoch,
|
||||
"local=" + times.local,
|
||||
"utc=" + times.utc
|
||||
@@ -365,13 +365,21 @@ async function fetchUpdates() {
|
||||
if (match) traceId = match[1];
|
||||
|
||||
inlineLinks += ` <a class="inline-link"
|
||||
href="/graph/traceroute/${traceId}"
|
||||
target="_blank">⮕</a>`;
|
||||
href="/traceroute/${traceId}"
|
||||
>⮕</a>`;
|
||||
}
|
||||
|
||||
const safePayload = (pkt.payload || "")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">");
|
||||
const packetIdCell = pkt.packet_id
|
||||
? `<a href="/packet/${pkt.storage_id || pkt.id}"
|
||||
style="text-decoration:underline; color:inherit;">
|
||||
${pkt.packet_id}
|
||||
</a>`
|
||||
: pkt.portnum === 73
|
||||
? `<span class="text-secondary" title="MQTT map report">Not at Packet</span>`
|
||||
: `<span class="text-secondary" title="No Meshtastic packet ID">—</span>`;
|
||||
|
||||
const html = `
|
||||
<tr class="packet-row">
|
||||
@@ -382,10 +390,7 @@ async function fetchUpdates() {
|
||||
|
||||
<td>
|
||||
<span class="toggle-btn">▶</span>
|
||||
<a href="/packet/${pkt.id}"
|
||||
style="text-decoration:underline; color:inherit;">
|
||||
${pkt.id}
|
||||
</a>
|
||||
${packetIdCell}
|
||||
</td>
|
||||
|
||||
<td>${from}</td>
|
||||
|
||||
+165
-22
@@ -148,6 +148,7 @@
|
||||
<script src="https://unpkg.com/leaflet-polylinedecorator@1.6.0/dist/leaflet.polylinedecorator.js"
|
||||
integrity="sha384-FhPn/2P/fJGhQLeNWDn9B/2Gml2bPOrKJwFqJXgR3xOPYxWg5mYQ5XZdhUSugZT0"
|
||||
crossorigin></script>
|
||||
<script src="https://unpkg.com/leaflet.heat/dist/leaflet-heat.js"></script>
|
||||
<script src="/static/portmaps.js"></script>
|
||||
|
||||
<script>
|
||||
@@ -188,25 +189,71 @@ function applyTranslationsMap(root = document) {
|
||||
====================================================== */
|
||||
|
||||
var map = L.map('map');
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
{ maxZoom:19, attribution:'© OpenStreetMap' }).addTo(map);
|
||||
var baseLayers = {
|
||||
"OpenStreetMap": L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© OpenStreetMap'
|
||||
}),
|
||||
"OpenTopoMap": L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 17,
|
||||
attribution: 'Map data: © OpenStreetMap, SRTM | Map style: © OpenTopoMap'
|
||||
})
|
||||
};
|
||||
baseLayers["OpenStreetMap"].addTo(map);
|
||||
L.control.scale({
|
||||
position: 'bottomleft',
|
||||
metric: true,
|
||||
imperial: true
|
||||
}).addTo(map);
|
||||
var nodeLayer = L.layerGroup().addTo(map);
|
||||
var edgeLayer = L.layerGroup().addTo(map);
|
||||
var trafficHeatLayer = L.heatLayer([], {
|
||||
radius: 34,
|
||||
blur: 18,
|
||||
maxZoom: 12,
|
||||
minOpacity: 0.3,
|
||||
gradient: {
|
||||
0.2: "#0b1f4d",
|
||||
0.45: "#12436b",
|
||||
0.7: "#7f2704",
|
||||
1.0: "#4d0000"
|
||||
}
|
||||
});
|
||||
var overlayLayers = {
|
||||
"Nodes": nodeLayer,
|
||||
"Traffic HeatMap": trafficHeatLayer
|
||||
};
|
||||
L.control.layers(baseLayers, overlayLayers, { collapsed: false }).addTo(map);
|
||||
|
||||
// Data structures
|
||||
var nodes = [], markers = {}, markerById = {}, nodeMap = new Map();
|
||||
var edgeLayer = L.layerGroup().addTo(map), selectedNodeId = null;
|
||||
var selectedNodeId = null;
|
||||
var activeBlinks = new Map(), lastImportTime = null;
|
||||
var mapInterval = 0;
|
||||
var unmappedPackets = [];
|
||||
var trafficHeatLoaded = false;
|
||||
var trafficHeatLoading = false;
|
||||
const UNMAPPED_LIMIT = 50;
|
||||
const UNMAPPED_TTL_MS = 5000;
|
||||
|
||||
const portMap = window.PORT_LABEL_MAP;
|
||||
|
||||
const palette = ["#e6194b","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe",
|
||||
"#008080","#e6beff","#9a6324","#fffac8","#800000","#aaffc3","#808000","#ffd8b1",
|
||||
"#000075","#808080"];
|
||||
const palette = ["#bcf60c","#fabebe","#e6beff","#9a6324","#fffac8","#800000","#aaffc3","#ffd8b1",
|
||||
"#808080"];
|
||||
|
||||
const colorMap = new Map(); let nextColorIndex = 0;
|
||||
const channelColorOverrides = {
|
||||
longfast: "#4363d8",
|
||||
longslow: "#000075",
|
||||
verylongslow: "#808000",
|
||||
mediumslow: "#008080",
|
||||
mediumfast: "#e6194b",
|
||||
shortslow: "#911eb4",
|
||||
shortfast: "#f58231",
|
||||
longmoderate: "#46f0f0",
|
||||
shortturbo: "#f032e6"
|
||||
};
|
||||
|
||||
const colorMap = new Map();
|
||||
const channelSet = new Set();
|
||||
|
||||
map.on("popupopen", function (e) {
|
||||
@@ -221,10 +268,17 @@ function timeAgoFromUs(us){
|
||||
return d>0?d+"d":h>0?h+"h":m>0?m+"m":s+"s";
|
||||
}
|
||||
|
||||
function normalizeChannelName(str){
|
||||
return String(str || "Unknown").toLowerCase().replace(/[\s_-]+/g, "");
|
||||
}
|
||||
|
||||
function hashToColor(str){
|
||||
if(colorMap.has(str)) return colorMap.get(str);
|
||||
const c = palette[nextColorIndex++ % palette.length];
|
||||
colorMap.set(str,c);
|
||||
const channel = String(str || "Unknown");
|
||||
if(colorMap.has(channel)) return colorMap.get(channel);
|
||||
|
||||
const override = channelColorOverrides[normalizeChannelName(channel)];
|
||||
const c = override || palette[Math.floor(hashToUnit(channel) * palette.length) % palette.length];
|
||||
colorMap.set(channel,c);
|
||||
return c;
|
||||
}
|
||||
|
||||
@@ -366,6 +420,15 @@ document.addEventListener("visibilitychange",()=>{
|
||||
document.hidden?stopPacketFetcher():startPacketFetcher();
|
||||
});
|
||||
|
||||
map.on("overlayadd", e => {
|
||||
if(e.layer === nodeLayer) updateNodeVisibility();
|
||||
if(e.layer === trafficHeatLayer) loadTrafficHeat();
|
||||
});
|
||||
|
||||
map.on("overlayremove", e => {
|
||||
if(e.layer === nodeLayer) clearActiveBlinks();
|
||||
});
|
||||
|
||||
async function waitForConfig() {
|
||||
while (typeof window._siteConfigPromise === "undefined") {
|
||||
await new Promise(r => setTimeout(r, 100));
|
||||
@@ -447,6 +510,9 @@ fetch('/api/nodes?days_active=3')
|
||||
|
||||
renderNodesOnMap();
|
||||
createChannelFilters();
|
||||
if(map.hasLayer(trafficHeatLayer)){
|
||||
loadTrafficHeat();
|
||||
}
|
||||
})
|
||||
.catch(console.error);
|
||||
|
||||
@@ -467,7 +533,7 @@ function renderNodesOnMap(){
|
||||
fillColor: color,
|
||||
fillOpacity: 1,
|
||||
weight: 0.7
|
||||
}).addTo(map);
|
||||
}).addTo(nodeLayer);
|
||||
|
||||
marker.nodeId = node.key;
|
||||
marker.originalColor = color;
|
||||
@@ -490,6 +556,56 @@ function renderNodesOnMap(){
|
||||
setTimeout(() => applyTranslationsMap(), 50);
|
||||
}
|
||||
|
||||
/* ======================================================
|
||||
TRAFFIC HEAT LAYER
|
||||
====================================================== */
|
||||
|
||||
async function loadTrafficHeat(){
|
||||
if(trafficHeatLoaded || trafficHeatLoading) return;
|
||||
if(nodeMap.size === 0) return;
|
||||
|
||||
trafficHeatLoading = true;
|
||||
|
||||
try {
|
||||
const url = new URL("/api/packets", window.location.origin);
|
||||
url.searchParams.set("limit", 1000);
|
||||
|
||||
const res = await fetch(url);
|
||||
if(!res.ok) return;
|
||||
|
||||
const data = await res.json();
|
||||
const counts = new Map();
|
||||
|
||||
(data.packets || []).forEach(pkt => {
|
||||
const nodeId = pkt.from_node_id;
|
||||
if(nodeId == null) return;
|
||||
counts.set(nodeId, (counts.get(nodeId) || 0) + 1);
|
||||
});
|
||||
|
||||
const maxCount = Math.max(...counts.values(), 0);
|
||||
const heatPoints = [];
|
||||
|
||||
counts.forEach((count, nodeId) => {
|
||||
const node = nodeMap.get(nodeId);
|
||||
if(!node || isInvalidCoord(node)) return;
|
||||
|
||||
const markerLatLng = markerById[nodeId]?.getLatLng();
|
||||
const lat = markerLatLng?.lat ?? node.lat;
|
||||
const lng = markerLatLng?.lng ?? node.long;
|
||||
const intensity = maxCount > 0 ? count / maxCount : 0;
|
||||
|
||||
heatPoints.push([lat, lng, Math.max(0.15, intensity)]);
|
||||
});
|
||||
|
||||
trafficHeatLayer.setLatLngs(heatPoints);
|
||||
trafficHeatLoaded = true;
|
||||
} catch(err) {
|
||||
console.error("Failed to load traffic heat layer:", err);
|
||||
} finally {
|
||||
trafficHeatLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ======================================================
|
||||
UNMAPPED PACKETS LIST
|
||||
====================================================== */
|
||||
@@ -628,13 +744,33 @@ function isTextPort(portnum){
|
||||
return portnum === 1 || portnum === 7;
|
||||
}
|
||||
|
||||
function isNodeVisibleForPackets(marker){
|
||||
return map.hasLayer(nodeLayer) && nodeLayer.hasLayer(marker);
|
||||
}
|
||||
|
||||
function clearBlinkForMarker(marker){
|
||||
if(activeBlinks.has(marker)){
|
||||
const interval = activeBlinks.get(marker);
|
||||
clearInterval(interval);
|
||||
activeBlinks.delete(marker);
|
||||
}
|
||||
marker.setStyle({ fillColor: marker.originalColor });
|
||||
if(marker.tooltip){
|
||||
map.removeLayer(marker.tooltip);
|
||||
marker.tooltip = null;
|
||||
}
|
||||
}
|
||||
|
||||
function clearActiveBlinks(){
|
||||
activeBlinks.forEach((interval, marker) => clearBlinkForMarker(marker));
|
||||
activeBlinks.clear();
|
||||
}
|
||||
|
||||
function blinkNode(marker,longName,portnum,payload){
|
||||
if(!map.hasLayer(marker)) return;
|
||||
if(!isNodeVisibleForPackets(marker)) return;
|
||||
|
||||
if(activeBlinks.has(marker)){
|
||||
clearInterval(activeBlinks.get(marker));
|
||||
marker.setStyle({ fillColor: marker.originalColor });
|
||||
if(marker.tooltip) map.removeLayer(marker.tooltip);
|
||||
clearBlinkForMarker(marker);
|
||||
}
|
||||
|
||||
let blinkCount = 0;
|
||||
@@ -662,19 +798,19 @@ function blinkNode(marker,longName,portnum,payload){
|
||||
marker.tooltip = tooltip;
|
||||
|
||||
const interval = setInterval(()=>{
|
||||
if(map.hasLayer(marker)){
|
||||
if(isNodeVisibleForPackets(marker)){
|
||||
marker.setStyle({
|
||||
fillColor: blinkCount%2===0 ? 'yellow' : marker.originalColor
|
||||
});
|
||||
marker.bringToFront();
|
||||
} else {
|
||||
clearBlinkForMarker(marker);
|
||||
return;
|
||||
}
|
||||
blinkCount++;
|
||||
|
||||
if(Date.now() - blinkStart > blinkDurationMs){
|
||||
clearInterval(interval);
|
||||
marker.setStyle({ fillColor: marker.originalColor });
|
||||
map.removeLayer(tooltip);
|
||||
activeBlinks.delete(marker);
|
||||
clearBlinkForMarker(marker);
|
||||
}
|
||||
|
||||
},500);
|
||||
@@ -690,7 +826,7 @@ function createChannelFilters(){
|
||||
const filterContainer = document.getElementById("filter-container");
|
||||
const saved = JSON.parse(localStorage.getItem("mapFilters") || "{}");
|
||||
|
||||
channelSet.forEach(channel=>{
|
||||
[...channelSet].sort((a, b) => a.localeCompare(b)).forEach(channel=>{
|
||||
const cb=document.createElement("input");
|
||||
cb.type="checkbox";
|
||||
cb.className="filter-checkbox";
|
||||
@@ -734,6 +870,8 @@ function saveFiltersToLocalStorage(){
|
||||
}
|
||||
|
||||
function updateNodeVisibility(){
|
||||
if(!map.hasLayer(nodeLayer)) return;
|
||||
|
||||
const routerOnly = document.getElementById("filter-routers-only").checked;
|
||||
const mqttOnly = document.getElementById("filter-mqtt-only").checked;
|
||||
const activeChannels = [...channelSet].filter(ch =>
|
||||
@@ -748,7 +886,12 @@ function updateNodeVisibility(){
|
||||
(!mqttOnly || n.is_mqtt_gateway) &&
|
||||
activeChannels.includes(n.channel);
|
||||
|
||||
visible ? map.addLayer(marker) : map.removeLayer(marker);
|
||||
if(visible){
|
||||
nodeLayer.addLayer(marker);
|
||||
} else {
|
||||
clearBlinkForMarker(marker);
|
||||
nodeLayer.removeLayer(marker);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -296,32 +296,6 @@
|
||||
color:#fff;
|
||||
}
|
||||
|
||||
/* --- Impersonation Warning --- */
|
||||
.impersonation-warning {
|
||||
background: rgba(239, 68, 68, 0.15);
|
||||
border: 1px solid rgba(239, 68, 68, 0.4);
|
||||
border-radius: 8px;
|
||||
padding: 12px 16px;
|
||||
margin-bottom: 14px;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 10px;
|
||||
}
|
||||
.impersonation-warning .warning-icon {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
.impersonation-warning .warning-content {
|
||||
flex: 1;
|
||||
}
|
||||
.impersonation-warning .warning-title {
|
||||
color: #f87171;
|
||||
font-weight: bold;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.impersonation-warning .warning-text {
|
||||
font-size: 0.85rem;
|
||||
color: #ccc;
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
@@ -340,6 +314,9 @@
|
||||
<button onclick="showQrCode()" id="showQrBtn">
|
||||
<span>🔳</span> <span data-translate-lang="show_qr_code">Show QR Code</span>
|
||||
</button>
|
||||
<button onclick="openReachReport()" id="reachReportBtn">
|
||||
<span>📈</span> <span>Reliability</span>
|
||||
</button>
|
||||
<button onclick="toggleCoverage()" id="toggleCoverageBtn" disabled title="Location required for coverage">
|
||||
<span>📡</span> <span data-translate-lang="toggle_coverage">Predicted Coverage</span>
|
||||
</button>
|
||||
@@ -348,15 +325,6 @@
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Impersonation Warning -->
|
||||
<div id="impersonationWarning" class="impersonation-warning" style="display:none;">
|
||||
<span class="warning-icon">⚠️</span>
|
||||
<div class="warning-content">
|
||||
<div class="warning-title" data-translate-lang="potential_impersonation">Potential Impersonation Detected</div>
|
||||
<div class="warning-text" id="impersonationText"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Node Info -->
|
||||
<div id="node-info" class="node-info">
|
||||
<div class="node-info-col">
|
||||
@@ -825,6 +793,11 @@ function initMap(){
|
||||
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
attribution:'© OpenStreetMap'
|
||||
}).addTo(map);
|
||||
L.control.scale({
|
||||
position: 'bottomleft',
|
||||
metric: true,
|
||||
imperial: true
|
||||
}).addTo(map);
|
||||
}
|
||||
|
||||
async function toggleCoverage() {
|
||||
@@ -1098,18 +1071,24 @@ async function loadPackets(filters = {}) {
|
||||
const match = pkt.payload?.match(/ID:\s*(\d+)/i);
|
||||
if (match) traceId = match[1];
|
||||
inlineLinks +=
|
||||
` <a class="inline-link" href="/graph/traceroute/${traceId}" target="_blank">⮕</a>`;
|
||||
` <a class="inline-link" href="/traceroute/${traceId}" target="_blank">⮕</a>`;
|
||||
}
|
||||
|
||||
const sizeBytes = packetSizeBytes(pkt);
|
||||
const packetIdCell = pkt.packet_id
|
||||
? `<a href="/packet/${pkt.storage_id || pkt.id}"
|
||||
style="text-decoration:underline; color:inherit;">
|
||||
${pkt.packet_id}
|
||||
</a>`
|
||||
: pkt.portnum === 73
|
||||
? `<span class="text-secondary" title="MQTT map report">Not a Packet</span>`
|
||||
: `<span class="text-secondary" title="No Meshtastic packet ID">—</span>`;
|
||||
|
||||
list.insertAdjacentHTML("afterbegin", `
|
||||
<tr class="packet-row">
|
||||
<td>${localTime}</td>
|
||||
<td><span class="toggle-btn">▶</span>
|
||||
<a href="/packet/${pkt.id}" style="text-decoration:underline; color:inherit;">
|
||||
${pkt.id}
|
||||
</a>
|
||||
${packetIdCell}
|
||||
</td>
|
||||
<td>${fromCell}</td>
|
||||
<td>${toCell}</td>
|
||||
@@ -1629,8 +1608,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
requestAnimationFrame(async () => {
|
||||
await loadNodeInfo();
|
||||
|
||||
// Load QR code URL and impersonation check
|
||||
await loadNodeQrAndImpersonation();
|
||||
await loadNodeQr();
|
||||
|
||||
// ✅ MAP MUST EXIST FIRST
|
||||
if (!map) initMap();
|
||||
@@ -1734,6 +1712,7 @@ async function loadNodeStats(nodeId) {
|
||||
: "";
|
||||
|
||||
const portName = PORT_LABEL_MAP[pkt.portnum] || `Port ${pkt.portnum}`;
|
||||
const displayPacketId = pkt.packet_id || (pkt.portnum === 73 ? "Not a Packet" : "");
|
||||
|
||||
// Escape quotes + line breaks for CSV safety
|
||||
const payload = (pkt.payload || "")
|
||||
@@ -1742,7 +1721,7 @@ async function loadNodeStats(nodeId) {
|
||||
|
||||
rows.push([
|
||||
time,
|
||||
pkt.id,
|
||||
displayPacketId,
|
||||
pkt.from_node_id,
|
||||
pkt.to_node_id,
|
||||
pkt.portnum,
|
||||
@@ -1766,16 +1745,11 @@ async function loadNodeStats(nodeId) {
|
||||
|
||||
let currentMeshtasticUrl = "";
|
||||
|
||||
async function loadNodeQrAndImpersonation() {
|
||||
async function loadNodeQr() {
|
||||
const actionsDiv = document.getElementById("nodeActions");
|
||||
const warningDiv = document.getElementById("impersonationWarning");
|
||||
|
||||
try {
|
||||
const [qrRes, impRes] = await Promise.all([
|
||||
fetch(`/api/node/${fromNodeId}/qr`),
|
||||
fetch(`/api/node/${fromNodeId}/impersonation-check`)
|
||||
]);
|
||||
|
||||
const qrRes = await fetch(`/api/node/${fromNodeId}/qr`);
|
||||
const qrData = await qrRes.json();
|
||||
if (qrRes.ok && qrData.meshtastic_url) {
|
||||
currentMeshtasticUrl = qrData.meshtastic_url;
|
||||
@@ -1783,19 +1757,9 @@ async function loadNodeQrAndImpersonation() {
|
||||
} else {
|
||||
actionsDiv.style.display = "none";
|
||||
}
|
||||
|
||||
const impData = await impRes.json();
|
||||
if (impRes.ok && impData.potential_impersonation) {
|
||||
warningDiv.style.display = "flex";
|
||||
document.getElementById("impersonationText").textContent =
|
||||
impData.warning || `This node has sent ${impData.unique_public_key_count} different public keys. This could indicate impersonation.`;
|
||||
} else {
|
||||
warningDiv.style.display = "none";
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed to load QR/impersonation data:", err);
|
||||
console.error("Failed to load QR data:", err);
|
||||
actionsDiv.style.display = "none";
|
||||
warningDiv.style.display = "none";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1830,6 +1794,11 @@ function showQrCode() {
|
||||
document.getElementById("qrModal").style.display = "flex";
|
||||
}
|
||||
|
||||
function openReachReport() {
|
||||
if (!fromNodeId) return;
|
||||
window.location.href = `/reliability?node_id=${encodeURIComponent(fromNodeId)}`;
|
||||
}
|
||||
|
||||
function closeQrModal() {
|
||||
document.getElementById("qrModal").style.display = "none";
|
||||
}
|
||||
|
||||
@@ -103,6 +103,20 @@ select, .export-btn, .search-box, .clear-btn {
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
.node-list-note {
|
||||
width: 80%;
|
||||
margin: -4px auto 10px;
|
||||
color: rgba(255, 255, 255, 0.68);
|
||||
font-size: 0.9em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.node-list-note select {
|
||||
padding: 3px 6px;
|
||||
min-width: 70px;
|
||||
}
|
||||
.node-status {
|
||||
margin-left: 10px;
|
||||
padding: 2px 8px;
|
||||
@@ -252,6 +266,15 @@ select, .export-btn, .search-box, .clear-btn {
|
||||
<span data-translate-lang="nodes_suffix">nodes</span>
|
||||
<span id="node-status" class="node-status" aria-live="polite"></span>
|
||||
</div>
|
||||
<div class="node-list-note">
|
||||
<span>Showing nodes active in the last</span>
|
||||
<select id="days-active-filter" aria-label="Days active">
|
||||
{% for day in range(1, 15) %}
|
||||
<option value="{{ day }}" {% if day == 3 %}selected{% endif %}>{{ day }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<span>days.</span>
|
||||
</div>
|
||||
|
||||
<!-- Desktop table -->
|
||||
<div id="node-list">
|
||||
@@ -407,16 +430,18 @@ document.addEventListener("DOMContentLoaded", async function() {
|
||||
const searchBox = document.getElementById("search-box");
|
||||
const countSpan = document.getElementById("node-count");
|
||||
const statusSpan = document.getElementById("node-status");
|
||||
const daysActiveFilter = document.getElementById("days-active-filter");
|
||||
const exportBtn = document.getElementById("export-btn");
|
||||
const clearBtn = document.getElementById("clear-btn");
|
||||
const favoritesBtn = document.getElementById("favorites-btn");
|
||||
|
||||
let lastIsMobile = (window.innerWidth <= 768);
|
||||
|
||||
try {
|
||||
async function loadNodesForActiveDays() {
|
||||
const daysActive = Number(daysActiveFilter.value) || 3;
|
||||
setStatus("Loading nodes…");
|
||||
await nextFrame();
|
||||
const res = await fetch("/api/nodes?days_active=3");
|
||||
const res = await fetch(`/api/nodes?days_active=${encodeURIComponent(daysActive)}`);
|
||||
if (!res.ok) throw new Error("Failed to fetch nodes");
|
||||
|
||||
const data = await res.json();
|
||||
@@ -447,6 +472,10 @@ document.addEventListener("DOMContentLoaded", async function() {
|
||||
applyFilters(); // ensures initial sort + render uses same path
|
||||
updateSortIcons();
|
||||
setStatus("");
|
||||
}
|
||||
|
||||
try {
|
||||
await loadNodesForActiveDays();
|
||||
} catch (err) {
|
||||
tbody.innerHTML = `<tr>
|
||||
<td colspan="11" style="text-align:center; color:red;">
|
||||
@@ -460,6 +489,20 @@ document.addEventListener("DOMContentLoaded", async function() {
|
||||
channelFilter.addEventListener("change", applyFilters);
|
||||
hwFilter.addEventListener("change", applyFilters);
|
||||
firmwareFilter.addEventListener("change", applyFilters);
|
||||
daysActiveFilter.addEventListener("change", async () => {
|
||||
try {
|
||||
await loadNodesForActiveDays();
|
||||
} catch (err) {
|
||||
console.error("Failed to reload nodes:", err);
|
||||
tbody.innerHTML = `<tr>
|
||||
<td colspan="11" style="text-align:center; color:red;">
|
||||
${nodelistTranslations.error_loading_nodes || "Error loading nodes"}
|
||||
</td></tr>`;
|
||||
mobileList.innerHTML = "";
|
||||
countSpan.textContent = 0;
|
||||
setStatus("");
|
||||
}
|
||||
});
|
||||
|
||||
// Debounced only for search typing
|
||||
searchBox.addEventListener("input", debounce(applyFilters, 250));
|
||||
@@ -526,12 +569,15 @@ document.addEventListener("DOMContentLoaded", async function() {
|
||||
}
|
||||
|
||||
function fillSelect(select, values) {
|
||||
const currentValue = select.value;
|
||||
select.querySelectorAll("option:not(:first-child)").forEach(opt => opt.remove());
|
||||
[...values].sort().forEach(v => {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = v;
|
||||
opt.textContent = v;
|
||||
select.appendChild(opt);
|
||||
});
|
||||
select.value = values.has(currentValue) ? currentValue : "";
|
||||
}
|
||||
|
||||
function toggleFavoritesFilter() {
|
||||
|
||||
@@ -0,0 +1,856 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block css %}
|
||||
.reach-page {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.reach-header {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.reach-header h1 {
|
||||
font-size: 1.35rem;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.reach-panel {
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: 8px;
|
||||
padding: 12px;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
|
||||
.reach-controls {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.reach-search {
|
||||
min-width: 0;
|
||||
flex: 0 1 420px;
|
||||
}
|
||||
|
||||
.reach-search-label,
|
||||
.reach-limit-label {
|
||||
align-self: center;
|
||||
white-space: nowrap;
|
||||
color: rgba(255, 255, 255, 0.72);
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.reach-limit-label {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.reach-node-link {
|
||||
align-self: center;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.reach-controls {
|
||||
flex-direction: column;
|
||||
}
|
||||
}
|
||||
|
||||
.reach-summary {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||
gap: 8px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.reach-metric {
|
||||
border: 1px solid rgba(255, 255, 255, 0.12);
|
||||
border-radius: 8px;
|
||||
padding: 8px 10px;
|
||||
background: rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.reach-metric-value {
|
||||
font-size: 1.2rem;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
.reach-table-wrap {
|
||||
overflow-x: auto;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.reach-table {
|
||||
width: 100%;
|
||||
min-width: 760px;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
.reach-map {
|
||||
width: 100%;
|
||||
height: 520px;
|
||||
margin-top: 10px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.14);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background: rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.reach-map-marker {
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
border: 2px solid #fff;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: #fff;
|
||||
font-size: 0.65rem;
|
||||
font-weight: 800;
|
||||
line-height: 1;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.75);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
|
||||
}
|
||||
|
||||
.reach-map-marker-source {
|
||||
background: #111827;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.reach-gateway-panels {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.reach-gateway-panel {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.reach-gateway-table {
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.reach-table th,
|
||||
.reach-table td {
|
||||
vertical-align: top;
|
||||
padding: 0.35rem 0.5rem;
|
||||
}
|
||||
|
||||
.reach-count-bar-cell {
|
||||
min-width: 180px;
|
||||
}
|
||||
|
||||
.reach-count-bar-track {
|
||||
position: relative;
|
||||
height: 20px;
|
||||
border-radius: 999px;
|
||||
background: rgba(255, 255, 255, 0.12);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.reach-count-bar-fill {
|
||||
height: 100%;
|
||||
min-width: 24px;
|
||||
border-radius: inherit;
|
||||
background: var(--reach-bar-color, #4ade80);
|
||||
}
|
||||
|
||||
.reach-count-bar-value {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding-left: 8px;
|
||||
font-family: monospace;
|
||||
font-size: 0.85rem;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.reach-muted {
|
||||
color: rgba(255, 255, 255, 0.62);
|
||||
}
|
||||
|
||||
.reach-heard-link {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #8ab4f8;
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.port-tag {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.reliability-modal {
|
||||
display: none;
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
z-index: 5000;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 16px;
|
||||
background: rgba(0, 0, 0, 0.72);
|
||||
}
|
||||
|
||||
.reliability-modal.open {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.reliability-modal-panel {
|
||||
width: min(760px, 100%);
|
||||
max-height: min(720px, 92vh);
|
||||
overflow: auto;
|
||||
border: 1px solid rgba(255, 255, 255, 0.18);
|
||||
border-radius: 8px;
|
||||
background: #111827;
|
||||
padding: 12px;
|
||||
box-shadow: 0 16px 48px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.reliability-modal-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.reliability-modal-title {
|
||||
font-size: 1rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.reliability-status-heard {
|
||||
color: #4ade80 !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.reliability-status-missed {
|
||||
color: #f87171 !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.reliability-status-skipped {
|
||||
color: #cbd5e1 !important;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.reliability-row-skipped td {
|
||||
text-decoration: line-through;
|
||||
text-decoration-thickness: 1px;
|
||||
color: rgba(255, 255, 255, 0.58) !important;
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.reach-gateway-panels {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<main class="reach-page">
|
||||
<div class="reach-header">
|
||||
<h1>Reliability</h1>
|
||||
<p class="text-secondary mb-0">
|
||||
Review how often each gateway hears packets from a selected node. The report uses the
|
||||
latest selected packet sample and calculates reliability as heard packets divided by packets
|
||||
reviewed. The range table groups gateways by reliability bands, while the gateway list
|
||||
shows each gateway's heard count and percentage for the same sample. Reliability is
|
||||
calculated only from Text, Position, Node Info, and Telemetry packets; other packet types
|
||||
are shown in packet details but skipped from the calculation.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<section class="reach-panel">
|
||||
<form class="reach-controls" id="reach-search-form">
|
||||
<label class="reach-search-label" for="reach-node-search">Search</label>
|
||||
<input
|
||||
class="form-control reach-search"
|
||||
id="reach-node-search"
|
||||
list="reach-node-options"
|
||||
placeholder="Search node name or enter node ID"
|
||||
autocomplete="off"
|
||||
>
|
||||
<datalist id="reach-node-options"></datalist>
|
||||
<label class="reach-limit-label" for="reliability-packet-type">Packet type</label>
|
||||
<select class="form-select" id="reliability-packet-type" style="max-width:150px;">
|
||||
<option value="">All</option>
|
||||
<option value="1" selected>Text</option>
|
||||
<option value="3">Position</option>
|
||||
<option value="4">Node Info</option>
|
||||
<option value="67">Telemetry</option>
|
||||
</select>
|
||||
<label class="reach-limit-label" for="reach-packet-limit">Packets to review</label>
|
||||
<select class="form-select" id="reach-packet-limit" style="max-width:110px;">
|
||||
<option value="10">10</option>
|
||||
<option value="20" selected>20</option>
|
||||
<option value="30">30</option>
|
||||
<option value="40">40</option>
|
||||
<option value="50">50</option>
|
||||
<option value="60">60</option>
|
||||
<option value="70">70</option>
|
||||
<option value="80">80</option>
|
||||
<option value="90">90</option>
|
||||
<option value="100">100</option>
|
||||
</select>
|
||||
<button class="btn btn-primary" type="submit">Load</button>
|
||||
<a class="btn btn-outline-secondary reach-node-link" id="reach-node-link" href="/node/3530776522">
|
||||
Back to Node
|
||||
</a>
|
||||
</form>
|
||||
|
||||
<div class="reach-table-wrap">
|
||||
<table class="table table-dark table-sm table-striped reach-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Reliability Bands</th>
|
||||
<th>Gateway Count</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="reach-bucket-body">
|
||||
<tr>
|
||||
<td colspan="2" class="reach-muted">Loading statistics...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div id="reach-gateway-map" class="reach-map"></div>
|
||||
|
||||
<div class="reach-summary">
|
||||
<div class="reach-metric">
|
||||
<div class="text-secondary">Latest Packets</div>
|
||||
<div class="reach-metric-value" id="reach-packet-count">...</div>
|
||||
</div>
|
||||
<div class="reach-metric">
|
||||
<div class="text-secondary">Unique Gateways</div>
|
||||
<div class="reach-metric-value" id="reach-gateway-count">...</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="reach-gateway-panels">
|
||||
<div class="reach-gateway-panel">
|
||||
<table class="table table-dark table-sm table-striped reach-table reach-gateway-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Gateway</th>
|
||||
<th>Heard</th>
|
||||
<th>Avg Hops</th>
|
||||
<th>Reliability</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="reach-packet-body-left">
|
||||
<tr>
|
||||
<td colspan="4" class="reach-muted">Loading packets...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="reach-gateway-panel">
|
||||
<table class="table table-dark table-sm table-striped reach-table reach-gateway-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Gateway</th>
|
||||
<th>Heard</th>
|
||||
<th>Avg Hops</th>
|
||||
<th>Reliability</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="reach-packet-body-right">
|
||||
<tr>
|
||||
<td colspan="4" class="reach-muted">Loading packets...</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<div class="reliability-modal" id="gateway-packet-modal" role="dialog" aria-modal="true" aria-labelledby="gateway-packet-title">
|
||||
<div class="reliability-modal-panel">
|
||||
<div class="reliability-modal-header">
|
||||
<div class="reliability-modal-title" id="gateway-packet-title">Packet Details</div>
|
||||
<button class="btn btn-sm btn-outline-light" type="button" onclick="closeGatewayPacketModal()">Close</button>
|
||||
</div>
|
||||
<div class="reach-table-wrap">
|
||||
<table class="table table-dark table-sm table-striped reach-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Packet</th>
|
||||
<th>Time</th>
|
||||
<th>Type</th>
|
||||
<th>Hops</th>
|
||||
<th>Status</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="gateway-packet-body">
|
||||
<tr>
|
||||
<td colspan="5" class="reach-muted">No packet selected.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="/static/portmaps.js"></script>
|
||||
<script>
|
||||
const defaultReachNodeId = 3530776522;
|
||||
const defaultReachPacketLimit = 20;
|
||||
const initialReachNodeId = Number(new URLSearchParams(window.location.search).get("node_id")) || defaultReachNodeId;
|
||||
let reachNodeId = initialReachNodeId;
|
||||
let reachNodes = [];
|
||||
let reliabilityGatewayDetails = new Map();
|
||||
let reliabilityMap = null;
|
||||
let reliabilityMapLayer = null;
|
||||
const countedReliabilityPorts = new Set([1, 3, 4, 67]);
|
||||
const reliabilityBuckets = [
|
||||
{ label: "100%", color: "#22c55e", matches: row => row.percent === 100 },
|
||||
{ label: "90-99%", color: "#84cc16", matches: row => row.percent >= 90 && row.percent < 100 },
|
||||
{ label: "80-89%", color: "#eab308", matches: row => row.percent >= 80 && row.percent < 90 },
|
||||
{ label: "70-79%", color: "#f97316", matches: row => row.percent >= 70 && row.percent < 80 },
|
||||
{ label: "60-69%", color: "#ef4444", matches: row => row.percent >= 60 && row.percent < 70 },
|
||||
{ label: "50-59%", color: "#991b1b", matches: row => row.percent >= 50 && row.percent < 60 },
|
||||
];
|
||||
|
||||
function escapeHtml(value) {
|
||||
return String(value ?? "")
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function gatewayLabel(nodeId, nodesById) {
|
||||
const node = nodesById.get(Number(nodeId));
|
||||
const name = node?.long_name || node?.short_name;
|
||||
return name ? `${name} (${nodeId})` : String(nodeId);
|
||||
}
|
||||
|
||||
function nodeLink(nodeId, nodesById) {
|
||||
return `<a href="/node/${encodeURIComponent(nodeId)}">${
|
||||
escapeHtml(gatewayLabel(nodeId, nodesById))
|
||||
}</a>`;
|
||||
}
|
||||
|
||||
function nodeSearchLabel(node) {
|
||||
const name = node.long_name || node.short_name || "Unnamed";
|
||||
return `${name} (${node.node_id})`;
|
||||
}
|
||||
|
||||
function formatPacketTime(us) {
|
||||
if (!us) return "N/A";
|
||||
return new Date(us / 1000).toLocaleString();
|
||||
}
|
||||
|
||||
function packetTypeTag(portnum) {
|
||||
const name = window.PORT_MAP?.[portnum] || "Unknown";
|
||||
const color = window.PORT_COLORS?.[portnum] || "#6c757d";
|
||||
return `
|
||||
<span class="port-tag" style="background-color:${color}">
|
||||
${escapeHtml(name)}
|
||||
</span>
|
||||
<span class="text-secondary">(${escapeHtml(portnum ?? "?")})</span>
|
||||
`;
|
||||
}
|
||||
|
||||
function packetSeenHopCount(row) {
|
||||
const hopStart = Number(row?.hop_start ?? 0);
|
||||
const hopLimit = Number(row?.hop_limit ?? 0);
|
||||
return Math.max(0, hopStart - hopLimit);
|
||||
}
|
||||
|
||||
function formatAverageHopCount(value) {
|
||||
if (value === null || value === undefined || !Number.isFinite(value)) return "—";
|
||||
|
||||
const lower = Math.floor(value);
|
||||
return value - lower === 0.5 ? lower : Math.round(value);
|
||||
}
|
||||
|
||||
function formatAverageHopCountWithActual(value) {
|
||||
if (value === null || value === undefined || !Number.isFinite(value)) return "—";
|
||||
return `${formatAverageHopCount(value)} (${value.toFixed(1)})`;
|
||||
}
|
||||
|
||||
function reliabilityBucketFor(row) {
|
||||
return reliabilityBuckets.find(bucket => bucket.matches(row)) || null;
|
||||
}
|
||||
|
||||
function nodeLatLng(node) {
|
||||
if (!node?.last_lat || !node?.last_long) return null;
|
||||
|
||||
const lat = node.last_lat / 1e7;
|
||||
const lon = node.last_long / 1e7;
|
||||
if (!Number.isFinite(lat) || !Number.isFinite(lon) || lat === 0 || lon === 0) return null;
|
||||
|
||||
return [lat, lon];
|
||||
}
|
||||
|
||||
function initReliabilityMap() {
|
||||
if (reliabilityMap) return reliabilityMap;
|
||||
|
||||
reliabilityMap = L.map("reach-gateway-map", { preferCanvas: true }).setView([37.7749, -122.4194], 8);
|
||||
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
|
||||
attribution: "© OpenStreetMap",
|
||||
maxZoom: 19,
|
||||
}).addTo(reliabilityMap);
|
||||
L.control.scale({
|
||||
position: "bottomleft",
|
||||
metric: true,
|
||||
imperial: true,
|
||||
}).addTo(reliabilityMap);
|
||||
reliabilityMapLayer = L.layerGroup().addTo(reliabilityMap);
|
||||
|
||||
return reliabilityMap;
|
||||
}
|
||||
|
||||
function resetReliabilityMap() {
|
||||
if (!reliabilityMap) initReliabilityMap();
|
||||
reliabilityMapLayer.clearLayers();
|
||||
requestAnimationFrame(() => reliabilityMap.invalidateSize());
|
||||
}
|
||||
|
||||
function reachMapIcon(label, color, extraClass = "") {
|
||||
return L.divIcon({
|
||||
className: "",
|
||||
iconSize: [34, 34],
|
||||
iconAnchor: [17, 17],
|
||||
popupAnchor: [0, -17],
|
||||
html: `
|
||||
<div class="reach-map-marker ${extraClass}" style="background:${color};">
|
||||
${escapeHtml(label)}
|
||||
</div>
|
||||
`,
|
||||
});
|
||||
}
|
||||
|
||||
function renderReliabilityMap(gatewayRows, nodesById) {
|
||||
if (!reliabilityMap) initReliabilityMap();
|
||||
reliabilityMapLayer.clearLayers();
|
||||
|
||||
const bounds = [];
|
||||
const sourceNode = nodesById.get(Number(reachNodeId));
|
||||
const sourceLatLng = nodeLatLng(sourceNode);
|
||||
if (sourceLatLng) {
|
||||
L.marker(sourceLatLng, {
|
||||
icon: reachMapIcon("TX", "#111827", "reach-map-marker-source"),
|
||||
}).bindPopup(`<b>${escapeHtml(gatewayLabel(reachNodeId, nodesById))}</b><br>Selected Node`)
|
||||
.addTo(reliabilityMapLayer);
|
||||
bounds.push(sourceLatLng);
|
||||
}
|
||||
|
||||
gatewayRows.forEach(row => {
|
||||
const bucket = reliabilityBucketFor(row);
|
||||
if (!bucket) return;
|
||||
|
||||
const node = nodesById.get(Number(row.nodeId));
|
||||
const latLng = nodeLatLng(node);
|
||||
if (!latLng) return;
|
||||
|
||||
L.marker(latLng, {
|
||||
icon: reachMapIcon(`${Math.round(row.percent)}%`, bucket.color),
|
||||
}).bindPopup(`
|
||||
<b>${nodeLink(row.nodeId, nodesById)}</b><br>
|
||||
Reliability: ${row.percent.toFixed(1)}% · Avg. hops ${formatAverageHopCountWithActual(row.avgHopCount)}<br>
|
||||
Heard:
|
||||
<button class="reach-heard-link" type="button" onclick="openGatewayPacketModal(${row.nodeId})">
|
||||
${row.heardCount}
|
||||
</button>
|
||||
<span class="text-secondary">(${row.total})</span>
|
||||
`).addTo(reliabilityMapLayer);
|
||||
bounds.push(latLng);
|
||||
});
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
reliabilityMap.invalidateSize();
|
||||
if (bounds.length) {
|
||||
reliabilityMap.fitBounds(bounds, { padding: [24, 24], maxZoom: 12 });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function isSkippedReliabilityPacket(packet) {
|
||||
return !countedReliabilityPorts.has(Number(packet.portnum));
|
||||
}
|
||||
|
||||
function openGatewayPacketModal(nodeId) {
|
||||
const details = reliabilityGatewayDetails.get(Number(nodeId));
|
||||
const titleEl = document.getElementById("gateway-packet-title");
|
||||
const bodyEl = document.getElementById("gateway-packet-body");
|
||||
const modalEl = document.getElementById("gateway-packet-modal");
|
||||
|
||||
if (!details) return;
|
||||
|
||||
titleEl.textContent = `${details.label}: ${details.heardCount} (${details.total}) packets heard`;
|
||||
bodyEl.innerHTML = details.packets.map(packet => {
|
||||
const statusClass = packet.skipped
|
||||
? "reliability-status-skipped"
|
||||
: packet.heard ? "reliability-status-heard" : "reliability-status-missed";
|
||||
const statusText = packet.heard ? "Heard" : "Missed";
|
||||
|
||||
return `
|
||||
<tr class="${packet.skipped ? "reliability-row-skipped" : ""}">
|
||||
<td><a href="/packet/${packet.id}">${packet.id}</a></td>
|
||||
<td>${escapeHtml(formatPacketTime(packet.import_time_us))}</td>
|
||||
<td>${packetTypeTag(packet.portnum)}</td>
|
||||
<td>${packet.hopCount ?? "—"}</td>
|
||||
<td class="${statusClass}">${statusText}</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join("");
|
||||
modalEl.classList.add("open");
|
||||
}
|
||||
|
||||
function closeGatewayPacketModal() {
|
||||
document.getElementById("gateway-packet-modal").classList.remove("open");
|
||||
}
|
||||
|
||||
function parseNodeSearchValue(value) {
|
||||
const trimmed = value.trim();
|
||||
const parenthesizedId = trimmed.match(/\((\d+)\)\s*$/);
|
||||
if (parenthesizedId) return Number(parenthesizedId[1]);
|
||||
|
||||
const rawId = trimmed.match(/^\d+$/);
|
||||
if (rawId) return Number(trimmed);
|
||||
|
||||
const lower = trimmed.toLowerCase();
|
||||
const node = reachNodes.find(n =>
|
||||
(n.long_name || "").toLowerCase() === lower ||
|
||||
(n.short_name || "").toLowerCase() === lower
|
||||
);
|
||||
return node ? Number(node.node_id) : null;
|
||||
}
|
||||
|
||||
async function fetchJson(url) {
|
||||
const res = await fetch(url);
|
||||
if (!res.ok) {
|
||||
throw new Error(`${url} returned ${res.status}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function loadReachNodes() {
|
||||
const data = await fetchJson("/api/nodes?days_active=3");
|
||||
reachNodes = data.nodes || [];
|
||||
|
||||
const optionsEl = document.getElementById("reach-node-options");
|
||||
optionsEl.innerHTML = reachNodes
|
||||
.filter(node => node.node_id)
|
||||
.map(node => `<option value="${escapeHtml(nodeSearchLabel(node))}"></option>`)
|
||||
.join("");
|
||||
|
||||
return reachNodes;
|
||||
}
|
||||
|
||||
async function loadReachReport(nodeId = reachNodeId) {
|
||||
reachNodeId = Number(nodeId);
|
||||
const packetLimit = Number(document.getElementById("reach-packet-limit").value) || defaultReachPacketLimit;
|
||||
const packetType = document.getElementById("reliability-packet-type").value;
|
||||
const packetCountEl = document.getElementById("reach-packet-count");
|
||||
const gatewayCountEl = document.getElementById("reach-gateway-count");
|
||||
const nodeLinkEl = document.getElementById("reach-node-link");
|
||||
const bodyEls = [
|
||||
document.getElementById("reach-packet-body-left"),
|
||||
document.getElementById("reach-packet-body-right"),
|
||||
];
|
||||
const bucketBodyEl = document.getElementById("reach-bucket-body");
|
||||
const setGatewayTables = html => {
|
||||
bodyEls.forEach(el => {
|
||||
el.innerHTML = html;
|
||||
});
|
||||
};
|
||||
|
||||
packetCountEl.textContent = "...";
|
||||
gatewayCountEl.textContent = "...";
|
||||
reliabilityGatewayDetails = new Map();
|
||||
nodeLinkEl.href = `/node/${encodeURIComponent(reachNodeId)}`;
|
||||
bucketBodyEl.innerHTML = '<tr><td colspan="2" class="reach-muted">Loading statistics...</td></tr>';
|
||||
setGatewayTables('<tr><td colspan="4" class="reach-muted">Loading packets...</td></tr>');
|
||||
resetReliabilityMap();
|
||||
|
||||
try {
|
||||
const packetUrl = new URL("/api/packets", window.location.origin);
|
||||
packetUrl.searchParams.set("from_node_id", reachNodeId);
|
||||
packetUrl.searchParams.set("limit", packetLimit);
|
||||
if (packetType) packetUrl.searchParams.set("portnum", packetType);
|
||||
|
||||
const [packetData] = await Promise.all([
|
||||
fetchJson(packetUrl),
|
||||
]);
|
||||
|
||||
const packets = packetData.packets || [];
|
||||
const nodesById = new Map(reachNodes.map(node => [Number(node.node_id), node]));
|
||||
|
||||
packetCountEl.textContent = packets.length;
|
||||
|
||||
if (packets.length === 0) {
|
||||
gatewayCountEl.textContent = "0";
|
||||
bucketBodyEl.innerHTML = '<tr><td colspan="2" class="reach-muted">No packets found.</td></tr>';
|
||||
setGatewayTables('<tr><td colspan="4" class="reach-muted">No packets found.</td></tr>');
|
||||
resetReliabilityMap();
|
||||
return;
|
||||
}
|
||||
|
||||
const seenResults = await Promise.all(
|
||||
packets.map(packet =>
|
||||
fetchJson(`/api/packets_seen/${packet.id}`)
|
||||
.then(data => ({ packet, seen: data.seen || [] }))
|
||||
.catch(err => {
|
||||
console.error("Failed to load packet seen rows", packet.id, err);
|
||||
return { packet, seen: [], error: true };
|
||||
})
|
||||
)
|
||||
);
|
||||
|
||||
const gatewayStats = new Map();
|
||||
const reportResults = seenResults.filter(result => !isSkippedReliabilityPacket(result.packet));
|
||||
reportResults.forEach(result => {
|
||||
const seenByGateway = new Map();
|
||||
result.seen.forEach(row => {
|
||||
const nodeId = Number(row.node_id);
|
||||
if (nodeId === reachNodeId || seenByGateway.has(nodeId)) return;
|
||||
seenByGateway.set(nodeId, row);
|
||||
});
|
||||
seenByGateway.forEach((seenRow, nodeId) => {
|
||||
const stats = gatewayStats.get(nodeId) || { heardCount: 0, hopTotal: 0 };
|
||||
stats.heardCount += 1;
|
||||
stats.hopTotal += packetSeenHopCount(seenRow);
|
||||
gatewayStats.set(nodeId, stats);
|
||||
});
|
||||
});
|
||||
|
||||
const gatewayRows = [...gatewayStats.entries()]
|
||||
.map(([nodeId, stats]) => ({
|
||||
nodeId,
|
||||
heardCount: stats.heardCount,
|
||||
avgHopCount: stats.heardCount ? stats.hopTotal / stats.heardCount : null,
|
||||
total: reportResults.length,
|
||||
percent: reportResults.length ? (stats.heardCount / reportResults.length) * 100 : 0,
|
||||
}))
|
||||
.sort((a, b) => b.percent - a.percent || b.heardCount - a.heardCount || a.nodeId - b.nodeId);
|
||||
|
||||
gatewayCountEl.textContent = gatewayRows.length;
|
||||
const bucketRows = reliabilityBuckets.map(bucket => ({
|
||||
label: bucket.label,
|
||||
color: bucket.color,
|
||||
count: gatewayRows.filter(bucket.matches).length,
|
||||
}));
|
||||
const maxBucketCount = Math.max(...bucketRows.map(row => row.count), 1);
|
||||
bucketBodyEl.innerHTML = bucketRows.map(row => {
|
||||
const width = row.count > 0 ? Math.max((row.count / maxBucketCount) * 100, 8) : 0;
|
||||
return `
|
||||
<tr>
|
||||
<td>${row.label}</td>
|
||||
<td class="reach-count-bar-cell">
|
||||
<div class="reach-count-bar-track">
|
||||
<div class="reach-count-bar-fill" style="width:${width}%; --reach-bar-color:${row.color};"></div>
|
||||
<div class="reach-count-bar-value">${row.count}</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
`;
|
||||
}).join("");
|
||||
|
||||
const renderGatewayRows = rows => rows.length
|
||||
? rows.map(row => `
|
||||
<tr>
|
||||
<td>${nodeLink(row.nodeId, nodesById)}</td>
|
||||
<td>
|
||||
<button class="reach-heard-link" type="button" onclick="openGatewayPacketModal(${row.nodeId})">
|
||||
${row.heardCount}
|
||||
</button>
|
||||
<span class="text-secondary">(${reportResults.length})</span>
|
||||
</td>
|
||||
<td>${formatAverageHopCountWithActual(row.avgHopCount)}</td>
|
||||
<td>${row.percent.toFixed(1)}%</td>
|
||||
</tr>
|
||||
`).join("")
|
||||
: '<tr><td colspan="4" class="reach-muted">No gateways heard these packets.</td></tr>';
|
||||
reliabilityGatewayDetails = new Map(gatewayRows.map(row => [
|
||||
Number(row.nodeId),
|
||||
{
|
||||
label: gatewayLabel(row.nodeId, nodesById),
|
||||
heardCount: row.heardCount,
|
||||
total: reportResults.length,
|
||||
packets: seenResults.map(result => {
|
||||
const seenRow = result.seen.find(seen => Number(seen.node_id) === Number(row.nodeId));
|
||||
return {
|
||||
id: result.packet.id,
|
||||
import_time_us: result.packet.import_time_us,
|
||||
portnum: result.packet.portnum,
|
||||
skipped: isSkippedReliabilityPacket(result.packet),
|
||||
heard: Boolean(seenRow),
|
||||
hopCount: seenRow ? packetSeenHopCount(seenRow) : null,
|
||||
};
|
||||
}),
|
||||
}
|
||||
]));
|
||||
const splitIndex = Math.ceil(gatewayRows.length / 2);
|
||||
bodyEls[0].innerHTML = renderGatewayRows(gatewayRows.slice(0, splitIndex));
|
||||
bodyEls[1].innerHTML = gatewayRows.length > 1
|
||||
? renderGatewayRows(gatewayRows.slice(splitIndex))
|
||||
: '<tr><td colspan="4" class="reach-muted">No additional gateways.</td></tr>';
|
||||
renderReliabilityMap(gatewayRows, nodesById);
|
||||
} catch (err) {
|
||||
console.error("Failed to load reach report:", err);
|
||||
packetCountEl.textContent = "!";
|
||||
gatewayCountEl.textContent = "!";
|
||||
bucketBodyEl.innerHTML = '<tr><td colspan="2" class="text-danger">Failed to load statistics.</td></tr>';
|
||||
setGatewayTables('<tr><td colspan="4" class="text-danger">Failed to load report.</td></tr>');
|
||||
resetReliabilityMap();
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
document.getElementById("gateway-packet-modal").addEventListener("click", event => {
|
||||
if (event.target.id === "gateway-packet-modal") closeGatewayPacketModal();
|
||||
});
|
||||
|
||||
document.getElementById("reach-search-form").addEventListener("submit", event => {
|
||||
event.preventDefault();
|
||||
|
||||
const nodeId = parseNodeSearchValue(document.getElementById("reach-node-search").value);
|
||||
if (!nodeId) {
|
||||
document.getElementById("reach-bucket-body").innerHTML =
|
||||
'<tr><td colspan="2" class="text-warning">Enter a valid node ID or select a node.</td></tr>';
|
||||
document.getElementById("reach-packet-body-left").innerHTML =
|
||||
'<tr><td colspan="4" class="text-warning">Enter a valid node ID or select a node.</td></tr>';
|
||||
document.getElementById("reach-packet-body-right").innerHTML =
|
||||
'<tr><td colspan="4" class="text-warning">Enter a valid node ID or select a node.</td></tr>';
|
||||
return;
|
||||
}
|
||||
|
||||
loadReachReport(nodeId);
|
||||
});
|
||||
|
||||
try {
|
||||
await loadReachNodes();
|
||||
} catch (err) {
|
||||
console.error("Failed to load node list:", err);
|
||||
}
|
||||
initReliabilityMap();
|
||||
|
||||
const searchEl = document.getElementById("reach-node-search");
|
||||
searchEl.value = nodeSearchLabel(
|
||||
reachNodes.find(node => Number(node.node_id) === initialReachNodeId) ||
|
||||
{ node_id: initialReachNodeId, long_name: "Node" }
|
||||
);
|
||||
loadReachReport(initialReachNodeId);
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
@@ -151,6 +151,11 @@ async function loadChannels() {
|
||||
const sel = document.getElementById("channelFilter");
|
||||
|
||||
sel.innerHTML = "";
|
||||
const allOpt = document.createElement("option");
|
||||
allOpt.value = "";
|
||||
allOpt.textContent = topTranslations.all_channels || "All channels";
|
||||
sel.appendChild(allOpt);
|
||||
|
||||
for (const ch of data.channels || []) {
|
||||
const opt = document.createElement("option");
|
||||
opt.value = ch;
|
||||
@@ -158,7 +163,7 @@ async function loadChannels() {
|
||||
sel.appendChild(opt);
|
||||
}
|
||||
|
||||
sel.value = "MediumFast";
|
||||
sel.value = "";
|
||||
}
|
||||
|
||||
/* ======================================================
|
||||
|
||||
@@ -7,12 +7,53 @@
|
||||
{% block css %}
|
||||
#traceroute-graph {
|
||||
width: 100%;
|
||||
height: 85vh;
|
||||
height: calc(100vh - 270px);
|
||||
border: 1px solid #2a2f36;
|
||||
background: linear-gradient(135deg, #0f1216 0%, #171b22 100%);
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
#traceroute-graph-wrap {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#traceroute-legend {
|
||||
position: absolute;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
z-index: 2;
|
||||
display: grid;
|
||||
gap: 8px;
|
||||
padding: 10px 12px;
|
||||
color: #d6dde6;
|
||||
background: rgba(15, 18, 22, 0.88);
|
||||
border: 1px solid #303743;
|
||||
border-radius: 8px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.traceroute-legend-row {
|
||||
display: grid;
|
||||
grid-template-columns: 34px auto;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.traceroute-legend-line {
|
||||
height: 0;
|
||||
border-top: 3px solid var(--line-color);
|
||||
}
|
||||
|
||||
.traceroute-legend-line.muted {
|
||||
border-top-width: 2px;
|
||||
opacity: 0.55;
|
||||
}
|
||||
|
||||
.traceroute-legend-line.dashed {
|
||||
border-top-style: dashed;
|
||||
}
|
||||
|
||||
#traceroute-meta {
|
||||
padding: 12px 16px;
|
||||
color: #c8d0da;
|
||||
@@ -28,7 +69,23 @@
|
||||
<div><b>Traceroute</b> <span id="traceroute-title"></span></div>
|
||||
<div id="traceroute-error"></div>
|
||||
</div>
|
||||
<div id="traceroute-graph"></div>
|
||||
<div id="traceroute-graph-wrap">
|
||||
<div id="traceroute-graph"></div>
|
||||
<div id="traceroute-legend" aria-label="Traceroute edge legend">
|
||||
<div class="traceroute-legend-row">
|
||||
<span class="traceroute-legend-line" style="--line-color: #34c759"></span>
|
||||
<span>Winning forward</span>
|
||||
</div>
|
||||
<div class="traceroute-legend-row">
|
||||
<span class="traceroute-legend-line dashed" style="--line-color: #ff3b30"></span>
|
||||
<span>Reported reverse</span>
|
||||
</div>
|
||||
<div class="traceroute-legend-row">
|
||||
<span class="traceroute-legend-line muted" style="--line-color: #7c858f"></span>
|
||||
<span>Reported route</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const el = document.getElementById("traceroute-graph");
|
||||
@@ -49,6 +106,33 @@ function addPathEdges(path, edges, style) {
|
||||
}
|
||||
}
|
||||
|
||||
function pathKey(path) {
|
||||
return path.map(id => String(id)).join(">");
|
||||
}
|
||||
|
||||
function addMissingEndpoints(path, startId, endId) {
|
||||
const fullPath = path.map(id => String(id));
|
||||
if (startId && (!fullPath.length || fullPath[0] !== startId)) {
|
||||
fullPath.unshift(startId);
|
||||
}
|
||||
if (endId && (!fullPath.length || fullPath[fullPath.length - 1] !== endId)) {
|
||||
fullPath.push(endId);
|
||||
}
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
function uniqueForwardPaths(data, originId, targetId) {
|
||||
return (data?.unique_forward_paths || [])
|
||||
.map(item => addMissingEndpoints(item.path || [], originId, targetId))
|
||||
.filter(path => path.length > 1);
|
||||
}
|
||||
|
||||
function uniqueReversePaths(data, originId, targetId) {
|
||||
return (data?.unique_reverse_paths || [])
|
||||
.map(path => addMissingEndpoints(path || [], targetId, null))
|
||||
.filter(path => path.length > 1);
|
||||
}
|
||||
|
||||
async function loadTraceroute() {
|
||||
const packetId = packetIdFromPath();
|
||||
document.getElementById("traceroute-title").textContent = `#${packetId}`;
|
||||
@@ -73,26 +157,61 @@ async function loadTraceroute() {
|
||||
const nodes = new Map();
|
||||
const edges = [];
|
||||
|
||||
const forwardPaths = data?.winning_paths?.forward || [];
|
||||
const reversePaths = data?.winning_paths?.reverse || [];
|
||||
const originId = data?.packet?.from != null ? String(data.packet.from) : null;
|
||||
const targetId = data?.packet?.to != null ? String(data.packet.to) : null;
|
||||
const forwardPaths = (data?.winning_paths?.forward || []).map(path => path.map(id => String(id)));
|
||||
const reversePaths = (data?.winning_paths?.reverse || []).map(path => path.map(id => String(id)));
|
||||
const winningPathKeys = new Set([
|
||||
...forwardPaths.map(pathKey),
|
||||
...reversePaths.map(pathKey)
|
||||
]);
|
||||
const winningForwardNodeIds = new Set(forwardPaths.flat());
|
||||
const hasWinningReversePath = reversePaths.some(path => path.length > 1);
|
||||
const winningForwardPath = forwardPaths.find(path => path.length > 1);
|
||||
const colorStartId = winningForwardPath ? winningForwardPath[0] : originId;
|
||||
const colorEndId = winningForwardPath ? winningForwardPath[winningForwardPath.length - 1] : targetId;
|
||||
const startNodeColor = hasWinningReversePath ? "#ff3b30" : "#34c759";
|
||||
const endNodeColor = hasWinningReversePath ? "#34c759" : "#ff3b30";
|
||||
|
||||
uniqueForwardPaths(data, originId, targetId).forEach(path => {
|
||||
if (winningPathKeys.has(pathKey(path))) {
|
||||
return;
|
||||
}
|
||||
path.forEach(id => nodes.set(String(id), { name: String(id) }));
|
||||
addPathEdges(path, edges, { color: "#7c858f", width: 1.5, opacity: 0.45 });
|
||||
});
|
||||
|
||||
uniqueReversePaths(data, originId, targetId).forEach(path => {
|
||||
if (winningPathKeys.has(pathKey(path))) {
|
||||
return;
|
||||
}
|
||||
path.forEach(id => nodes.set(String(id), { name: String(id) }));
|
||||
addPathEdges(path, edges, { color: "#7c858f", width: 1.5, opacity: 0.45, type: "dashed" });
|
||||
});
|
||||
|
||||
forwardPaths.forEach(path => {
|
||||
path.forEach(id => nodes.set(String(id), { name: String(id) }));
|
||||
addPathEdges(path, edges, { color: "#ff5733", width: 3 });
|
||||
addPathEdges(path, edges, { color: "#34c759", width: 3 });
|
||||
});
|
||||
|
||||
reversePaths.forEach(path => {
|
||||
path.forEach(id => nodes.set(String(id), { name: String(id) }));
|
||||
addPathEdges(path, edges, { color: "#00c3ff", width: 2, type: "dashed" });
|
||||
addPathEdges(path, edges, { color: "#ff3b30", width: 2, type: "dashed" });
|
||||
});
|
||||
|
||||
const graphNodes = Array.from(nodes.values()).map(n => {
|
||||
const isOrigin = originId && n.name === originId;
|
||||
const isTarget = targetId && n.name === targetId;
|
||||
const color = isOrigin ? "#ff3b30" : isTarget ? "#34c759" : "#8aa4c8";
|
||||
const size = isOrigin || isTarget ? 44 : 36;
|
||||
const isColorStart = colorStartId && n.name === colorStartId;
|
||||
const isColorEnd = colorEndId && n.name === colorEndId;
|
||||
const isWinningForwardNode = winningForwardNodeIds.has(n.name);
|
||||
let color = "#3f454d";
|
||||
if (isColorStart) {
|
||||
color = startNodeColor;
|
||||
} else if (isColorEnd) {
|
||||
color = endNodeColor;
|
||||
} else if (isWinningForwardNode) {
|
||||
color = "#b88a2a";
|
||||
}
|
||||
const size = isColorStart || isColorEnd ? 44 : 36;
|
||||
return {
|
||||
id: n.name,
|
||||
name: nodeShortNameById.get(n.name) || n.name,
|
||||
@@ -104,7 +223,10 @@ async function loadTraceroute() {
|
||||
fontWeight: "bold"
|
||||
},
|
||||
tooltip: {
|
||||
formatter: () => nodeLongNameById.get(n.name) || n.name
|
||||
formatter: () => {
|
||||
const longName = nodeLongNameById.get(n.name) || n.name;
|
||||
return longName === n.name ? n.name : `${longName} (${n.name})`;
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
@@ -53,6 +53,7 @@ class Packet:
|
||||
"""UI-friendly packet wrapper for templates and API payloads."""
|
||||
|
||||
id: int
|
||||
packet_id: int | None
|
||||
from_node_id: int
|
||||
from_node: models.Node
|
||||
to_node_id: int
|
||||
@@ -99,8 +100,13 @@ class Packet:
|
||||
f'<a href="https://www.google.com/maps/search/?api=1&query={payload.latitude_i * 1e-7},{payload.longitude_i * 1e-7}" target="_blank">map</a>'
|
||||
)
|
||||
|
||||
packet_id = None
|
||||
if mesh_packet and mesh_packet.id:
|
||||
packet_id = mesh_packet.id
|
||||
|
||||
return cls(
|
||||
id=packet.id,
|
||||
packet_id=packet_id,
|
||||
from_node=packet.from_node,
|
||||
from_node_id=packet.from_node_id,
|
||||
to_node=packet.to_node,
|
||||
@@ -259,6 +265,12 @@ async def map(request):
|
||||
return web.Response(text=template.render(), content_type="text/html")
|
||||
|
||||
|
||||
@routes.get("/reliability")
|
||||
async def reliability(request):
|
||||
template = env.get_template("reliability.html")
|
||||
return web.Response(text=template.render(), content_type="text/html")
|
||||
|
||||
|
||||
@routes.get("/nodelist")
|
||||
async def nodelist(request):
|
||||
template = env.get_template("nodelist.html")
|
||||
|
||||
+111
-47
@@ -13,7 +13,7 @@ from meshtastic.protobuf.portnums_pb2 import PortNum
|
||||
from meshview import database, decode_payload, store
|
||||
from meshview.__version__ import __version__, _git_revision_short, get_version_info
|
||||
from meshview.config import CONFIG
|
||||
from meshview.models import DailySnapshot, Node, NodePublicKey
|
||||
from meshview.models import DailySnapshot, Node
|
||||
from meshview.models import Packet as PacketModel
|
||||
from meshview.models import PacketSeen as PacketSeenModel
|
||||
from meshview.radio.coverage import (
|
||||
@@ -38,6 +38,96 @@ _LANG_CACHE = {}
|
||||
routes = web.RouteTableDef()
|
||||
|
||||
|
||||
def _config_bool(section: str, key: str, default: bool = False) -> bool:
|
||||
return str(CONFIG.get(section, {}).get(key, default)).lower() in ("1", "true", "yes", "on")
|
||||
|
||||
|
||||
def _config_int(section: str, key: str, default: int = 0) -> int:
|
||||
try:
|
||||
return int(CONFIG.get(section, {}).get(key, default))
|
||||
except (TypeError, ValueError):
|
||||
return default
|
||||
|
||||
|
||||
def _config_str(section: str, key: str, default: str = "") -> str:
|
||||
value = CONFIG.get(section, {}).get(key, default)
|
||||
return str(value) if value is not None else default
|
||||
|
||||
|
||||
def _cleanup_status_file() -> str:
|
||||
cleanup_logfile = CONFIG.get("logging", {}).get("db_cleanup_logfile", "dbcleanup.log")
|
||||
path_without_extension, _ = os.path.splitext(cleanup_logfile)
|
||||
return f"{path_without_extension}.status.json"
|
||||
|
||||
|
||||
def _backup_status_file() -> str:
|
||||
cleanup_logfile = CONFIG.get("logging", {}).get("db_cleanup_logfile", "dbcleanup.log")
|
||||
return os.path.join(os.path.dirname(cleanup_logfile), "dbbackup.status.json")
|
||||
|
||||
|
||||
def _get_cleanup_health() -> dict:
|
||||
cleanup_health = {
|
||||
"enabled": _config_bool("cleanup", "enabled", False),
|
||||
"days_to_keep": _config_int("cleanup", "days_to_keep", 14),
|
||||
"scheduled_time": (
|
||||
f"{_config_int('cleanup', 'hour', 2):02d}:{_config_int('cleanup', 'minute', 0):02d}"
|
||||
),
|
||||
"vacuum": _config_bool("cleanup", "vacuum", False),
|
||||
"status": "disabled",
|
||||
}
|
||||
|
||||
if cleanup_health["enabled"]:
|
||||
cleanup_health["status"] = "unknown"
|
||||
|
||||
status_file = _cleanup_status_file()
|
||||
cleanup_health["status_file"] = status_file
|
||||
if not os.path.exists(status_file):
|
||||
return cleanup_health
|
||||
|
||||
try:
|
||||
with open(status_file, encoding="utf-8") as f:
|
||||
last_run = json.load(f)
|
||||
except Exception as e:
|
||||
cleanup_health["status"] = "error"
|
||||
cleanup_health["error"] = f"Unable to read cleanup status: {e}"
|
||||
return cleanup_health
|
||||
|
||||
cleanup_health["status"] = last_run.get("status", cleanup_health["status"])
|
||||
cleanup_health["last_run"] = last_run
|
||||
return cleanup_health
|
||||
|
||||
|
||||
def _get_backup_health() -> dict:
|
||||
backup_hour = _config_int("cleanup", "backup_hour", _config_int("cleanup", "hour", 2))
|
||||
backup_minute = _config_int("cleanup", "backup_minute", _config_int("cleanup", "minute", 0))
|
||||
backup_health = {
|
||||
"enabled": _config_bool("cleanup", "backup_enabled", False),
|
||||
"backup_dir": _config_str("cleanup", "backup_dir", "./backups"),
|
||||
"scheduled_time": f"{backup_hour:02d}:{backup_minute:02d}",
|
||||
"status": "disabled",
|
||||
}
|
||||
|
||||
if backup_health["enabled"]:
|
||||
backup_health["status"] = "unknown"
|
||||
|
||||
status_file = _backup_status_file()
|
||||
backup_health["status_file"] = status_file
|
||||
if not os.path.exists(status_file):
|
||||
return backup_health
|
||||
|
||||
try:
|
||||
with open(status_file, encoding="utf-8") as f:
|
||||
last_run = json.load(f)
|
||||
except Exception as e:
|
||||
backup_health["status"] = "error"
|
||||
backup_health["error"] = f"Unable to read backup status: {e}"
|
||||
return backup_health
|
||||
|
||||
backup_health["status"] = last_run.get("status", backup_health["status"])
|
||||
backup_health["last_run"] = last_run
|
||||
return backup_health
|
||||
|
||||
|
||||
def _haversine_km(lat1, lon1, lat2, lon2):
|
||||
r = 6371.0
|
||||
phi1 = math.radians(lat1)
|
||||
@@ -160,6 +250,8 @@ async def api_packets(request):
|
||||
p = Packet.from_model(packet)
|
||||
data = {
|
||||
"id": p.id,
|
||||
"storage_id": p.id,
|
||||
"packet_id": p.packet_id,
|
||||
"from_node_id": p.from_node_id,
|
||||
"to_node_id": p.to_node_id,
|
||||
"portnum": int(p.portnum) if p.portnum is not None else None,
|
||||
@@ -249,6 +341,8 @@ async def api_packets(request):
|
||||
for p in ui_packets:
|
||||
packet_dict = {
|
||||
"id": p.id,
|
||||
"storage_id": p.id,
|
||||
"packet_id": p.packet_id,
|
||||
"import_time_us": p.import_time_us,
|
||||
"channel": p.channel,
|
||||
"from_node_id": p.from_node_id,
|
||||
@@ -720,6 +814,8 @@ async def health_check(request):
|
||||
"timestamp": datetime.datetime.now(datetime.UTC).isoformat(),
|
||||
"version": __version__,
|
||||
"git_revision": _git_revision_short,
|
||||
"cleanup": _get_cleanup_health(),
|
||||
"backup": _get_backup_health(),
|
||||
}
|
||||
|
||||
# Check database connectivity
|
||||
@@ -872,11 +968,10 @@ async def api_traceroute(request):
|
||||
if tr["reverse_hops"]:
|
||||
reverse_paths.append(r)
|
||||
|
||||
if tr["done"]:
|
||||
if tr["reverse_hops"]:
|
||||
if tr["forward_hops"]:
|
||||
winning_forward_paths.append(f)
|
||||
if tr["reverse_hops"]:
|
||||
winning_reverse_paths.append(r)
|
||||
winning_reverse_paths.append(r)
|
||||
|
||||
# Deduplicate
|
||||
unique_forward_paths = sorted(set(forward_paths))
|
||||
@@ -897,10 +992,10 @@ async def api_traceroute(request):
|
||||
winning_forward_with_endpoints = []
|
||||
for path in set(winning_forward_paths):
|
||||
full_path = list(path)
|
||||
if from_node_id is not None and (not full_path or full_path[0] != from_node_id):
|
||||
full_path = [from_node_id, *full_path]
|
||||
if to_node_id is not None and (not full_path or full_path[-1] != to_node_id):
|
||||
full_path = [*full_path, to_node_id]
|
||||
full_path = [to_node_id, *full_path]
|
||||
if from_node_id is not None and (not full_path or full_path[-1] != from_node_id):
|
||||
full_path = [*full_path, from_node_id]
|
||||
winning_forward_with_endpoints.append(full_path)
|
||||
|
||||
winning_reverse_with_endpoints = []
|
||||
@@ -908,8 +1003,6 @@ async def api_traceroute(request):
|
||||
full_path = list(path)
|
||||
if to_node_id is not None and (not full_path or full_path[0] != to_node_id):
|
||||
full_path = [to_node_id, *full_path]
|
||||
if from_node_id is not None and (not full_path or full_path[-1] != from_node_id):
|
||||
full_path = [*full_path, from_node_id]
|
||||
winning_reverse_with_endpoints.append(full_path)
|
||||
|
||||
winning_paths_json = {
|
||||
@@ -1041,6 +1134,7 @@ async def api_node_qr(request):
|
||||
|
||||
try:
|
||||
from meshtastic.protobuf.admin_pb2 import SharedContact
|
||||
from meshtastic.protobuf.config_pb2 import Config
|
||||
from meshtastic.protobuf.mesh_pb2 import User
|
||||
|
||||
user = User()
|
||||
@@ -1058,6 +1152,13 @@ async def api_node_qr(request):
|
||||
user.hw_model = hw_model_value
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
if node.role:
|
||||
try:
|
||||
role_value = getattr(Config.DeviceConfig.Role, node.role.upper(), None)
|
||||
if role_value is not None:
|
||||
user.role = role_value
|
||||
except (AttributeError, TypeError):
|
||||
pass
|
||||
|
||||
contact = SharedContact()
|
||||
contact.node_num = node_id
|
||||
@@ -1077,6 +1178,7 @@ async def api_node_qr(request):
|
||||
"node_id": node_id,
|
||||
"long_name": node.long_name,
|
||||
"short_name": node.short_name,
|
||||
"role": node.role,
|
||||
"meshtastic_url": meshtastic_url,
|
||||
}
|
||||
)
|
||||
@@ -1088,44 +1190,6 @@ async def api_node_qr(request):
|
||||
return web.json_response({"error": f"Failed to generate URL: {str(e)}"}, status=500)
|
||||
|
||||
|
||||
@routes.get("/api/node/{node_id}/impersonation-check")
|
||||
async def api_node_impersonation_check(request):
|
||||
"""
|
||||
Check if a node has multiple different public keys, which could indicate impersonation.
|
||||
"""
|
||||
try:
|
||||
node_id_str = request.match_info["node_id"]
|
||||
node_id = int(node_id_str, 0)
|
||||
except (KeyError, ValueError):
|
||||
return web.json_response({"error": "Invalid node_id"}, status=400)
|
||||
|
||||
try:
|
||||
async with database.async_session() as session:
|
||||
result = await session.execute(
|
||||
select(NodePublicKey.public_key).where(NodePublicKey.node_id == node_id).distinct()
|
||||
)
|
||||
public_keys = result.scalars().all()
|
||||
|
||||
unique_key_count = len(public_keys)
|
||||
|
||||
return web.json_response(
|
||||
{
|
||||
"node_id": node_id,
|
||||
"unique_public_key_count": unique_key_count,
|
||||
"potential_impersonation": unique_key_count > 1,
|
||||
"public_keys": public_keys
|
||||
if unique_key_count <= 3
|
||||
else public_keys[:3] + ["..."],
|
||||
"warning": "Multiple different public keys detected. This node may be getting impersonated."
|
||||
if unique_key_count > 1
|
||||
else None,
|
||||
}
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"Error checking impersonation for node {node_id}: {e}")
|
||||
return web.json_response({"error": "Failed to check impersonation"}, status=500)
|
||||
|
||||
|
||||
@routes.get("/api/coverage/{node_id}")
|
||||
async def api_coverage(request):
|
||||
try:
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: nanopb.proto
|
||||
"""Generated protocol buffer code."""
|
||||
from google.protobuf.internal import builder as _builder
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import descriptor_pool as _descriptor_pool
|
||||
from google.protobuf import symbol_database as _symbol_database
|
||||
# @@protoc_insertion_point(imports)
|
||||
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cnanopb.proto\x1a google/protobuf/descriptor.proto\"\xa4\x07\n\rNanoPBOptions\x12\x10\n\x08max_size\x18\x01 \x01(\x05\x12\x12\n\nmax_length\x18\x0e \x01(\x05\x12\x11\n\tmax_count\x18\x02 \x01(\x05\x12&\n\x08int_size\x18\x07 \x01(\x0e\x32\x08.IntSize:\nIS_DEFAULT\x12$\n\x04type\x18\x03 \x01(\x0e\x32\n.FieldType:\nFT_DEFAULT\x12\x18\n\nlong_names\x18\x04 \x01(\x08:\x04true\x12\x1c\n\rpacked_struct\x18\x05 \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0bpacked_enum\x18\n \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0cskip_message\x18\x06 \x01(\x08:\x05\x66\x61lse\x12\x18\n\tno_unions\x18\x08 \x01(\x08:\x05\x66\x61lse\x12\r\n\x05msgid\x18\t \x01(\r\x12\x1e\n\x0f\x61nonymous_oneof\x18\x0b \x01(\x08:\x05\x66\x61lse\x12\x15\n\x06proto3\x18\x0c \x01(\x08:\x05\x66\x61lse\x12#\n\x14proto3_singular_msgs\x18\x15 \x01(\x08:\x05\x66\x61lse\x12\x1d\n\x0e\x65num_to_string\x18\r \x01(\x08:\x05\x66\x61lse\x12\x1b\n\x0c\x66ixed_length\x18\x0f \x01(\x08:\x05\x66\x61lse\x12\x1a\n\x0b\x66ixed_count\x18\x10 \x01(\x08:\x05\x66\x61lse\x12\x1e\n\x0fsubmsg_callback\x18\x16 \x01(\x08:\x05\x66\x61lse\x12/\n\x0cmangle_names\x18\x11 \x01(\x0e\x32\x11.TypenameMangling:\x06M_NONE\x12(\n\x11\x63\x61llback_datatype\x18\x12 \x01(\t:\rpb_callback_t\x12\x34\n\x11\x63\x61llback_function\x18\x13 \x01(\t:\x19pb_default_field_callback\x12\x30\n\x0e\x64\x65scriptorsize\x18\x14 \x01(\x0e\x32\x0f.DescriptorSize:\x07\x44S_AUTO\x12\x1a\n\x0b\x64\x65\x66\x61ult_has\x18\x17 \x01(\x08:\x05\x66\x61lse\x12\x0f\n\x07include\x18\x18 \x03(\t\x12\x0f\n\x07\x65xclude\x18\x1a \x03(\t\x12\x0f\n\x07package\x18\x19 \x01(\t\x12\x41\n\rtype_override\x18\x1b \x01(\x0e\x32*.google.protobuf.FieldDescriptorProto.Type\x12\x19\n\x0bsort_by_tag\x18\x1c \x01(\x08:\x04true\x12.\n\rfallback_type\x18\x1d \x01(\x0e\x32\n.FieldType:\x0b\x46T_CALLBACK*i\n\tFieldType\x12\x0e\n\nFT_DEFAULT\x10\x00\x12\x0f\n\x0b\x46T_CALLBACK\x10\x01\x12\x0e\n\nFT_POINTER\x10\x04\x12\r\n\tFT_STATIC\x10\x02\x12\r\n\tFT_IGNORE\x10\x03\x12\r\n\tFT_INLINE\x10\x05*D\n\x07IntSize\x12\x0e\n\nIS_DEFAULT\x10\x00\x12\x08\n\x04IS_8\x10\x08\x12\t\n\x05IS_16\x10\x10\x12\t\n\x05IS_32\x10 \x12\t\n\x05IS_64\x10@*Z\n\x10TypenameMangling\x12\n\n\x06M_NONE\x10\x00\x12\x13\n\x0fM_STRIP_PACKAGE\x10\x01\x12\r\n\tM_FLATTEN\x10\x02\x12\x16\n\x12M_PACKAGE_INITIALS\x10\x03*E\n\x0e\x44\x65scriptorSize\x12\x0b\n\x07\x44S_AUTO\x10\x00\x12\x08\n\x04\x44S_1\x10\x01\x12\x08\n\x04\x44S_2\x10\x02\x12\x08\n\x04\x44S_4\x10\x04\x12\x08\n\x04\x44S_8\x10\x08:E\n\x0enanopb_fileopt\x12\x1c.google.protobuf.FileOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:G\n\rnanopb_msgopt\x12\x1f.google.protobuf.MessageOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:E\n\x0enanopb_enumopt\x12\x1c.google.protobuf.EnumOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptions:>\n\x06nanopb\x12\x1d.google.protobuf.FieldOptions\x18\xf2\x07 \x01(\x0b\x32\x0e.NanoPBOptionsB>\n\x18\x66i.kapsi.koti.jpa.nanopbZ\"github.com/meshtastic/go/generated')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'nanopb_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(nanopb_fileopt)
|
||||
google_dot_protobuf_dot_descriptor__pb2.MessageOptions.RegisterExtension(nanopb_msgopt)
|
||||
google_dot_protobuf_dot_descriptor__pb2.EnumOptions.RegisterExtension(nanopb_enumopt)
|
||||
google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(nanopb)
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\030fi.kapsi.koti.jpa.nanopbZ\"github.com/meshtastic/go/generated'
|
||||
_FIELDTYPE._serialized_start=985
|
||||
_FIELDTYPE._serialized_end=1090
|
||||
_INTSIZE._serialized_start=1092
|
||||
_INTSIZE._serialized_end=1160
|
||||
_TYPENAMEMANGLING._serialized_start=1162
|
||||
_TYPENAMEMANGLING._serialized_end=1252
|
||||
_DESCRIPTORSIZE._serialized_start=1254
|
||||
_DESCRIPTORSIZE._serialized_end=1323
|
||||
_NANOPBOPTIONS._serialized_start=51
|
||||
_NANOPBOPTIONS._serialized_end=983
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,5 +1,6 @@
|
||||
#!/usr/bin/env python3
|
||||
import argparse
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
@@ -11,6 +12,39 @@ def run(cmd, cwd=None):
|
||||
subprocess.run(cmd, cwd=cwd, check=True)
|
||||
|
||||
|
||||
def clone_ref(repo, ref, tmp_path):
|
||||
if re.fullmatch(r"[0-9a-fA-F]{40}", ref):
|
||||
run(["git", "clone", "--no-checkout", "--depth", "1", repo, str(tmp_path)])
|
||||
run(["git", "fetch", "--depth", "1", "origin", ref], cwd=tmp_path)
|
||||
run(["git", "checkout", "--detach", "FETCH_HEAD"], cwd=tmp_path)
|
||||
return
|
||||
|
||||
run(["git", "clone", "--depth", "1", "--branch", ref, repo, str(tmp_path)])
|
||||
|
||||
|
||||
def stage_meshtastic_package(proto_root, tmp_path):
|
||||
"""Map upstream meshtastic/*.proto files to Meshview's vendored package path."""
|
||||
if proto_root != tmp_path / "meshtastic":
|
||||
return tmp_path, proto_root
|
||||
|
||||
stage_root = tmp_path / "_meshview_proto_stage"
|
||||
staged_proto_root = stage_root / "meshtastic" / "protobuf"
|
||||
staged_proto_root.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for proto in sorted(proto_root.glob("*.proto")):
|
||||
text = proto.read_text(encoding="utf-8")
|
||||
text = text.replace('import "meshtastic/', 'import "meshtastic/protobuf/')
|
||||
text = text.replace('import "nanopb.proto"', 'import "meshtastic/protobuf/nanopb.proto"')
|
||||
text = text.replace("package meshtastic;", "package meshtastic.protobuf;")
|
||||
(staged_proto_root / proto.name).write_text(text, encoding="utf-8")
|
||||
|
||||
nanopb = tmp_path / "nanopb.proto"
|
||||
if nanopb.exists():
|
||||
shutil.copy2(nanopb, staged_proto_root / "nanopb.proto")
|
||||
|
||||
return stage_root, staged_proto_root
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Update Meshtastic protobufs")
|
||||
parser.add_argument(
|
||||
@@ -36,7 +70,7 @@ def main():
|
||||
with tempfile.TemporaryDirectory(prefix="meshtastic-protobufs-") as tmp:
|
||||
tmp_path = Path(tmp)
|
||||
print(f"Cloning {args.repo} ({args.ref}) into {tmp_path}...")
|
||||
run(["git", "clone", "--depth", "1", "--branch", args.ref, args.repo, str(tmp_path)])
|
||||
clone_ref(args.repo, args.ref, tmp_path)
|
||||
upstream_rev = (
|
||||
subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=tmp_path).decode().strip()
|
||||
)
|
||||
@@ -57,6 +91,7 @@ def main():
|
||||
# Common locations in the meshtastic/protobufs repo
|
||||
candidates = [
|
||||
tmp_path / "meshtastic" / "protobuf",
|
||||
tmp_path / "meshtastic",
|
||||
tmp_path / "protobufs",
|
||||
tmp_path / "protobuf",
|
||||
tmp_path / "proto",
|
||||
@@ -81,14 +116,17 @@ def main():
|
||||
print(f"No .proto files found in {proto_root}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
rel_protos = [str(p.relative_to(tmp_path)) for p in protos]
|
||||
proto_base, proto_root = stage_meshtastic_package(proto_root, tmp_path)
|
||||
protos = sorted(proto_root.glob("*.proto"))
|
||||
rel_protos = [str(p.relative_to(proto_base)) for p in protos]
|
||||
|
||||
protoc = shutil.which("protoc")
|
||||
if protoc:
|
||||
cmd = [
|
||||
protoc,
|
||||
f"-I{tmp_path}",
|
||||
f"-I{proto_base}",
|
||||
f"--python_out={out_root}",
|
||||
f"--pyi_out={out_root}",
|
||||
*rel_protos,
|
||||
]
|
||||
print("Running protoc...")
|
||||
@@ -107,8 +145,9 @@ def main():
|
||||
sys.executable,
|
||||
"-m",
|
||||
"grpc_tools.protoc",
|
||||
f"-I{tmp_path}",
|
||||
f"-I{proto_base}",
|
||||
f"--python_out={out_root}",
|
||||
f"--pyi_out={out_root}",
|
||||
*rel_protos,
|
||||
]
|
||||
print("Running grpc_tools.protoc...")
|
||||
|
||||
+92
-2
@@ -33,6 +33,8 @@ file_handler.setLevel(logging.INFO)
|
||||
formatter = logging.Formatter('%(asctime)s [%(levelname)s] %(message)s')
|
||||
file_handler.setFormatter(formatter)
|
||||
cleanup_logger.addHandler(file_handler)
|
||||
cleanup_status_file = str(Path(cleanup_logfile).with_suffix(".status.json"))
|
||||
backup_status_file = str(Path(cleanup_logfile).with_name("dbbackup.status.json"))
|
||||
|
||||
|
||||
# -------------------------
|
||||
@@ -49,6 +51,32 @@ def get_int(config, section, key, default=0):
|
||||
return default
|
||||
|
||||
|
||||
def _rowcount(value):
|
||||
return value if value is not None and value >= 0 else None
|
||||
|
||||
|
||||
def write_cleanup_status(status: dict) -> None:
|
||||
status_path = Path(cleanup_status_file)
|
||||
tmp_path = status_path.with_suffix(f"{status_path.suffix}.tmp")
|
||||
try:
|
||||
with open(tmp_path, "w", encoding="utf-8") as f:
|
||||
json.dump(status, f, indent=2)
|
||||
tmp_path.replace(status_path)
|
||||
except Exception as e:
|
||||
cleanup_logger.warning(f"Failed to write cleanup status file: {e}")
|
||||
|
||||
|
||||
def write_backup_status(status: dict) -> None:
|
||||
status_path = Path(backup_status_file)
|
||||
tmp_path = status_path.with_suffix(f"{status_path.suffix}.tmp")
|
||||
try:
|
||||
with open(tmp_path, "w", encoding="utf-8") as f:
|
||||
json.dump(status, f, indent=2)
|
||||
tmp_path.replace(status_path)
|
||||
except Exception as e:
|
||||
cleanup_logger.warning(f"Failed to write backup status file: {e}")
|
||||
|
||||
|
||||
# -------------------------
|
||||
# Shared DB lock
|
||||
# -------------------------
|
||||
@@ -66,19 +94,40 @@ async def backup_database(database_url: str, backup_dir: str = ".") -> None:
|
||||
database_url: SQLAlchemy connection string
|
||||
backup_dir: Directory to store backups (default: current directory)
|
||||
"""
|
||||
backup_status = {
|
||||
"status": "running",
|
||||
"started_at": datetime.datetime.now(datetime.UTC).isoformat(),
|
||||
"completed_at": None,
|
||||
"backup_dir": backup_dir,
|
||||
"database_path": None,
|
||||
"backup_file": None,
|
||||
"original_size_bytes": None,
|
||||
"compressed_size_bytes": None,
|
||||
"compression_percent": None,
|
||||
"error": None,
|
||||
}
|
||||
write_backup_status(backup_status)
|
||||
|
||||
try:
|
||||
url = make_url(database_url)
|
||||
if not url.drivername.startswith("sqlite"):
|
||||
cleanup_logger.warning("Backup only supported for SQLite databases")
|
||||
backup_status["status"] = "unsupported"
|
||||
backup_status["error"] = "Backup only supported for SQLite databases"
|
||||
return
|
||||
|
||||
if not url.database or url.database == ":memory:":
|
||||
cleanup_logger.error("Could not extract database path from connection string")
|
||||
backup_status["status"] = "error"
|
||||
backup_status["error"] = "Could not extract database path from connection string"
|
||||
return
|
||||
|
||||
db_file = Path(url.database)
|
||||
backup_status["database_path"] = str(db_file)
|
||||
if not db_file.exists():
|
||||
cleanup_logger.error(f"Database file not found: {db_file}")
|
||||
backup_status["status"] = "error"
|
||||
backup_status["error"] = f"Database file not found: {db_file}"
|
||||
return
|
||||
|
||||
# Create backup directory if it doesn't exist
|
||||
@@ -89,6 +138,7 @@ async def backup_database(database_url: str, backup_dir: str = ".") -> None:
|
||||
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_filename = f"{db_file.stem}_backup_{timestamp}.db.gz"
|
||||
backup_file = backup_path / backup_filename
|
||||
backup_status["backup_file"] = str(backup_file)
|
||||
|
||||
cleanup_logger.info(f"Creating backup: {backup_file}")
|
||||
|
||||
@@ -98,9 +148,15 @@ async def backup_database(database_url: str, backup_dir: str = ".") -> None:
|
||||
shutil.copyfileobj(f_in, f_out)
|
||||
|
||||
# Get file sizes for logging
|
||||
original_size = db_file.stat().st_size / (1024 * 1024) # MB
|
||||
compressed_size = backup_file.stat().st_size / (1024 * 1024) # MB
|
||||
original_size_bytes = db_file.stat().st_size
|
||||
compressed_size_bytes = backup_file.stat().st_size
|
||||
original_size = original_size_bytes / (1024 * 1024) # MB
|
||||
compressed_size = compressed_size_bytes / (1024 * 1024) # MB
|
||||
compression_ratio = (1 - compressed_size / original_size) * 100 if original_size > 0 else 0
|
||||
backup_status["original_size_bytes"] = original_size_bytes
|
||||
backup_status["compressed_size_bytes"] = compressed_size_bytes
|
||||
backup_status["compression_percent"] = round(compression_ratio, 1)
|
||||
backup_status["status"] = "ok"
|
||||
|
||||
cleanup_logger.info(
|
||||
f"Backup created successfully: {backup_file.name} "
|
||||
@@ -110,6 +166,11 @@ async def backup_database(database_url: str, backup_dir: str = ".") -> None:
|
||||
|
||||
except Exception as e:
|
||||
cleanup_logger.error(f"Error creating database backup: {e}")
|
||||
backup_status["status"] = "error"
|
||||
backup_status["error"] = str(e)
|
||||
finally:
|
||||
backup_status["completed_at"] = datetime.datetime.now(datetime.UTC).isoformat()
|
||||
write_backup_status(backup_status)
|
||||
|
||||
|
||||
# -------------------------
|
||||
@@ -179,6 +240,24 @@ async def daily_cleanup_at(
|
||||
).replace(tzinfo=None)
|
||||
cutoff_us = int(cutoff_dt.timestamp() * 1_000_000)
|
||||
cleanup_logger.info(f"Running cleanup for records older than {cutoff_dt.isoformat()}...")
|
||||
rows_deleted = {
|
||||
"packet": None,
|
||||
"packet_seen": None,
|
||||
"traceroute": None,
|
||||
"node": None,
|
||||
}
|
||||
cleanup_status = {
|
||||
"status": "running",
|
||||
"started_at": datetime.datetime.now(datetime.UTC).isoformat(),
|
||||
"completed_at": None,
|
||||
"cutoff_at": cutoff_dt.replace(tzinfo=datetime.UTC).isoformat(),
|
||||
"days_to_keep": days_to_keep,
|
||||
"vacuum_requested": vacuum_db,
|
||||
"vacuum_completed": False,
|
||||
"rows_deleted": rows_deleted,
|
||||
"error": None,
|
||||
}
|
||||
write_cleanup_status(cleanup_status)
|
||||
|
||||
try:
|
||||
async with db_lock: # Pause ingestion
|
||||
@@ -191,6 +270,7 @@ async def daily_cleanup_at(
|
||||
result = await session.execute(
|
||||
delete(models.Packet).where(models.Packet.import_time_us < cutoff_us)
|
||||
)
|
||||
rows_deleted["packet"] = _rowcount(result.rowcount)
|
||||
cleanup_logger.info(f"Deleted {result.rowcount} rows from Packet")
|
||||
|
||||
# -------------------------
|
||||
@@ -201,6 +281,7 @@ async def daily_cleanup_at(
|
||||
models.PacketSeen.import_time_us < cutoff_us
|
||||
)
|
||||
)
|
||||
rows_deleted["packet_seen"] = _rowcount(result.rowcount)
|
||||
cleanup_logger.info(f"Deleted {result.rowcount} rows from PacketSeen")
|
||||
|
||||
# -------------------------
|
||||
@@ -211,6 +292,7 @@ async def daily_cleanup_at(
|
||||
models.Traceroute.import_time_us < cutoff_us
|
||||
)
|
||||
)
|
||||
rows_deleted["traceroute"] = _rowcount(result.rowcount)
|
||||
cleanup_logger.info(f"Deleted {result.rowcount} rows from Traceroute")
|
||||
|
||||
# -------------------------
|
||||
@@ -219,6 +301,7 @@ async def daily_cleanup_at(
|
||||
result = await session.execute(
|
||||
delete(models.Node).where(models.Node.last_seen_us < cutoff_us)
|
||||
)
|
||||
rows_deleted["node"] = _rowcount(result.rowcount)
|
||||
cleanup_logger.info(f"Deleted {result.rowcount} rows from Node")
|
||||
|
||||
await session.commit()
|
||||
@@ -228,14 +311,21 @@ async def daily_cleanup_at(
|
||||
async with mqtt_database.engine.begin() as conn:
|
||||
await conn.exec_driver_sql("VACUUM;")
|
||||
cleanup_logger.info("VACUUM completed.")
|
||||
cleanup_status["vacuum_completed"] = True
|
||||
elif vacuum_db:
|
||||
cleanup_logger.info("VACUUM skipped (not supported for this database).")
|
||||
|
||||
cleanup_logger.info("Cleanup completed successfully.")
|
||||
cleanup_logger.info("Ingestion resumed after cleanup.")
|
||||
cleanup_status["status"] = "ok"
|
||||
|
||||
except Exception as e:
|
||||
cleanup_logger.error(f"Error during cleanup: {e}")
|
||||
cleanup_status["status"] = "error"
|
||||
cleanup_status["error"] = str(e)
|
||||
finally:
|
||||
cleanup_status["completed_at"] = datetime.datetime.now(datetime.UTC).isoformat()
|
||||
write_cleanup_status(cleanup_status)
|
||||
|
||||
|
||||
# -------------------------
|
||||
|
||||
Reference in New Issue
Block a user