mirror of
https://github.com/pablorevilla-meshtastic/meshview.git
synced 2026-11-01 11:35:47 +01:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d175ed1eb0 | ||
|
|
852703ac69 | ||
|
|
fd94477013 | ||
|
|
5559c84a58 | ||
|
|
9952426aee | ||
|
|
424998090d | ||
|
|
b3b95dbb81 |
No files matched your search
@@ -6,7 +6,6 @@ The project serves as a real-time monitoring and diagnostic tool for the Meshtas
|
||||
|
||||
### Version 3.0.9 — October 2026
|
||||
|
||||
- Protobufs: refreshed Meshtastic schemas and Python type stubs to upstream commit `569a2b3ae7b6bda1a7ab177463a55d8ede3bef53`; updated the refresh script to handle custom metadata options.
|
||||
- Live map: added animated packet traces from senders to reporting gateways and configurable channel colors through the optional `[map_channel_colors]` section in `config.ini`.
|
||||
- Daily snapshots: new snapshots report activity for the previous complete UTC day, including newly imported packets, unique packet senders observed that day, and gateways that reported packets that day. Existing historical snapshots keep their original counts.
|
||||
- Node tracking: record nodes from packet activity before their node information arrives, and preserve known positions when map reports have missing or invalid coordinates.
|
||||
@@ -16,6 +15,29 @@ The project serves as a real-time monitoring and diagnostic tool for the Meshtas
|
||||
- Coverage API: validate and bound request parameters, and run coverage calculations off the event loop to keep the web server responsive.
|
||||
- Contributors: thanks to [nullrouten0](https://github.com/nullrouten0) and Nathan for the neighbor SNR chart, MQTT reliability, security, privacy, and coverage API fixes; Manuel Villaverde for improving map channel color visibility; and [Pablo Revilla](https://github.com/pablorevilla-meshtastic) for the live map, node tracking, and daily snapshot updates.
|
||||
|
||||
#### Updating your configuration for 3.0.9
|
||||
|
||||
Add the following section at the end of your existing `config.ini` to use these map channel colors.
|
||||
If `[map_channel_colors]` already exists, update that section instead of adding a duplicate.
|
||||
|
||||
```ini
|
||||
# Map channel color overrides. Use six-digit hex colors; other channels get generated colors.
|
||||
# Names ignore case, spaces, hyphens, and underscores. Restart the web server after editing.
|
||||
[map_channel_colors]
|
||||
LongFast = #4363d8
|
||||
LongSlow = #000075
|
||||
VeryLongSlow = #808000
|
||||
MediumSlow = #008080
|
||||
MediumFast = #e6194b
|
||||
ShortSlow = #911eb4
|
||||
ShortFast = #f58231
|
||||
LongModerate = #46f0f0
|
||||
ShortTurbo = #f032e6
|
||||
```
|
||||
|
||||
Restart the web server and reload the map after saving. This section is optional;
|
||||
channels without an override use generated colors.
|
||||
|
||||
### Version 3.0.8 — September 2026
|
||||
- Map updates: added OpenTopoMap as a selectable base map, improved map controls, and fixed several map/node display edge cases.
|
||||
- Traceroute: added a dedicated traceroute page, corrected route path orientation in graph edges, and improved traceroute API/documentation support.
|
||||
@@ -34,10 +56,7 @@ The project serves as a real-time monitoring and diagnostic tool for the Meshtas
|
||||
- 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.
|
||||
Each new snapshot stores packets imported during the previous complete UTC day,
|
||||
labeled with that day's date. Node and gateway counts are database totals at capture
|
||||
time. Existing historical snapshots retain their previously stored packet totals.
|
||||
- Daily snapshots: added the `daily_snapshot` table, scheduled snapshot capture, and `/api/snapshots/daily` for historical node, packet, and gateway counts. These originally stored database totals; version 3.0.9 changes new snapshots to daily activity 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.
|
||||
@@ -298,6 +317,9 @@ title = Bay Area Mesh
|
||||
# A brief message shown on the homepage.
|
||||
message = Real time data from around the bay area and beyond.
|
||||
|
||||
# Starting URL when loading the index page.
|
||||
starting = /chat
|
||||
|
||||
# Enable or disable site features (as strings: "True" or "False").
|
||||
nodes = True
|
||||
conversations = True
|
||||
@@ -307,8 +329,6 @@ stats = True
|
||||
net = True
|
||||
map = True
|
||||
top = True
|
||||
# Show the API documentation link in the navigation bar (default: True).
|
||||
api = True
|
||||
|
||||
# Map boundaries (used for the map view).
|
||||
# Defaults will show the San Francisco Bay Area
|
||||
|
||||
+14
-271
@@ -2,43 +2,8 @@
|
||||
|
||||
Base URL: `http(s)://<host>`
|
||||
|
||||
This reference covers all 16 GET routes registered in `meshview/web_api/api.py`,
|
||||
including `/health` and `/version`. The browser version is served at `/api.html`.
|
||||
Responses below are illustrative examples; actual values depend on stored data.
|
||||
Regenerate the browser reference after editing this file with
|
||||
`node scripts/build-api-docs.mjs`.
|
||||
|
||||
## Conventions
|
||||
|
||||
- Successful API responses are JSON. Explicit validation errors usually return JSON
|
||||
with an `error` field. Some unhandled errors return HTTP 500 with a plain-text
|
||||
body; check HTTP status and Content-Type before parsing an error response.
|
||||
- All routes are read-only. The application does not require an API token; a reverse
|
||||
proxy may impose authentication. There are no application-level write endpoints.
|
||||
- `*_us` timestamps and `since` use microseconds since the Unix epoch. Snapshot dates
|
||||
and statistics buckets use UTC. Node latitude/longitude integers must be divided
|
||||
by 10,000,000 to obtain degrees; coverage coordinates are already degrees.
|
||||
- Packet `id` and `storage_id` are database row IDs. Use these for the `packet_id`
|
||||
query/path parameters on packet, observation, count, and traceroute endpoints.
|
||||
A response field named `packet_id` on a packet object is instead its over-the-air
|
||||
Meshtastic ID. `reply_id`, when present, is also an over-the-air ID. These ID types
|
||||
are not interchangeable. Node IDs are numeric Meshtastic node numbers; the node
|
||||
object's `id` is a separate string identifier.
|
||||
- Use decimal node IDs throughout. The packet sender/recipient filters and the QR
|
||||
and coverage paths also accept Python-style `0x` hexadecimal numbers. This is
|
||||
not supported consistently by the other routes.
|
||||
- Public broadcast text is readable. Direct text messages on port 1 are returned as
|
||||
`<redacted>`. Request chat with `/api/packets?portnum=1`; there is no `/api/chat`
|
||||
route. Do not treat a decoded `payload` string as trusted HTML.
|
||||
|
||||
## Quick examples
|
||||
|
||||
```sh
|
||||
curl 'http://localhost:8081/api/nodes?days_active=3'
|
||||
curl 'http://localhost:8081/api/packets?portnum=1&limit=100'
|
||||
curl 'http://localhost:8081/api/stats/count'
|
||||
curl 'http://localhost:8081/api/coverage/1234?mode=perimeter&radius_km=20'
|
||||
```
|
||||
All endpoints return JSON. Timestamps are either ISO 8601 strings or `*_us` values in
|
||||
microseconds since epoch.
|
||||
|
||||
## 1. Nodes API
|
||||
|
||||
@@ -50,21 +15,14 @@ Query Parameters
|
||||
- `role` (optional, string): Node role.
|
||||
- `channel` (optional, string): Channel name.
|
||||
- `hw_model` (optional, string): Hardware model.
|
||||
- `days_active` (optional, int): Nodes seen within the last N days. Omit for all
|
||||
nodes with a non-null last-seen timestamp; invalid integers are ignored.
|
||||
|
||||
Nodes are sorted by `short_name` ascending. `role` is normalized to uppercase;
|
||||
channel and hardware filters are exact matches. No pagination is implemented.
|
||||
|
||||
Errors: HTTP 500 with `{"error":"Failed to fetch nodes"}` for handler failures;
|
||||
the storage helper may return an empty list for database failures.
|
||||
- `days_active` (optional, int): Nodes seen within the last N days.
|
||||
|
||||
Response Example
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "!000004d2",
|
||||
"id": 42,
|
||||
"node_id": 1234,
|
||||
"long_name": "Alice",
|
||||
"short_name": "A",
|
||||
@@ -74,8 +32,6 @@ Response Example
|
||||
"last_lat": 377749000,
|
||||
"last_long": -1224194000,
|
||||
"channel": "main",
|
||||
"is_mqtt_gateway": true,
|
||||
"first_seen_us": 1736283723456789,
|
||||
"last_seen_us": 1736370123456789
|
||||
}
|
||||
]
|
||||
@@ -90,7 +46,7 @@ Response Example
|
||||
Returns packets with optional filters.
|
||||
|
||||
Query Parameters
|
||||
- `packet_id` (optional, decimal int): Return one packet by database row ID (overrides other filters).
|
||||
- `packet_id` (optional, int): Return exactly one packet (overrides other filters).
|
||||
- `limit` (optional, int): Max packets to return, clamped 1-1000. Default: `50`.
|
||||
- `since` (optional, int): Only packets imported after this microsecond timestamp.
|
||||
- `portnum` (optional, int): Filter by port number.
|
||||
@@ -105,16 +61,14 @@ Response Example
|
||||
"packets": [
|
||||
{
|
||||
"id": 123,
|
||||
"storage_id": 123,
|
||||
"packet_id": 3314808102,
|
||||
"import_time_us": 1736370123456789,
|
||||
"channel": "main",
|
||||
"from_node_id": 5678,
|
||||
"to_node_id": 4294967295,
|
||||
"to_node_id": 91011,
|
||||
"portnum": 1,
|
||||
"long_name": "Alice",
|
||||
"payload": "Hello, mesh!",
|
||||
"to_long_name": null,
|
||||
"payload": "Hello, Bob!",
|
||||
"to_long_name": "Bob",
|
||||
"reply_id": 122
|
||||
}
|
||||
],
|
||||
@@ -124,21 +78,7 @@ Response Example
|
||||
|
||||
Notes
|
||||
- For `portnum=1` (text messages), packets are filtered to remove sequence-only payloads.
|
||||
- Results are newest first. `since` is strictly greater than the supplied timestamp.
|
||||
Store `latest_import_time` for the next poll and deduplicate by `id`. A bounded
|
||||
result can omit older records if more packets arrive than the requested limit;
|
||||
this endpoint is not a durable cursor or backfill API.
|
||||
- `latest_import_time` is returned only when the list response has a positive import
|
||||
timestamp; it is absent for empty results and single-packet lookups.
|
||||
- `packet_id` lookup returns `{"packets":[]}` with HTTP 200 when missing. Its objects
|
||||
omit `to_long_name` and `reply_id`; nullable `portnum` is possible in this mode.
|
||||
- `contains` is case-insensitive. With `portnum=1`, matching is performed on decoded
|
||||
displayed payload text (including redaction placeholders) after the database limit is applied, so fewer than `limit` results
|
||||
may be returned. For other requests, it searches stored payload bytes cast to text;
|
||||
this is not a general search over decoded protobuf fields.
|
||||
- Invalid `limit` falls back to 50. Invalid `since`, `portnum`, and node filters are
|
||||
logged and ignored. Invalid single-packet IDs return HTTP 400; handler failures
|
||||
return HTTP 500 with `{"error":"Failed to fetch packets"}`.
|
||||
- `latest_import_time` is returned when available for incremental polling (microseconds).
|
||||
|
||||
---
|
||||
|
||||
@@ -160,10 +100,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
Errors: storage/period failures return HTTP 200 with `channels: []` and an `error`
|
||||
field. Non-integer `length` is parsed outside that handler and can return HTTP 500.
|
||||
Use a positive integer length and the literal `hour` or `day`.
|
||||
|
||||
## 4. Stats API
|
||||
|
||||
### GET `/api/stats`
|
||||
@@ -200,26 +136,13 @@ Response Example (`node` totals)
|
||||
"node_id": 12345678,
|
||||
"period_type": "hour",
|
||||
"length": 24,
|
||||
"sent": 0,
|
||||
"seen": 0
|
||||
"sent": 42,
|
||||
"seen": 58
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
The series response contains only buckets with records, ordered oldest first;
|
||||
missing hours/days are not filled with zeroes. Periods are UTC strings.
|
||||
|
||||
Current `node`-mode limitation: the handler reads a `total` key that the statistics
|
||||
helper does not provide, so `sent` and `seen` currently return zero. It also uses
|
||||
recipient filtering for the second query, rather than gateway observations. This
|
||||
mode ignores the other filters. For usable sent/observation totals, request
|
||||
`/api/stats/count?from_node=1234&period_type=day&length=1` instead.
|
||||
|
||||
Errors: HTTP 400 for an unsupported `period_type`, non-integer `length`, `node`,
|
||||
`portnum`, `from_node`, or `to_node`. Storage failures can return HTTP 500.
|
||||
Use a positive `length`; the handler does not impose a positive lower bound.
|
||||
|
||||
### GET `/api/stats/count`
|
||||
Returns total packet counts, optionally filtered.
|
||||
|
||||
@@ -241,18 +164,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
Without filters, counts cover the whole retained database. With time, channel,
|
||||
or direction filters, omitted time settings default to `period_type=day&length=1`.
|
||||
`total_seen` counts observation rows for packets matching the packet import-time
|
||||
window, not distinct gateways. Channel matching is case-insensitive.
|
||||
|
||||
`packet_id` applies only to `total_seen` and overrides its other filters: it counts
|
||||
all observations of that database packet ID. It does not narrow `total_packets`.
|
||||
In particular, `packet_id` alone leaves `total_packets` as the global packet total.
|
||||
|
||||
Errors: HTTP 400 for non-integer ID/length filters. Unsupported `period_type` or
|
||||
storage failures can return HTTP 500; use `hour` or `day` and a positive length.
|
||||
|
||||
### GET `/api/stats/top`
|
||||
Returns nodes sorted by packets seen, with pagination.
|
||||
|
||||
@@ -285,16 +196,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
`sent` counts packet records from each node; `seen` counts observation records for
|
||||
that sender's packets. `avg` is `round(seen / max(sent, 1), 2)`, not a distinct-gateway
|
||||
count. Windows are anchored to the newest packet and newest observation in the
|
||||
respective tables, not wall-clock time. Nodes with zero activity are included;
|
||||
`total` counts nodes matching the channel filter, not just active nodes.
|
||||
|
||||
Channel matching is exact. Use positive `length` and `limit`, and a nonnegative
|
||||
`offset`. Only the upper limit of 100 is enforced. Invalid numeric strings can
|
||||
return HTTP 500; any `period_type` other than the literal `hour` is treated as days.
|
||||
|
||||
## 5. Edges API
|
||||
|
||||
### GET `/api/edges`
|
||||
@@ -324,12 +225,7 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
Unknown `type` values return an empty edge list. Invalid `node_id` returns HTTP 400;
|
||||
storage failures can return HTTP 500. A missing node is not an error and normally
|
||||
returns an empty list. Neighbor edges come from the latest stored port-71 sample
|
||||
(the storage helper defaults to 50 packets), not the traceroute 12-hour window.
|
||||
|
||||
## 6. Daily Snapshots and Configuration
|
||||
## 6. Config API
|
||||
|
||||
### GET `/api/snapshots/daily`
|
||||
|
||||
@@ -345,22 +241,6 @@ import timestamps, not device timestamps. Older snapshots retain their originall
|
||||
counts and are not automatically converted. Counts depend on the packet and observation
|
||||
history still retained at capture time.
|
||||
|
||||
Query Parameters
|
||||
|
||||
- `length` (optional, int): Return the latest N snapshot records, clamped to 1-3650.
|
||||
Omit for all stored snapshots. Results are always ordered by date ascending.
|
||||
This is a record limit, not a guarantee of consecutive calendar dates.
|
||||
|
||||
Response Example
|
||||
|
||||
```json
|
||||
{"data":[{"date":"2026-10-24","node_count":143,"packet_count":28465,"gateway_count":17,"captured_at_us":1792886400000000}]}
|
||||
```
|
||||
|
||||
No stored snapshots returns `{"data":[]}`. Invalid `length` returns HTTP 400;
|
||||
storage failures return HTTP 500. `captured_at_us` is the capture time, which may
|
||||
be later than the day summarized by `date`.
|
||||
|
||||
### GET `/api/config`
|
||||
Returns a safe subset of server configuration.
|
||||
|
||||
@@ -375,17 +255,6 @@ LongFast = #4363d8
|
||||
LocalChat = #18aa18
|
||||
```
|
||||
|
||||
No query parameters are supported. Only the `site`, MQTT server/topics, and cleanup
|
||||
fields shown here are exposed; credentials and the database connection string are
|
||||
not returned. Feature flags and cleanup booleans are lowercase strings (`"true"` /
|
||||
`"false"`), not JSON booleans. Cleanup scheduling values are strings; map bounds are
|
||||
numbers and refresh intervals are integers. The removed `starting` option is not
|
||||
returned: `/` always serves the dashboard. `site.api` controls visibility of the API
|
||||
documentation link in the navigation bar, defaults to `"true"`, and can be disabled
|
||||
with `api = False` in `[site]`. This setting does not disable documentation or API
|
||||
routes. Restart the web server and reload the page after changing it. Handler
|
||||
failures return HTTP 500.
|
||||
|
||||
Restart the web server and reload the map after changing these settings. Omitting
|
||||
the section uses generated colors for every channel.
|
||||
|
||||
@@ -397,6 +266,7 @@ Response Example
|
||||
"language": "en",
|
||||
"title": "Meshview",
|
||||
"message": "",
|
||||
"starting": "/chat",
|
||||
"nodes": "true",
|
||||
"chat": "true",
|
||||
"everything": "true",
|
||||
@@ -405,13 +275,11 @@ Response Example
|
||||
"net": "true",
|
||||
"map": "true",
|
||||
"top": "true",
|
||||
"api": "true",
|
||||
"map_top_left_lat": 39.0,
|
||||
"map_top_left_lon": -123.0,
|
||||
"map_bottom_right_lat": 36.0,
|
||||
"map_bottom_right_lon": -121.0,
|
||||
"map_interval": 3,
|
||||
"map_channel_colors": {"LongFast":"#4363d8"},
|
||||
"firehose_interval": 3,
|
||||
"weekly_net_message": "Weekly Mesh check-in message.",
|
||||
"net_tag": "#BayMeshNet",
|
||||
@@ -452,10 +320,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
Unknown or invalid language codes fall back to the English file. An unknown section
|
||||
returns HTTP 404. The response has no wrapper: it is either the full translation
|
||||
object or the requested section. Translation-file failures can return HTTP 500.
|
||||
|
||||
## 8. Packets Seen API
|
||||
|
||||
### GET `/api/packets_seen/{packet_id}`
|
||||
@@ -471,7 +335,7 @@ Response Example
|
||||
{
|
||||
"packet_id": 123,
|
||||
"node_id": 456,
|
||||
"rx_time": 1753188300,
|
||||
"rx_time": "2025-07-22T12:45:00",
|
||||
"hop_limit": 7,
|
||||
"hop_start": 0,
|
||||
"channel": "main",
|
||||
@@ -486,16 +350,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
`node_id` identifies the observing MQTT gateway. `rx_time` is the device-provided
|
||||
receive time in Unix seconds, while `import_time_us` is local import time
|
||||
in microseconds. Signal fields can be null. Multiple rows can describe the same
|
||||
gateway; consumers wanting unique gateways must deduplicate them. Hop count is
|
||||
usually `max(0, hop_start - hop_limit)` when both values are known. Observations
|
||||
do not by themselves prove a direct radio link from the sender to that gateway.
|
||||
|
||||
No observations, including for an unknown packet, returns `{"seen":[]}` with HTTP
|
||||
200. Invalid path IDs return HTTP 400; handler failures return HTTP 500.
|
||||
|
||||
## 9. Traceroute API
|
||||
|
||||
### GET `/api/traceroute/{packet_id}`
|
||||
@@ -555,10 +409,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
`traceroute_packets` can be empty even when the packet exists. Unknown database
|
||||
packet IDs return HTTP 404. Invalid integer IDs and storage failures can return
|
||||
HTTP 500; this handler does not implement a separate HTTP 400 validation branch.
|
||||
|
||||
## 10. Health API
|
||||
|
||||
### GET `/health`
|
||||
@@ -622,15 +472,6 @@ Response Example
|
||||
|
||||
---
|
||||
|
||||
No query parameters. HTTP 200 reports `status: "healthy"` with database connectivity.
|
||||
A database failure returns HTTP 503 with `status: "unhealthy"` and
|
||||
`database: "disconnected"`. `seconds_since_last_message` is included only when a
|
||||
latest imported packet exists; SQLite size fields appear only when available.
|
||||
Cleanup and backup reports include configured schedules and status-file contents
|
||||
when present. Their status may be `disabled`, `unknown`, `error`, or the last job's
|
||||
recorded status; a failed backup/cleanup does not itself change the top-level HTTP
|
||||
status. The optional `last_run` objects depend on the job's stored report.
|
||||
|
||||
## 11. Version API
|
||||
|
||||
### GET `/version`
|
||||
@@ -645,101 +486,3 @@ Response Example
|
||||
"git_revision_short": "abc1234"
|
||||
}
|
||||
```
|
||||
|
||||
No query parameters. HTTP 500 with an `error` field if version metadata cannot be
|
||||
retrieved. A revision may be `unknown` if Git metadata is unavailable.
|
||||
|
||||
## 12. Node Contact URL
|
||||
|
||||
### GET `/api/node/{node_id}/qr`
|
||||
|
||||
Returns a Meshtastic shared-contact URL as JSON, not a PNG or SVG image. The client
|
||||
can encode `meshtastic_url` in a QR code. No query parameters are supported.
|
||||
|
||||
Path Parameters
|
||||
|
||||
- `node_id` (required, int): Node number in decimal or `0x` hexadecimal form.
|
||||
|
||||
Response Example
|
||||
|
||||
```json
|
||||
{
|
||||
"node_id":1234,
|
||||
"long_name":"Alice",
|
||||
"short_name":"A",
|
||||
"role":"CLIENT",
|
||||
"meshtastic_url":"https://meshtastic.org/v/#BASE64URL_CONTACT"
|
||||
}
|
||||
```
|
||||
|
||||
The example contact payload is a placeholder, not an importable contact. The URL
|
||||
encodes node identity and available user metadata as a base64url SharedContact
|
||||
protobuf, with `manually_verified` false. Metadata can be null.
|
||||
|
||||
Errors: HTTP 400 for invalid IDs; HTTP 404 when the node is absent; HTTP 500 for
|
||||
contact serialization failures or unhandled storage errors.
|
||||
|
||||
## 13. Predicted Radio Coverage
|
||||
|
||||
### GET `/api/coverage/{node_id}`
|
||||
|
||||
Computes an ITM area-model prediction centered on the node's last stored position.
|
||||
This is a model prediction, not a measured coverage boundary or terrain profile.
|
||||
The optional `pyitm` dependency is required. Calculations run off the event loop
|
||||
and reuse cached model results. All parameters are optional except the node ID.
|
||||
|
||||
Path Parameters
|
||||
|
||||
- `node_id` (required, int): Node number in decimal or `0x` hexadecimal form.
|
||||
|
||||
Query Parameters
|
||||
|
||||
- `mode` (string, default `perimeter`): `perimeter` or `heatmap`. Currently every
|
||||
value other than the exact string `perimeter` selects the heatmap branch.
|
||||
- `freq_mhz` (number, default `907`): Frequency in MHz; range 1-10000.
|
||||
- `tx_dbm` (number, default `20`): Transmit power in dBm; range -50 to 60.
|
||||
- `tx_height_m` (number, default `5`): Transmit antenna height in meters; range 0-1000.
|
||||
- `rx_height_m` (number, default `1.5`): Receive antenna height in meters; range 0-1000.
|
||||
- `radius_km` (number, default `40`): Maximum distance in kilometers; range 1-200.
|
||||
- `step_km` (number, default `0.25`): Radial sample spacing in kilometers; range 0.05-50.
|
||||
- `reliability` (number, default `0.5`): ITM time fraction; range 0.01-0.99.
|
||||
- `threshold_dbm` (number, default `-120`): Perimeter received-power threshold in dBm;
|
||||
range -200 to 0. Ignored by heatmap computation, although still validated.
|
||||
|
||||
Numeric bounds are inclusive, values must be finite, and `radius_km / step_km`
|
||||
must not exceed 4000. Smaller steps increase computation cost.
|
||||
|
||||
Response Example (`mode=perimeter`)
|
||||
|
||||
```json
|
||||
{
|
||||
"mode":"perimeter",
|
||||
"threshold_dbm":-120.0,
|
||||
"perimeter":[[30.21,-93.20],[30.209,-93.198]]
|
||||
}
|
||||
```
|
||||
|
||||
`perimeter` contains `[latitude, longitude]` degree pairs for the furthest qualifying
|
||||
sample on each modeled bearing. Bearings with no qualifying sample are omitted;
|
||||
the list is not necessarily a closed GeoJSON polygon.
|
||||
|
||||
Response Example (`mode=heatmap`)
|
||||
|
||||
```json
|
||||
{
|
||||
"mode":"heatmap",
|
||||
"min_dbm":-130.0,
|
||||
"max_dbm":-80.0,
|
||||
"points":[[30.21,-93.20,-110.5]]
|
||||
}
|
||||
```
|
||||
|
||||
`points` contains `[latitude, longitude, received_power_dbm]` triples. Min/max values
|
||||
provide a color-scale range, extended from the defaults to include computed values.
|
||||
An empty perimeter or point list is a valid result when no samples qualify.
|
||||
|
||||
Errors: HTTP 400 for invalid IDs, nonnumeric/nonfinite/out-of-range parameters, or
|
||||
an excessive radius/step ratio; HTTP 404 for an unknown node or missing/zero-valued
|
||||
stored coordinates; HTTP 503 when `pyitm` is unavailable. Dependency availability is checked
|
||||
before numeric query validation and node lookup. Unexpected model/storage failures
|
||||
can return HTTP 500.
|
||||
@@ -1 +1 @@
|
||||
569a2b3ae7b6bda1a7ab177463a55d8ede3bef53
|
||||
9ab4a1d08cb833d897aee2367013318718391f2f
|
||||
@@ -19,7 +19,7 @@ from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb
|
||||
from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\xb5\x1d\n\x0c\x41\x64minMessage\x12\x17\n\x0fsession_passkey\x18\x65 \x01(\x0c\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12N\n\x12\x62\x61\x63kup_preferences\x18\x18 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12O\n\x13restore_preferences\x18\x19 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12U\n\x19remove_backup_preferences\x18\x1a \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12H\n\x10send_input_event\x18\x1b \x01(\x0b\x32,.meshtastic.protobuf.AdminMessage.InputEventH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1f\n\x15get_ui_config_request\x18, \x01(\x08H\x00\x12\x45\n\x16get_ui_config_response\x18- \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0fstore_ui_config\x18. \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12\x1a\n\x10set_ignored_node\x18/ \x01(\rH\x00\x12\x1d\n\x13remove_ignored_node\x18\x30 \x01(\rH\x00\x12\x1b\n\x11toggle_muted_node\x18\x31 \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x39\n\x0b\x61\x64\x64_contact\x18\x42 \x01(\x0b\x32\".meshtastic.protobuf.SharedContactH\x00\x12\x45\n\x10key_verification\x18\x43 \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationAdminH\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12 \n\x12reboot_ota_seconds\x18_ \x01(\x05\x42\x02\x18\x01H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x08H\x00\x12\x41\n\x0bota_request\x18\x66 \x01(\x0b\x32*.meshtastic.protobuf.AdminMessage.OTAEventH\x00\x12:\n\rsensor_config\x18g \x01(\x0b\x32!.meshtastic.protobuf.SensorConfigH\x00\x12:\n\rlockdown_auth\x18h \x01(\x0b\x32!.meshtastic.protobuf.LockdownAuthH\x00\x1aS\n\nInputEvent\x12\x12\n\nevent_code\x18\x01 \x01(\r\x12\x0f\n\x07kb_char\x18\x02 \x01(\r\x12\x0f\n\x07touch_x\x18\x03 \x01(\r\x12\x0f\n\x07touch_y\x18\x04 \x01(\r\x1aS\n\x08OTAEvent\x12\x35\n\x0freboot_ota_mode\x18\x01 \x01(\x0e\x32\xLine truncated
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1fmeshtastic/protobuf/admin.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a+meshtastic/protobuf/connection_status.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\x1emeshtastic/protobuf/mesh.proto\x1a\'meshtastic/protobuf/module_config.proto\"\x9e\x1d\n\x0c\x41\x64minMessage\x12\x17\n\x0fsession_passkey\x18\x65 \x01(\x0c\x12\x1d\n\x13get_channel_request\x18\x01 \x01(\rH\x00\x12<\n\x14get_channel_response\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x1b\n\x11get_owner_request\x18\x03 \x01(\x08H\x00\x12\x37\n\x12get_owner_response\x18\x04 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12J\n\x12get_config_request\x18\x05 \x01(\x0e\x32,.meshtastic.protobuf.AdminMessage.ConfigTypeH\x00\x12:\n\x13get_config_response\x18\x06 \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12W\n\x19get_module_config_request\x18\x07 \x01(\x0e\x32\x32.meshtastic.protobuf.AdminMessage.ModuleConfigTypeH\x00\x12G\n\x1aget_module_config_response\x18\x08 \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12\x34\n*get_canned_message_module_messages_request\x18\n \x01(\x08H\x00\x12\x35\n+get_canned_message_module_messages_response\x18\x0b \x01(\tH\x00\x12%\n\x1bget_device_metadata_request\x18\x0c \x01(\x08H\x00\x12K\n\x1cget_device_metadata_response\x18\r \x01(\x0b\x32#.meshtastic.protobuf.DeviceMetadataH\x00\x12\x1e\n\x14get_ringtone_request\x18\x0e \x01(\x08H\x00\x12\x1f\n\x15get_ringtone_response\x18\x0f \x01(\tH\x00\x12.\n$get_device_connection_status_request\x18\x10 \x01(\x08H\x00\x12\\\n%get_device_connection_status_response\x18\x11 \x01(\x0b\x32+.meshtastic.protobuf.DeviceConnectionStatusH\x00\x12:\n\x0cset_ham_mode\x18\x12 \x01(\x0b\x32\".meshtastic.protobuf.HamParametersH\x00\x12/\n%get_node_remote_hardware_pins_request\x18\x13 \x01(\x08H\x00\x12\x65\n&get_node_remote_hardware_pins_response\x18\x14 \x01(\x0b\x32\x33.meshtastic.protobuf.NodeRemoteHardwarePinsResponseH\x00\x12 \n\x16\x65nter_dfu_mode_request\x18\x15 \x01(\x08H\x00\x12\x1d\n\x13\x64\x65lete_file_request\x18\x16 \x01(\tH\x00\x12\x13\n\tset_scale\x18\x17 \x01(\rH\x00\x12N\n\x12\x62\x61\x63kup_preferences\x18\x18 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12O\n\x13restore_preferences\x18\x19 \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12U\n\x19remove_backup_preferences\x18\x1a \x01(\x0e\x32\x30.meshtastic.protobuf.AdminMessage.BackupLocationH\x00\x12H\n\x10send_input_event\x18\x1b \x01(\x0b\x32,.meshtastic.protobuf.AdminMessage.InputEventH\x00\x12.\n\tset_owner\x18 \x01(\x0b\x32\x19.meshtastic.protobuf.UserH\x00\x12\x33\n\x0bset_channel\x18! \x01(\x0b\x32\x1c.meshtastic.protobuf.ChannelH\x00\x12\x31\n\nset_config\x18\" \x01(\x0b\x32\x1b.meshtastic.protobuf.ConfigH\x00\x12>\n\x11set_module_config\x18# \x01(\x0b\x32!.meshtastic.protobuf.ModuleConfigH\x00\x12,\n\"set_canned_message_module_messages\x18$ \x01(\tH\x00\x12\x1e\n\x14set_ringtone_message\x18% \x01(\tH\x00\x12\x1b\n\x11remove_by_nodenum\x18& \x01(\rH\x00\x12\x1b\n\x11set_favorite_node\x18\' \x01(\rH\x00\x12\x1e\n\x14remove_favorite_node\x18( \x01(\rH\x00\x12;\n\x12set_fixed_position\x18) \x01(\x0b\x32\x1d.meshtastic.protobuf.PositionH\x00\x12\x1f\n\x15remove_fixed_position\x18* \x01(\x08H\x00\x12\x17\n\rset_time_only\x18+ \x01(\x07H\x00\x12\x1f\n\x15get_ui_config_request\x18, \x01(\x08H\x00\x12\x45\n\x16get_ui_config_response\x18- \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12>\n\x0fstore_ui_config\x18. \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x12\x1a\n\x10set_ignored_node\x18/ \x01(\rH\x00\x12\x1d\n\x13remove_ignored_node\x18\x30 \x01(\rH\x00\x12\x1b\n\x11toggle_muted_node\x18\x31 \x01(\rH\x00\x12\x1d\n\x13\x62\x65gin_edit_settings\x18@ \x01(\x08H\x00\x12\x1e\n\x14\x63ommit_edit_settings\x18\x41 \x01(\x08H\x00\x12\x39\n\x0b\x61\x64\x64_contact\x18\x42 \x01(\x0b\x32\".meshtastic.protobuf.SharedContactH\x00\x12\x45\n\x10key_verification\x18\x43 \x01(\x0b\x32).meshtastic.protobuf.KeyVerificationAdminH\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_device\x18^ \x01(\x05H\x00\x12 \n\x12reboot_ota_seconds\x18_ \x01(\x05\x42\x02\x18\x01H\x00\x12\x18\n\x0e\x65xit_simulator\x18` \x01(\x08H\x00\x12\x18\n\x0ereboot_seconds\x18\x61 \x01(\x05H\x00\x12\x1a\n\x10shutdown_seconds\x18\x62 \x01(\x05H\x00\x12\x1e\n\x14\x66\x61\x63tory_reset_config\x18\x63 \x01(\x05H\x00\x12\x16\n\x0cnodedb_reset\x18\x64 \x01(\x08H\x00\x12\x41\n\x0bota_request\x18\x66 \x01(\x0b\x32*.meshtastic.protobuf.AdminMessage.OTAEventH\x00\x12:\n\rsensor_config\x18g \x01(\x0b\x32!.meshtastic.protobuf.SensorConfigH\x00\x12:\n\rlockdown_auth\x18h \x01(\x0b\x32!.meshtastic.protobuf.LockdownAuthH\x00\x1aS\n\nInputEvent\x12\x12\n\nevent_code\x18\x01 \x01(\r\x12\x0f\n\x07kb_char\x18\x02 \x01(\r\x12\x0f\n\x07touch_x\x18\x03 \x01(\r\x12\x0f\n\x07touch_y\x18\x04 \x01(\r\x1aS\n\x08OTAEvent\x12\x35\n\x0freboot_ota_mode\x18\x01 \x01(\x0e\x32\xLine truncated
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.admin_pb2', globals())
|
||||
@@ -29,10 +29,10 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\013AdminProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_ADMINMESSAGE.fields_by_name['reboot_ota_seconds']._options = None
|
||||
_ADMINMESSAGE.fields_by_name['reboot_ota_seconds']._serialized_options = b'\030\001'
|
||||
_OTAMODE._serialized_start=6748
|
||||
_OTAMODE._serialized_end=6803
|
||||
_OTAMODE._serialized_start=5852
|
||||
_OTAMODE._serialized_end=5907
|
||||
_ADMINMESSAGE._serialized_start=281
|
||||
_ADMINMESSAGE._serialized_end=4046
|
||||
_ADMINMESSAGE._serialized_end=4023
|
||||
_ADMINMESSAGE_INPUTEVENT._serialized_start=3192
|
||||
_ADMINMESSAGE_INPUTEVENT._serialized_end=3275
|
||||
_ADMINMESSAGE_OTAEVENT._serialized_start=3277
|
||||
@@ -40,35 +40,29 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
_ADMINMESSAGE_CONFIGTYPE._serialized_start=3363
|
||||
_ADMINMESSAGE_CONFIGTYPE._serialized_end=3577
|
||||
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_start=3580
|
||||
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=3990
|
||||
_ADMINMESSAGE_BACKUPLOCATION._serialized_start=3992
|
||||
_ADMINMESSAGE_BACKUPLOCATION._serialized_end=4027
|
||||
_LOCKDOWNAUTH._serialized_start=4049
|
||||
_LOCKDOWNAUTH._serialized_end=4199
|
||||
_HAMPARAMETERS._serialized_start=4201
|
||||
_HAMPARAMETERS._serialized_end=4311
|
||||
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=4313
|
||||
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=4424
|
||||
_SHAREDCONTACT._serialized_start=4426
|
||||
_SHAREDCONTACT._serialized_end=4550
|
||||
_KEYVERIFICATIONADMIN._serialized_start=4553
|
||||
_KEYVERIFICATIONADMIN._serialized_end=4846
|
||||
_KEYVERIFICATIONADMIN_MESSAGETYPE._serialized_start=4723
|
||||
_KEYVERIFICATIONADMIN_MESSAGETYPE._serialized_end=4826
|
||||
_SENSORCONFIG._serialized_start=4849
|
||||
_SENSORCONFIG._serialized_end=5266
|
||||
_SCD4X_CONFIG._serialized_start=5269
|
||||
_SCD4X_CONFIG._serialized_end=5623
|
||||
_SEN5X_CONFIG._serialized_start=5626
|
||||
_SEN5X_CONFIG._serialized_end=5800
|
||||
_SEN6X_CONFIG._serialized_start=5803
|
||||
_SEN6X_CONFIG._serialized_end=6219
|
||||
_SCD30_CONFIG._serialized_start=6222
|
||||
_SCD30_CONFIG._serialized_end=6530
|
||||
_SHTXX_CONFIG._serialized_start=6532
|
||||
_SHTXX_CONFIG._serialized_end=6590
|
||||
_DS248X_CONFIG._serialized_start=6592
|
||||
_DS248X_CONFIG._serialized_end=6675
|
||||
_AS3935_CONFIG._serialized_start=6677
|
||||
_AS3935_CONFIG._serialized_end=6746
|
||||
_ADMINMESSAGE_MODULECONFIGTYPE._serialized_end=3967
|
||||
_ADMINMESSAGE_BACKUPLOCATION._serialized_start=3969
|
||||
_ADMINMESSAGE_BACKUPLOCATION._serialized_end=4004
|
||||
_LOCKDOWNAUTH._serialized_start=4025
|
||||
_LOCKDOWNAUTH._serialized_end=4129
|
||||
_HAMPARAMETERS._serialized_start=4131
|
||||
_HAMPARAMETERS._serialized_end=4222
|
||||
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_start=4224
|
||||
_NODEREMOTEHARDWAREPINSRESPONSE._serialized_end=4335
|
||||
_SHAREDCONTACT._serialized_start=4337
|
||||
_SHAREDCONTACT._serialized_end=4461
|
||||
_KEYVERIFICATIONADMIN._serialized_start=4464
|
||||
_KEYVERIFICATIONADMIN._serialized_end=4757
|
||||
_KEYVERIFICATIONADMIN_MESSAGETYPE._serialized_start=4634
|
||||
_KEYVERIFICATIONADMIN_MESSAGETYPE._serialized_end=4737
|
||||
_SENSORCONFIG._serialized_start=4760
|
||||
_SENSORCONFIG._serialized_end=5002
|
||||
_SCD4X_CONFIG._serialized_start=5005
|
||||
_SCD4X_CONFIG._serialized_end=5359
|
||||
_SEN5X_CONFIG._serialized_start=5361
|
||||
_SEN5X_CONFIG._serialized_end=5479
|
||||
_SCD30_CONFIG._serialized_start=5482
|
||||
_SCD30_CONFIG._serialized_end=5790
|
||||
_SHTXX_CONFIG._serialized_start=5792
|
||||
_SHTXX_CONFIG._serialized_end=5850
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -15,12 +15,6 @@ NO_REBOOT_OTA: OTAMode
|
||||
OTA_BLE: OTAMode
|
||||
OTA_WIFI: OTAMode
|
||||
|
||||
class AS3935_config(_message.Message):
|
||||
__slots__ = ["set_tuning_cap_pf"]
|
||||
SET_TUNING_CAP_PF_FIELD_NUMBER: _ClassVar[int]
|
||||
set_tuning_cap_pf: int
|
||||
def __init__(self, set_tuning_cap_pf: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class AdminMessage(_message.Message):
|
||||
__slots__ = ["add_contact", "backup_preferences", "begin_edit_settings", "commit_edit_settings", "delete_file_request", "enter_dfu_mode_request", "exit_simulator", "factory_reset_config", "factory_reset_device", "get_canned_message_module_messages_request", "get_canned_message_module_messages_response", "get_channel_request", "get_channel_response", "get_config_request", "get_config_response", "get_device_connection_status_request", "get_device_connection_status_response", "get_device_metadata_request", "get_device_metadata_response", "get_module_config_request", "get_module_config_response", "get_node_remote_hardware_pins_request", "get_node_remote_hardware_pins_response", "get_owner_request", "get_owner_response", "get_ringtone_request", "get_ringtone_response", "get_ui_config_request", "get_ui_config_response", "key_verification", "lockdown_auth", "nodedb_reset", "ota_request", "reboot_ota_seconds", "reboot_seconds", "remove_backup_preferences", "remove_by_nodenum", "remove_favorite_node", "remove_fixed_position", "remove_ignored_node", "restore_preferences", "send_input_event", "sensor_config", "session_passkey", "set_canned_message_module_messages", "set_channel", "set_config", "set_favorite_node", "set_fixed_position", "set_ham_mode", "set_ignored_node", "set_module_config", "set_owner", "set_ringtone_message", "set_scale", "set_time_only", "shutdown_seconds", "store_ui_config", "toggle_muted_node"]
|
||||
class BackupLocation(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
@@ -89,7 +83,6 @@ class AdminMessage(_message.Message):
|
||||
KEY_VERIFICATION_FIELD_NUMBER: _ClassVar[int]
|
||||
LOCKDOWN_AUTH_FIELD_NUMBER: _ClassVar[int]
|
||||
LORA_CONFIG: AdminMessage.ConfigType
|
||||
MESHBEACON_CONFIG: AdminMessage.ModuleConfigType
|
||||
MQTT_CONFIG: AdminMessage.ModuleConfigType
|
||||
NEIGHBORINFO_CONFIG: AdminMessage.ModuleConfigType
|
||||
NETWORK_CONFIG: AdminMessage.ConfigType
|
||||
@@ -196,25 +189,17 @@ class AdminMessage(_message.Message):
|
||||
toggle_muted_node: int
|
||||
def __init__(self, session_passkey: _Optional[bytes] = ..., get_channel_request: _Optional[int] = ..., get_channel_response: _Optional[_Union[_channel_pb2.Channel, _Mapping]] = ..., get_owner_request: bool = ..., get_owner_response: _Optional[_Union[_mesh_pb2.User, _Mapping]] = ..., get_config_request: _Optional[_Union[AdminMessage.ConfigType, str]] = ..., get_config_response: _Optional[_Union[_config_pb2.Config, _Mapping]] = ..., get_module_config_request: _Optional[_Union[AdminMessage.ModuleConfigType, str]] = ..., get_module_config_response: _Optional[_Union[_module_config_pb2.ModuleConfig, _Mapping]] = ..., get_canned_message_module_messages_request: bool = ..., get_canned_message_module_messages_response: _Optional[str] = ..., get_device_metadata_request: bool = ..., get_device_metadata_response: _Optional[_Union[_mesh_pb2.DeviceMetadata, _Mapping]] = ..., get_ringtone_request: bool = ..., get_ringtone_response: _Optional[str] = ..., get_device_connection_status_request: bool = ..., get_device_connection_status_response: _Optional[_Union[_connection_status_pb2.DeviceConnectionStatus, _Mapping]] = ..., set_ham_mode: _Optional[_Union[HamParameters, _Mapping]] = ..., get_node_remote_hardware_pins_request: bool = ..., get_node_remote_hardware_pins_response: _Optional[_Union[NodeRemoteHardwarePinsResponse, _Mapping]] = ..., enter_dfu_mode_request: bool = ..., delete_file_request: _Optional[str] = ..., set_scale: _Optional[int] = ..., backup_preferences: _Optional[_Union[AdminMessage.BackupLocation, str]] = ..., restore_preferences: _Optional[_Union[AdminMessage.BackupLocation, str]] = ..., remove_backup_preferences: _Optional[_Union[AdminMessage.BackupLocation, str]] = ..., send_input_event: _Optional[_Union[AdminMessage.InputEvent, _Mapping]] = ..., set_owner: _Optional[_Union[_mesh_pb2.User, _Mapping]] = ..., set_channel: _Optional[_Union[_channel_pb2.Channel, _Mapping]] = ..., set_config: _Optional[_Union[_config_pb2.Config, _Mapping]] = ..., set_module_config: _Optional[_Union[_module_config_pb2.ModuleConfig, _Mapping]] = ..., set_canned_message_module_messages: _Optional[str] = ..., set_ringtone_message: _Optional[str] = ..., remove_by_nodenum: _Optional[int] = ..., set_favorite_node: _Optional[int] = ..., remove_favorite_node: _Optional[int] = ..., set_fixed_position: _Optional[_Union[_mesh_pb2.Position, _Mapping]] = ..., remove_fixed_position: bool = ..., set_time_only: _Optional[int] = ..., get_ui_config_request: bool = ..., get_ui_config_response: _Optional[_Union[_device_ui_pb2.DeviceUIConfig, _Mapping]] = ..., store_ui_config: _Optional[_Union[_device_ui_pb2.DeviceUIConfig, _Mapping]] = ..., set_ignored_node: _Optional[int] = ..., remove_ignored_node: _Optional[int] = ..., toggle_muted_node: _Optional[int] = ..., begin_edit_settings: bool = ..., commit_edit_settings: bool = ..., add_contact: _Optional[_Union[SharedContact, _Mapping]] = ..., key_verification: _Optional[_Union[KeyVerificationAdmin, _Mapping]] = ..., factory_reset_device: _Optional[int] = ..., reboot_ota_seconds: _Optional[int] = ..., exit_simulator: bool = ..., reboot_seconds: _Optional[int] = ..., shutdown_seconds: _Optional[int] = ..., factory_reset_config: _Optional[int] = ..., nodedb_reset: bool = ..., ota_request: _Optional[_Union[AdminMessage.OTAEvent, _Mapping]] = ..., sensor_config: _Optional[_Union[SensorConfig, _Mapping]] = ..., lockdown_auth: _Optional[_Union[LockdownAuth, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class DS248X_config(_message.Message):
|
||||
__slots__ = ["main_temperature_channel"]
|
||||
MAIN_TEMPERATURE_CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
main_temperature_channel: int
|
||||
def __init__(self, main_temperature_channel: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class HamParameters(_message.Message):
|
||||
__slots__ = ["call_sign", "frequency", "long_name", "short_name", "tx_power"]
|
||||
__slots__ = ["call_sign", "frequency", "short_name", "tx_power"]
|
||||
CALL_SIGN_FIELD_NUMBER: _ClassVar[int]
|
||||
FREQUENCY_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
SHORT_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
TX_POWER_FIELD_NUMBER: _ClassVar[int]
|
||||
call_sign: str
|
||||
frequency: float
|
||||
long_name: str
|
||||
short_name: str
|
||||
tx_power: int
|
||||
def __init__(self, call_sign: _Optional[str] = ..., tx_power: _Optional[int] = ..., frequency: _Optional[float] = ..., short_name: _Optional[str] = ..., long_name: _Optional[str] = ...) -> None: ...
|
||||
def __init__(self, call_sign: _Optional[str] = ..., tx_power: _Optional[int] = ..., frequency: _Optional[float] = ..., short_name: _Optional[str] = ...) -> None: ...
|
||||
|
||||
class KeyVerificationAdmin(_message.Message):
|
||||
__slots__ = ["message_type", "nonce", "remote_nodenum", "security_number"]
|
||||
@@ -235,20 +220,16 @@ class KeyVerificationAdmin(_message.Message):
|
||||
def __init__(self, message_type: _Optional[_Union[KeyVerificationAdmin.MessageType, str]] = ..., remote_nodenum: _Optional[int] = ..., nonce: _Optional[int] = ..., security_number: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class LockdownAuth(_message.Message):
|
||||
__slots__ = ["boots_remaining", "disable", "lock_now", "max_session_seconds", "passphrase", "valid_until_epoch"]
|
||||
__slots__ = ["boots_remaining", "lock_now", "passphrase", "valid_until_epoch"]
|
||||
BOOTS_REMAINING_FIELD_NUMBER: _ClassVar[int]
|
||||
DISABLE_FIELD_NUMBER: _ClassVar[int]
|
||||
LOCK_NOW_FIELD_NUMBER: _ClassVar[int]
|
||||
MAX_SESSION_SECONDS_FIELD_NUMBER: _ClassVar[int]
|
||||
PASSPHRASE_FIELD_NUMBER: _ClassVar[int]
|
||||
VALID_UNTIL_EPOCH_FIELD_NUMBER: _ClassVar[int]
|
||||
boots_remaining: int
|
||||
disable: bool
|
||||
lock_now: bool
|
||||
max_session_seconds: int
|
||||
passphrase: bytes
|
||||
valid_until_epoch: int
|
||||
def __init__(self, passphrase: _Optional[bytes] = ..., boots_remaining: _Optional[int] = ..., valid_until_epoch: _Optional[int] = ..., lock_now: bool = ..., max_session_seconds: _Optional[int] = ..., disable: bool = ...) -> None: ...
|
||||
def __init__(self, passphrase: _Optional[bytes] = ..., boots_remaining: _Optional[int] = ..., valid_until_epoch: _Optional[int] = ..., lock_now: bool = ...) -> None: ...
|
||||
|
||||
class NodeRemoteHardwarePinsResponse(_message.Message):
|
||||
__slots__ = ["node_remote_hardware_pins"]
|
||||
@@ -291,34 +272,12 @@ class SCD4X_config(_message.Message):
|
||||
def __init__(self, set_asc: bool = ..., set_target_co2_conc: _Optional[int] = ..., set_temperature: _Optional[float] = ..., set_altitude: _Optional[int] = ..., set_ambient_pressure: _Optional[int] = ..., factory_reset: bool = ..., set_power_mode: bool = ...) -> None: ...
|
||||
|
||||
class SEN5X_config(_message.Message):
|
||||
__slots__ = ["set_one_shot_mode", "set_temperature", "start_fan_cleaning"]
|
||||
__slots__ = ["set_one_shot_mode", "set_temperature"]
|
||||
SET_ONE_SHOT_MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_TEMPERATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
START_FAN_CLEANING_FIELD_NUMBER: _ClassVar[int]
|
||||
set_one_shot_mode: bool
|
||||
set_temperature: float
|
||||
start_fan_cleaning: bool
|
||||
def __init__(self, set_temperature: _Optional[float] = ..., set_one_shot_mode: bool = ..., start_fan_cleaning: bool = ...) -> None: ...
|
||||
|
||||
class SEN6X_config(_message.Message):
|
||||
__slots__ = ["factory_reset", "set_altitude", "set_ambient_pressure", "set_asc", "set_one_shot_mode", "set_target_co2_conc", "set_temperature", "start_fan_cleaning"]
|
||||
FACTORY_RESET_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_ALTITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_AMBIENT_PRESSURE_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_ASC_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_ONE_SHOT_MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_TARGET_CO2_CONC_FIELD_NUMBER: _ClassVar[int]
|
||||
SET_TEMPERATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
START_FAN_CLEANING_FIELD_NUMBER: _ClassVar[int]
|
||||
factory_reset: bool
|
||||
set_altitude: int
|
||||
set_ambient_pressure: int
|
||||
set_asc: bool
|
||||
set_one_shot_mode: bool
|
||||
set_target_co2_conc: int
|
||||
set_temperature: float
|
||||
start_fan_cleaning: bool
|
||||
def __init__(self, set_temperature: _Optional[float] = ..., set_one_shot_mode: bool = ..., start_fan_cleaning: bool = ..., set_asc: bool = ..., set_target_co2_conc: _Optional[int] = ..., set_altitude: _Optional[int] = ..., set_ambient_pressure: _Optional[int] = ..., factory_reset: bool = ...) -> None: ...
|
||||
def __init__(self, set_temperature: _Optional[float] = ..., set_one_shot_mode: bool = ...) -> None: ...
|
||||
|
||||
class SHTXX_config(_message.Message):
|
||||
__slots__ = ["set_accuracy"]
|
||||
@@ -327,22 +286,16 @@ class SHTXX_config(_message.Message):
|
||||
def __init__(self, set_accuracy: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class SensorConfig(_message.Message):
|
||||
__slots__ = ["as3935_config", "ds248x_config", "scd30_config", "scd4x_config", "sen5x_config", "sen6x_config", "shtxx_config"]
|
||||
AS3935_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
DS248X_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
__slots__ = ["scd30_config", "scd4x_config", "sen5x_config", "shtxx_config"]
|
||||
SCD30_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
SCD4X_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
SEN5X_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
SEN6X_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
SHTXX_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
as3935_config: AS3935_config
|
||||
ds248x_config: DS248X_config
|
||||
scd30_config: SCD30_config
|
||||
scd4x_config: SCD4X_config
|
||||
sen5x_config: SEN5X_config
|
||||
sen6x_config: SEN6X_config
|
||||
shtxx_config: SHTXX_config
|
||||
def __init__(self, scd4x_config: _Optional[_Union[SCD4X_config, _Mapping]] = ..., sen5x_config: _Optional[_Union[SEN5X_config, _Mapping]] = ..., scd30_config: _Optional[_Union[SCD30_config, _Mapping]] = ..., shtxx_config: _Optional[_Union[SHTXX_config, _Mapping]] = ..., ds248x_config: _Optional[_Union[DS248X_config, _Mapping]] = ..., sen6x_config: _Optional[_Union[SEN6X_config, _Mapping]] = ..., as3935_config: _Optional[_Union[AS3935_config, _Mapping]] = ...) -> None: ...
|
||||
def __init__(self, scd4x_config: _Optional[_Union[SCD4X_config, _Mapping]] = ..., sen5x_config: _Optional[_Union[SEN5X_config, _Mapping]] = ..., scd30_config: _Optional[_Union[SCD30_config, _Mapping]] = ..., shtxx_config: _Optional[_Union[SHTXX_config, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class SharedContact(_message.Message):
|
||||
__slots__ = ["manually_verified", "node_num", "should_ignore", "user"]
|
||||
|
||||
+81
-134
@@ -11,10 +11,9 @@ from google.protobuf import symbol_database as _symbol_database
|
||||
_sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from meshtastic.protobuf import field_metadata_pb2 as meshtastic_dot_protobuf_dot_field__metadata__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\x1a(meshtastic/protobuf/field_metadata.proto\"\xa5\x02\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12-\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.Contact\x12)\n\x05group\x18\x03 \x01(\x0b\x32\x1a.meshtastic.protobuf.Group\x12+\n\x06status\x18\x04 \x01(\x0b\x32\x1b.meshtastic.protobuf.Status\x12\'\n\x03pli\x18\x05 \x01(\x0b\x32\x18.meshtastic.protobuf.PLIH\x00\x12,\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\xfd\x02\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\x0freceipt_for_uid\x18\x04 \x01(\t\x12>\n\x0creceipt_type\x18\x05 \x01(\x0e\x32(.meshtastic.protobuf.GeoChat.ReceiptType\x12\x11\n\x04lang\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07room_id\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\x1d\n\x10voice_profile_id\x18\x08 \x01(\tH\x04\x88\x01\x01\"T\n\x0bReceiptType\x12\x14\n\x10ReceiptType_None\x10\x00\x12\x19\n\x15ReceiptType_Delivered\x10\x01\x12\x14\n\x10ReceiptType_Read\x10\x02\x42\x05\n\x03_toB\x0e\n\x0c_to_callsignB\x07\n\x05_langB\n\n\x08_room_idB\x13\n\x11_voice_profile_id\"_\n\x05Group\x12-\n\x04role\x18\x01 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\'\n\x04team\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\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\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r\"\xb0\x01\n\rAircraftTrack\x12\x0c\n\x04icao\x18\x01 \x01(\t\x12\x14\n\x0cregistration\x18\x02 \x01(\t\x12\x0e\n\x06\x66light\x18\x03 \x01(\t\x12\x15\n\raircraft_type\x18\x04 \x01(\t\x12\x0e\n\x06squawk\x18\x05 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x06 \x01(\t\x12\x10\n\x08rssi_x10\x18\x07 \x01(\x11\x12\x0b\n\x03gps\x18\x08 \x01(\x08\x12\x13\n\x0b\x63ot_host_id\x18\t \x01(\t\"7\n\x0b\x43otGeoPoint\x12\x13\n\x0blat_delta_i\x18\x01 \x01(\x11\x12\x13\n\x0blon_delta_i\x18\x02 \x01(\x11\"\x80\x07\n\nDrawnShape\x12\x32\n\x04kind\x18\x01 \x01(\x0e\x32$.meshtastic.protobuf.DrawnShape.Kind\x12\x38\n\x05style\x18\x02 \x01(\x0e\x32).meshtastic.protobuf.DrawnShape.StyleMode\x12\x10\n\x08major_cm\x18\x03 \x01(\r\x12\x10\n\x08minor_cm\x18\x04 \x01(\r\x12\x11\n\tangle_deg\x18\x05 \x01(\r\x12/\n\x0cstroke_color\x18\x06 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x13\n\x0bstroke_argb\x18\x07 \x01(\x07\x12\x19\n\x11stroke_weight_x10\x18\x08 \x01(\r\x12-\n\nfill_color\x18\t \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x11\n\tfill_argb\x18\n \x01(\x07\x12\x11\n\tlabels_on\x18\x0b \x01(\x08\x12\x19\n\x11vertex_lat_deltas\x18\x12 \x03(\x11\x12\x19\n\x11vertex_lon_deltas\x18\x13 \x03(\x11\x12\x11\n\ttruncated\x18\r \x01(\x08\x12\x1c\n\x14\x62ullseye_distance_dm\x18\x0e \x01(\r\x12\x1c\n\x14\x62ullseye_bearing_ref\x18\x0f \x01(\r\x12\x16\n\x0e\x62ullseye_flags\x18\x10 \x01(\r\x12\x18\n\x10\x62ullseye_uid_ref\x18\x11 \x01(\t\"\xe2\x01\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\x0f\n\x0bKind_Circle\x10\x01\x12\x12\n\x0eKind_Rectangle\x10\x02\x12\x11\n\rKind_Freeform\x10\x03\x12\x15\n\x11Kind_Telestration\x10\x04\x12\x10\n\x0cKind_Polygon\x10\x05\x12\x16\n\x12Kind_RangingCircle\x10\x06\x12\x11\n\rKind_Bullseye\x10\x07\x12\x10\n\x0cKind_Ellipse\x10\x08\x12\x12\n\x0eKind_Vehicle2D\x10\t\x12\x12\n\x0eKind_Vehicle3D\x10\n\"u\n\tStyleMode\x12\x19\n\x15StyleMode_Unspecified\x10\x00\x12\x18\n\x14StyleMode_StrokeOnly\x10\x01\x12\x16\n\x12StyleMode_FillOnly\x10\x02\x12\x1b\n\x17StyleMode_StrokeAndFill\x10\x03J\x04\x08\x0c\x10\r\"\xf7\x03\n\x06Marker\x12.\n\x04kind\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.Marker.Kind\x12(\n\x05\x63olor\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x12\n\ncolor_argb\x18\x03 \x01(\x07\x12\x11\n\treadiness\x18\x04 \x01(\x08\x12\x12\n\nparent_uid\x18\x05 \x01(\t\x12\x13\n\x0bparent_type\x18\x06 \x01(\t\x12\x17\n\x0fparent_callsign\x18\x07 \x01(\t\x12\x0f\n\x07iconset\x18\x08 \x01(\t\"\x98\x02\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\r\n\tKind_Spot\x10\x01\x12\x11\n\rKind_Waypoint\x10\x02\x12\x13\n\x0fKind_Checkpoint\x10\x03\x12\x15\n\x11Kind_SelfPosition\x10\x04\x12\x13\n\x0fKind_Symbol2525\x10\x05\x12\x10\n\x0cKind_SpotMap\x10\x06\x12\x13\n\x0fKind_CustomIcon\x10\x07\x12\x12\n\x0eKind_GoToPoint\x10\x08\x12\x15\n\x11Kind_InitialPoint\x10\t\x12\x15\n\x11Kind_ContactPoint\x10\n\x12\x18\n\x14Kind_ObservationPost\x10\x0b\x12\x14\n\x10Kind_ImageMarker\x10\x0c\"\xe0\x01\n\x0fRangeAndBearing\x12\x30\n\x06\x61nchor\x18\x01 \x01(\x0b\x32 .meshtastic.protobuf.CotGeoPoint\x12\x12\n\nanchor_uid\x18\x02 \x01(Line truncated
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/atak.proto\x12\x13meshtastic.protobuf\"\xa5\x02\n\tTAKPacket\x12\x15\n\ris_compressed\x18\x01 \x01(\x08\x12-\n\x07\x63ontact\x18\x02 \x01(\x0b\x32\x1c.meshtastic.protobuf.Contact\x12)\n\x05group\x18\x03 \x01(\x0b\x32\x1a.meshtastic.protobuf.Group\x12+\n\x06status\x18\x04 \x01(\x0b\x32\x1b.meshtastic.protobuf.Status\x12\'\n\x03pli\x18\x05 \x01(\x0b\x32\x18.meshtastic.protobuf.PLIH\x00\x12,\n\x04\x63hat\x18\x06 \x01(\x0b\x32\x1c.meshtastic.protobuf.GeoChatH\x00\x12\x10\n\x06\x64\x65tail\x18\x07 \x01(\x0cH\x00\x42\x11\n\x0fpayload_variant\"\xfd\x02\n\x07GeoChat\x12\x0f\n\x07message\x18\x01 \x01(\t\x12\x0f\n\x02to\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x18\n\x0bto_callsign\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x17\n\x0freceipt_for_uid\x18\x04 \x01(\t\x12>\n\x0creceipt_type\x18\x05 \x01(\x0e\x32(.meshtastic.protobuf.GeoChat.ReceiptType\x12\x11\n\x04lang\x18\x06 \x01(\tH\x02\x88\x01\x01\x12\x14\n\x07room_id\x18\x07 \x01(\tH\x03\x88\x01\x01\x12\x1d\n\x10voice_profile_id\x18\x08 \x01(\tH\x04\x88\x01\x01\"T\n\x0bReceiptType\x12\x14\n\x10ReceiptType_None\x10\x00\x12\x19\n\x15ReceiptType_Delivered\x10\x01\x12\x14\n\x10ReceiptType_Read\x10\x02\x42\x05\n\x03_toB\x0e\n\x0c_to_callsignB\x07\n\x05_langB\n\n\x08_room_idB\x13\n\x11_voice_profile_id\"_\n\x05Group\x12-\n\x04role\x18\x01 \x01(\x0e\x32\x1f.meshtastic.protobuf.MemberRole\x12\'\n\x04team\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\"\x19\n\x06Status\x12\x0f\n\x07\x62\x61ttery\x18\x01 \x01(\r\"4\n\x07\x43ontact\x12\x10\n\x08\x63\x61llsign\x18\x01 \x01(\t\x12\x17\n\x0f\x64\x65vice_callsign\x18\x02 \x01(\t\"_\n\x03PLI\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\r\n\x05speed\x18\x04 \x01(\r\x12\x0e\n\x06\x63ourse\x18\x05 \x01(\r\"\xb0\x01\n\rAircraftTrack\x12\x0c\n\x04icao\x18\x01 \x01(\t\x12\x14\n\x0cregistration\x18\x02 \x01(\t\x12\x0e\n\x06\x66light\x18\x03 \x01(\t\x12\x15\n\raircraft_type\x18\x04 \x01(\t\x12\x0e\n\x06squawk\x18\x05 \x01(\r\x12\x10\n\x08\x63\x61tegory\x18\x06 \x01(\t\x12\x10\n\x08rssi_x10\x18\x07 \x01(\x11\x12\x0b\n\x03gps\x18\x08 \x01(\x08\x12\x13\n\x0b\x63ot_host_id\x18\t \x01(\t\"7\n\x0b\x43otGeoPoint\x12\x13\n\x0blat_delta_i\x18\x01 \x01(\x11\x12\x13\n\x0blon_delta_i\x18\x02 \x01(\x11\"\xf8\x06\n\nDrawnShape\x12\x32\n\x04kind\x18\x01 \x01(\x0e\x32$.meshtastic.protobuf.DrawnShape.Kind\x12\x38\n\x05style\x18\x02 \x01(\x0e\x32).meshtastic.protobuf.DrawnShape.StyleMode\x12\x10\n\x08major_cm\x18\x03 \x01(\r\x12\x10\n\x08minor_cm\x18\x04 \x01(\r\x12\x11\n\tangle_deg\x18\x05 \x01(\r\x12/\n\x0cstroke_color\x18\x06 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x13\n\x0bstroke_argb\x18\x07 \x01(\x07\x12\x19\n\x11stroke_weight_x10\x18\x08 \x01(\r\x12-\n\nfill_color\x18\t \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x11\n\tfill_argb\x18\n \x01(\x07\x12\x11\n\tlabels_on\x18\x0b \x01(\x08\x12\x32\n\x08vertices\x18\x0c \x03(\x0b\x32 .meshtastic.protobuf.CotGeoPoint\x12\x11\n\ttruncated\x18\r \x01(\x08\x12\x1c\n\x14\x62ullseye_distance_dm\x18\x0e \x01(\r\x12\x1c\n\x14\x62ullseye_bearing_ref\x18\x0f \x01(\r\x12\x16\n\x0e\x62ullseye_flags\x18\x10 \x01(\r\x12\x18\n\x10\x62ullseye_uid_ref\x18\x11 \x01(\t\"\xe2\x01\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\x0f\n\x0bKind_Circle\x10\x01\x12\x12\n\x0eKind_Rectangle\x10\x02\x12\x11\n\rKind_Freeform\x10\x03\x12\x15\n\x11Kind_Telestration\x10\x04\x12\x10\n\x0cKind_Polygon\x10\x05\x12\x16\n\x12Kind_RangingCircle\x10\x06\x12\x11\n\rKind_Bullseye\x10\x07\x12\x10\n\x0cKind_Ellipse\x10\x08\x12\x12\n\x0eKind_Vehicle2D\x10\t\x12\x12\n\x0eKind_Vehicle3D\x10\n\"u\n\tStyleMode\x12\x19\n\x15StyleMode_Unspecified\x10\x00\x12\x18\n\x14StyleMode_StrokeOnly\x10\x01\x12\x16\n\x12StyleMode_FillOnly\x10\x02\x12\x1b\n\x17StyleMode_StrokeAndFill\x10\x03\"\xf7\x03\n\x06Marker\x12.\n\x04kind\x18\x01 \x01(\x0e\x32 .meshtastic.protobuf.Marker.Kind\x12(\n\x05\x63olor\x18\x02 \x01(\x0e\x32\x19.meshtastic.protobuf.Team\x12\x12\n\ncolor_argb\x18\x03 \x01(\x07\x12\x11\n\treadiness\x18\x04 \x01(\x08\x12\x12\n\nparent_uid\x18\x05 \x01(\t\x12\x13\n\x0bparent_type\x18\x06 \x01(\t\x12\x17\n\x0fparent_callsign\x18\x07 \x01(\t\x12\x0f\n\x07iconset\x18\x08 \x01(\t\"\x98\x02\n\x04Kind\x12\x14\n\x10Kind_Unspecified\x10\x00\x12\r\n\tKind_Spot\x10\x01\x12\x11\n\rKind_Waypoint\x10\x02\x12\x13\n\x0fKind_Checkpoint\x10\x03\x12\x15\n\x11Kind_SelfPosition\x10\x04\x12\x13\n\x0fKind_Symbol2525\x10\x05\x12\x10\n\x0cKind_SpotMap\x10\x06\x12\x13\n\x0fKind_CustomIcon\x10\x07\x12\x12\n\x0eKind_GoToPoint\x10\x08\x12\x15\n\x11Kind_InitialPoint\x10\t\x12\x15\n\x11Kind_ContactPoint\x10\n\x12\x18\n\x14Kind_ObservationPost\x10\x0b\x12\x14\n\x10Kind_ImageMarker\x10\x0c\"\xe0\x01\n\x0fRangeAndBearing\x12\x30\n\x06\x61nchor\x18\x01 \x01(\x0b\x32 .meshtastic.protobuf.CotGeoPoint\x12\x12\n\nanchor_uid\x18\x02 \x01(\t\x12\x10\n\x08range_cm\x18\x03 \x01(\r\x12\x14\n\x0c\x62\x65\x61ring_cdeg\x18\x04 \Line truncated
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.atak_pb2', globals())
|
||||
@@ -22,136 +21,84 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nATAKProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_TEAM.values_by_name["Unspecifed_Color"]._options = None
|
||||
_TEAM.values_by_name["Unspecifed_Color"]._serialized_options = b'\312\363\030\020:\016Default (Cyan)'
|
||||
_TEAM.values_by_name["White"]._options = None
|
||||
_TEAM.values_by_name["White"]._serialized_options = b'\312\363\030\007:\005White'
|
||||
_TEAM.values_by_name["Yellow"]._options = None
|
||||
_TEAM.values_by_name["Yellow"]._serialized_options = b'\312\363\030\010:\006Yellow'
|
||||
_TEAM.values_by_name["Orange"]._options = None
|
||||
_TEAM.values_by_name["Orange"]._serialized_options = b'\312\363\030\010:\006Orange'
|
||||
_TEAM.values_by_name["Magenta"]._options = None
|
||||
_TEAM.values_by_name["Magenta"]._serialized_options = b'\312\363\030\t:\007Magenta'
|
||||
_TEAM.values_by_name["Red"]._options = None
|
||||
_TEAM.values_by_name["Red"]._serialized_options = b'\312\363\030\005:\003Red'
|
||||
_TEAM.values_by_name["Maroon"]._options = None
|
||||
_TEAM.values_by_name["Maroon"]._serialized_options = b'\312\363\030\010:\006Maroon'
|
||||
_TEAM.values_by_name["Purple"]._options = None
|
||||
_TEAM.values_by_name["Purple"]._serialized_options = b'\312\363\030\010:\006Purple'
|
||||
_TEAM.values_by_name["Dark_Blue"]._options = None
|
||||
_TEAM.values_by_name["Dark_Blue"]._serialized_options = b'\312\363\030\013:\tDark Blue'
|
||||
_TEAM.values_by_name["Blue"]._options = None
|
||||
_TEAM.values_by_name["Blue"]._serialized_options = b'\312\363\030\006:\004Blue'
|
||||
_TEAM.values_by_name["Cyan"]._options = None
|
||||
_TEAM.values_by_name["Cyan"]._serialized_options = b'\312\363\030\006:\004Cyan'
|
||||
_TEAM.values_by_name["Teal"]._options = None
|
||||
_TEAM.values_by_name["Teal"]._serialized_options = b'\312\363\030\006:\004Teal'
|
||||
_TEAM.values_by_name["Green"]._options = None
|
||||
_TEAM.values_by_name["Green"]._serialized_options = b'\312\363\030\007:\005Green'
|
||||
_TEAM.values_by_name["Dark_Green"]._options = None
|
||||
_TEAM.values_by_name["Dark_Green"]._serialized_options = b'\312\363\030\014:\nDark Green'
|
||||
_TEAM.values_by_name["Brown"]._options = None
|
||||
_TEAM.values_by_name["Brown"]._serialized_options = b'\312\363\030\007:\005Brown'
|
||||
_MEMBERROLE.values_by_name["Unspecifed"]._options = None
|
||||
_MEMBERROLE.values_by_name["Unspecifed"]._serialized_options = b'\312\363\030\027:\025Default (Team Member)'
|
||||
_MEMBERROLE.values_by_name["TeamMember"]._options = None
|
||||
_MEMBERROLE.values_by_name["TeamMember"]._serialized_options = b'\312\363\030\r:\013Team Member'
|
||||
_MEMBERROLE.values_by_name["TeamLead"]._options = None
|
||||
_MEMBERROLE.values_by_name["TeamLead"]._serialized_options = b'\312\363\030\013:\tTeam Lead'
|
||||
_MEMBERROLE.values_by_name["HQ"]._options = None
|
||||
_MEMBERROLE.values_by_name["HQ"]._serialized_options = b'\312\363\030\004:\002HQ'
|
||||
_MEMBERROLE.values_by_name["Sniper"]._options = None
|
||||
_MEMBERROLE.values_by_name["Sniper"]._serialized_options = b'\312\363\030\010:\006Sniper'
|
||||
_MEMBERROLE.values_by_name["Medic"]._options = None
|
||||
_MEMBERROLE.values_by_name["Medic"]._serialized_options = b'\312\363\030\007:\005Medic'
|
||||
_MEMBERROLE.values_by_name["ForwardObserver"]._options = None
|
||||
_MEMBERROLE.values_by_name["ForwardObserver"]._serialized_options = b'\312\363\030\022:\020Forward Observer'
|
||||
_MEMBERROLE.values_by_name["RTO"]._options = None
|
||||
_MEMBERROLE.values_by_name["RTO"]._serialized_options = b'\312\363\030\005:\003RTO'
|
||||
_MEMBERROLE.values_by_name["K9"]._options = None
|
||||
_MEMBERROLE.values_by_name["K9"]._serialized_options = b'\312\363\030\004:\002K9'
|
||||
_TAKTALKROOMDATA.fields_by_name['sender_callsign']._options = None
|
||||
_TAKTALKROOMDATA.fields_by_name['sender_callsign']._serialized_options = b'\030\001'
|
||||
_TEAM._serialized_start=7941
|
||||
_TEAM._serialized_end=8347
|
||||
_MEMBERROLE._serialized_start=8350
|
||||
_MEMBERROLE._serialized_end=8624
|
||||
_COTHOW._serialized_start=8627
|
||||
_COTHOW._serialized_end=8777
|
||||
_COTTYPE._serialized_start=8780
|
||||
_COTTYPE._serialized_end=11727
|
||||
_GEOPOINTSOURCE._serialized_start=11729
|
||||
_GEOPOINTSOURCE._serialized_end=11854
|
||||
_TAKPACKET._serialized_start=98
|
||||
_TAKPACKET._serialized_end=391
|
||||
_GEOCHAT._serialized_start=394
|
||||
_GEOCHAT._serialized_end=775
|
||||
_GEOCHAT_RECEIPTTYPE._serialized_start=626
|
||||
_GEOCHAT_RECEIPTTYPE._serialized_end=710
|
||||
_GROUP._serialized_start=777
|
||||
_GROUP._serialized_end=872
|
||||
_STATUS._serialized_start=874
|
||||
_STATUS._serialized_end=899
|
||||
_CONTACT._serialized_start=901
|
||||
_CONTACT._serialized_end=953
|
||||
_PLI._serialized_start=955
|
||||
_PLI._serialized_end=1050
|
||||
_AIRCRAFTTRACK._serialized_start=1053
|
||||
_AIRCRAFTTRACK._serialized_end=1229
|
||||
_COTGEOPOINT._serialized_start=1231
|
||||
_COTGEOPOINT._serialized_end=1286
|
||||
_DRAWNSHAPE._serialized_start=1289
|
||||
_DRAWNSHAPE._serialized_end=2185
|
||||
_DRAWNSHAPE_KIND._serialized_start=1834
|
||||
_DRAWNSHAPE_KIND._serialized_end=2060
|
||||
_DRAWNSHAPE_STYLEMODE._serialized_start=2062
|
||||
_DRAWNSHAPE_STYLEMODE._serialized_end=2179
|
||||
_MARKER._serialized_start=2188
|
||||
_MARKER._serialized_end=2691
|
||||
_MARKER_KIND._serialized_start=2411
|
||||
_MARKER_KIND._serialized_end=2691
|
||||
_RANGEANDBEARING._serialized_start=2694
|
||||
_RANGEANDBEARING._serialized_end=2918
|
||||
_ROUTE._serialized_start=2921
|
||||
_ROUTE._serialized_end=3473
|
||||
_ROUTE_LINK._serialized_start=3148
|
||||
_ROUTE_LINK._serialized_end=3253
|
||||
_ROUTE_METHOD._serialized_start=3256
|
||||
_ROUTE_METHOD._serialized_end=3391
|
||||
_ROUTE_DIRECTION._serialized_start=3393
|
||||
_ROUTE_DIRECTION._serialized_end=3473
|
||||
_CASEVACREPORT._serialized_start=3476
|
||||
_CASEVACREPORT._serialized_end=4878
|
||||
_CASEVACREPORT_PRECEDENCE._serialized_start=4400
|
||||
_CASEVACREPORT_PRECEDENCE._serialized_end=4571
|
||||
_CASEVACREPORT_HLZMARKING._serialized_start=4574
|
||||
_CASEVACREPORT_HLZMARKING._serialized_end=4729
|
||||
_CASEVACREPORT_SECURITY._serialized_start=4732
|
||||
_CASEVACREPORT_SECURITY._serialized_end=4878
|
||||
_ZMISTENTRY._serialized_start=4880
|
||||
_ZMISTENTRY._serialized_end=4962
|
||||
_EMERGENCYALERT._serialized_start=4965
|
||||
_EMERGENCYALERT._serialized_end=5243
|
||||
_EMERGENCYALERT_TYPE._serialized_start=5093
|
||||
_EMERGENCYALERT_TYPE._serialized_end=5243
|
||||
_TASKREQUEST._serialized_start=5246
|
||||
_TASKREQUEST._serialized_end=5718
|
||||
_TASKREQUEST_PRIORITY._serialized_start=5454
|
||||
_TASKREQUEST_PRIORITY._serialized_end=5571
|
||||
_TASKREQUEST_STATUS._serialized_start=5574
|
||||
_TASKREQUEST_STATUS._serialized_end=5718
|
||||
_TAKENVIRONMENT._serialized_start=5720
|
||||
_TAKENVIRONMENT._serialized_end=5816
|
||||
_SENSORFOV._serialized_start=5819
|
||||
_SENSORFOV._serialized_end=6225
|
||||
_SENSORFOV_SENSORTYPE._serialized_start=6043
|
||||
_SENSORFOV_SENSORTYPE._serialized_end=6213
|
||||
_TAKTALKMESSAGE._serialized_start=6227
|
||||
_TAKTALKMESSAGE._serialized_end=6312
|
||||
_TAKTALKROOMDATA._serialized_start=6314
|
||||
_TAKTALKROOMDATA._serialized_end=6418
|
||||
_MARTI._serialized_start=6420
|
||||
_MARTI._serialized_end=6450
|
||||
_TAKPACKETV2._serialized_start=6453
|
||||
_TAKPACKETV2._serialized_end=7938
|
||||
_TEAM._serialized_start=7812
|
||||
_TEAM._serialized_end=8004
|
||||
_MEMBERROLE._serialized_start=8006
|
||||
_MEMBERROLE._serialized_end=8133
|
||||
_COTHOW._serialized_start=8136
|
||||
_COTHOW._serialized_end=8286
|
||||
_COTTYPE._serialized_start=8289
|
||||
_COTTYPE._serialized_end=11236
|
||||
_GEOPOINTSOURCE._serialized_start=11238
|
||||
_GEOPOINTSOURCE._serialized_end=11363
|
||||
_TAKPACKET._serialized_start=56
|
||||
_TAKPACKET._serialized_end=349
|
||||
_GEOCHAT._serialized_start=352
|
||||
_GEOCHAT._serialized_end=733
|
||||
_GEOCHAT_RECEIPTTYPE._serialized_start=584
|
||||
_GEOCHAT_RECEIPTTYPE._serialized_end=668
|
||||
_GROUP._serialized_start=735
|
||||
_GROUP._serialized_end=830
|
||||
_STATUS._serialized_start=832
|
||||
_STATUS._serialized_end=857
|
||||
_CONTACT._serialized_start=859
|
||||
_CONTACT._serialized_end=911
|
||||
_PLI._serialized_start=913
|
||||
_PLI._serialized_end=1008
|
||||
_AIRCRAFTTRACK._serialized_start=1011
|
||||
_AIRCRAFTTRACK._serialized_end=1187
|
||||
_COTGEOPOINT._serialized_start=1189
|
||||
_COTGEOPOINT._serialized_end=1244
|
||||
_DRAWNSHAPE._serialized_start=1247
|
||||
_DRAWNSHAPE._serialized_end=2135
|
||||
_DRAWNSHAPE_KIND._serialized_start=1790
|
||||
_DRAWNSHAPE_KIND._serialized_end=2016
|
||||
_DRAWNSHAPE_STYLEMODE._serialized_start=2018
|
||||
_DRAWNSHAPE_STYLEMODE._serialized_end=2135
|
||||
_MARKER._serialized_start=2138
|
||||
_MARKER._serialized_end=2641
|
||||
_MARKER_KIND._serialized_start=2361
|
||||
_MARKER_KIND._serialized_end=2641
|
||||
_RANGEANDBEARING._serialized_start=2644
|
||||
_RANGEANDBEARING._serialized_end=2868
|
||||
_ROUTE._serialized_start=2871
|
||||
_ROUTE._serialized_end=3423
|
||||
_ROUTE_LINK._serialized_start=3098
|
||||
_ROUTE_LINK._serialized_end=3203
|
||||
_ROUTE_METHOD._serialized_start=3206
|
||||
_ROUTE_METHOD._serialized_end=3341
|
||||
_ROUTE_DIRECTION._serialized_start=3343
|
||||
_ROUTE_DIRECTION._serialized_end=3423
|
||||
_CASEVACREPORT._serialized_start=3426
|
||||
_CASEVACREPORT._serialized_end=4828
|
||||
_CASEVACREPORT_PRECEDENCE._serialized_start=4350
|
||||
_CASEVACREPORT_PRECEDENCE._serialized_end=4521
|
||||
_CASEVACREPORT_HLZMARKING._serialized_start=4524
|
||||
_CASEVACREPORT_HLZMARKING._serialized_end=4679
|
||||
_CASEVACREPORT_SECURITY._serialized_start=4682
|
||||
_CASEVACREPORT_SECURITY._serialized_end=4828
|
||||
_ZMISTENTRY._serialized_start=4830
|
||||
_ZMISTENTRY._serialized_end=4912
|
||||
_EMERGENCYALERT._serialized_start=4915
|
||||
_EMERGENCYALERT._serialized_end=5193
|
||||
_EMERGENCYALERT_TYPE._serialized_start=5043
|
||||
_EMERGENCYALERT_TYPE._serialized_end=5193
|
||||
_TASKREQUEST._serialized_start=5196
|
||||
_TASKREQUEST._serialized_end=5668
|
||||
_TASKREQUEST_PRIORITY._serialized_start=5404
|
||||
_TASKREQUEST_PRIORITY._serialized_end=5521
|
||||
_TASKREQUEST_STATUS._serialized_start=5524
|
||||
_TASKREQUEST_STATUS._serialized_end=5668
|
||||
_TAKENVIRONMENT._serialized_start=5670
|
||||
_TAKENVIRONMENT._serialized_end=5766
|
||||
_SENSORFOV._serialized_start=5769
|
||||
_SENSORFOV._serialized_end=6175
|
||||
_SENSORFOV_SENSORTYPE._serialized_start=5993
|
||||
_SENSORFOV_SENSORTYPE._serialized_end=6163
|
||||
_TAKTALKMESSAGE._serialized_start=6177
|
||||
_TAKTALKMESSAGE._serialized_end=6262
|
||||
_TAKTALKROOMDATA._serialized_start=6264
|
||||
_TAKTALKROOMDATA._serialized_end=6364
|
||||
_TAKPACKETV2._serialized_start=6367
|
||||
_TAKPACKETV2._serialized_end=7809
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,4 +1,3 @@
|
||||
from meshtastic.protobuf import field_metadata_pb2 as _field_metadata_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
|
||||
@@ -302,7 +301,7 @@ class CotGeoPoint(_message.Message):
|
||||
def __init__(self, lat_delta_i: _Optional[int] = ..., lon_delta_i: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class DrawnShape(_message.Message):
|
||||
__slots__ = ["angle_deg", "bullseye_bearing_ref", "bullseye_distance_dm", "bullseye_flags", "bullseye_uid_ref", "fill_argb", "fill_color", "kind", "labels_on", "major_cm", "minor_cm", "stroke_argb", "stroke_color", "stroke_weight_x10", "style", "truncated", "vertex_lat_deltas", "vertex_lon_deltas"]
|
||||
__slots__ = ["angle_deg", "bullseye_bearing_ref", "bullseye_distance_dm", "bullseye_flags", "bullseye_uid_ref", "fill_argb", "fill_color", "kind", "labels_on", "major_cm", "minor_cm", "stroke_argb", "stroke_color", "stroke_weight_x10", "style", "truncated", "vertices"]
|
||||
class Kind(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class StyleMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
@@ -338,8 +337,7 @@ class DrawnShape(_message.Message):
|
||||
StyleMode_StrokeOnly: DrawnShape.StyleMode
|
||||
StyleMode_Unspecified: DrawnShape.StyleMode
|
||||
TRUNCATED_FIELD_NUMBER: _ClassVar[int]
|
||||
VERTEX_LAT_DELTAS_FIELD_NUMBER: _ClassVar[int]
|
||||
VERTEX_LON_DELTAS_FIELD_NUMBER: _ClassVar[int]
|
||||
VERTICES_FIELD_NUMBER: _ClassVar[int]
|
||||
angle_deg: int
|
||||
bullseye_bearing_ref: int
|
||||
bullseye_distance_dm: int
|
||||
@@ -356,9 +354,8 @@ class DrawnShape(_message.Message):
|
||||
stroke_weight_x10: int
|
||||
style: DrawnShape.StyleMode
|
||||
truncated: bool
|
||||
vertex_lat_deltas: _containers.RepeatedScalarFieldContainer[int]
|
||||
vertex_lon_deltas: _containers.RepeatedScalarFieldContainer[int]
|
||||
def __init__(self, kind: _Optional[_Union[DrawnShape.Kind, str]] = ..., style: _Optional[_Union[DrawnShape.StyleMode, str]] = ..., major_cm: _Optional[int] = ..., minor_cm: _Optional[int] = ..., angle_deg: _Optional[int] = ..., stroke_color: _Optional[_Union[Team, str]] = ..., stroke_argb: _Optional[int] = ..., stroke_weight_x10: _Optional[int] = ..., fill_color: _Optional[_Union[Team, str]] = ..., fill_argb: _Optional[int] = ..., labels_on: bool = ..., vertex_lat_deltas: _Optional[_Iterable[int]] = ..., vertex_lon_deltas: _Optional[_Iterable[int]] = ..., truncated: bool = ..., bullseye_distance_dm: _Optional[int] = ..., bullseye_bearing_ref: _Optional[int] = ..., bullseye_flags: _Optional[int] = ..., bullseye_uid_ref: _Optional[str] = ...) -> None: ...
|
||||
vertices: _containers.RepeatedCompositeFieldContainer[CotGeoPoint]
|
||||
def __init__(self, kind: _Optional[_Union[DrawnShape.Kind, str]] = ..., style: _Optional[_Union[DrawnShape.StyleMode, str]] = ..., major_cm: _Optional[int] = ..., minor_cm: _Optional[int] = ..., angle_deg: _Optional[int] = ..., stroke_color: _Optional[_Union[Team, str]] = ..., stroke_argb: _Optional[int] = ..., stroke_weight_x10: _Optional[int] = ..., fill_color: _Optional[_Union[Team, str]] = ..., fill_argb: _Optional[int] = ..., labels_on: bool = ..., vertices: _Optional[_Iterable[_Union[CotGeoPoint, _Mapping]]] = ..., truncated: bool = ..., bullseye_distance_dm: _Optional[int] = ..., bullseye_bearing_ref: _Optional[int] = ..., bullseye_flags: _Optional[int] = ..., bullseye_uid_ref: _Optional[str] = ...) -> None: ...
|
||||
|
||||
class EmergencyAlert(_message.Message):
|
||||
__slots__ = ["authoring_uid", "cancel_reference_uid", "type"]
|
||||
@@ -447,12 +444,6 @@ class Marker(_message.Message):
|
||||
readiness: bool
|
||||
def __init__(self, kind: _Optional[_Union[Marker.Kind, str]] = ..., color: _Optional[_Union[Team, str]] = ..., color_argb: _Optional[int] = ..., readiness: bool = ..., parent_uid: _Optional[str] = ..., parent_type: _Optional[str] = ..., parent_callsign: _Optional[str] = ..., iconset: _Optional[str] = ...) -> None: ...
|
||||
|
||||
class Marti(_message.Message):
|
||||
__slots__ = ["dest_callsign"]
|
||||
DEST_CALLSIGN_FIELD_NUMBER: _ClassVar[int]
|
||||
dest_callsign: _containers.RepeatedScalarFieldContainer[str]
|
||||
def __init__(self, dest_callsign: _Optional[_Iterable[str]] = ...) -> None: ...
|
||||
|
||||
class PLI(_message.Message):
|
||||
__slots__ = ["altitude", "course", "latitude_i", "longitude_i", "speed"]
|
||||
ALTITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -589,7 +580,7 @@ class TAKPacket(_message.Message):
|
||||
def __init__(self, is_compressed: bool = ..., contact: _Optional[_Union[Contact, _Mapping]] = ..., group: _Optional[_Union[Group, _Mapping]] = ..., status: _Optional[_Union[Status, _Mapping]] = ..., pli: _Optional[_Union[PLI, _Mapping]] = ..., chat: _Optional[_Union[GeoChat, _Mapping]] = ..., detail: _Optional[bytes] = ...) -> None: ...
|
||||
|
||||
class TAKPacketV2(_message.Message):
|
||||
__slots__ = ["aircraft", "alt_src", "altitude", "battery", "callsign", "casevac", "chat", "cot_type_id", "cot_type_str", "course", "device_callsign", "emergency", "endpoint", "environment", "geo_src", "how", "latitude_i", "longitude_i", "marker", "marti", "phone", "rab", "raw_detail", "remarks", "role", "route", "sensor_fov", "shape", "speed", "stale_seconds", "tak_device", "tak_os", "tak_platform", "tak_version", "taktalk", "taktalk_room", "task", "team", "uid"]
|
||||
__slots__ = ["aircraft", "alt_src", "altitude", "battery", "callsign", "casevac", "chat", "cot_type_id", "cot_type_str", "course", "device_callsign", "emergency", "endpoint", "environment", "geo_src", "how", "latitude_i", "longitude_i", "marker", "phone", "pli", "rab", "raw_detail", "remarks", "role", "route", "sensor_fov", "shape", "speed", "stale_seconds", "tak_device", "tak_os", "tak_platform", "tak_version", "taktalk", "taktalk_room", "task", "team", "uid"]
|
||||
AIRCRAFT_FIELD_NUMBER: _ClassVar[int]
|
||||
ALTITUDE_FIELD_NUMBER: _ClassVar[int]
|
||||
ALT_SRC_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -609,8 +600,8 @@ class TAKPacketV2(_message.Message):
|
||||
LATITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
MARKER_FIELD_NUMBER: _ClassVar[int]
|
||||
MARTI_FIELD_NUMBER: _ClassVar[int]
|
||||
PHONE_FIELD_NUMBER: _ClassVar[int]
|
||||
PLI_FIELD_NUMBER: _ClassVar[int]
|
||||
RAB_FIELD_NUMBER: _ClassVar[int]
|
||||
RAW_DETAIL_FIELD_NUMBER: _ClassVar[int]
|
||||
REMARKS_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -648,8 +639,8 @@ class TAKPacketV2(_message.Message):
|
||||
latitude_i: int
|
||||
longitude_i: int
|
||||
marker: Marker
|
||||
marti: Marti
|
||||
phone: str
|
||||
pli: bool
|
||||
rab: RangeAndBearing
|
||||
raw_detail: bytes
|
||||
remarks: str
|
||||
@@ -668,7 +659,7 @@ class TAKPacketV2(_message.Message):
|
||||
task: TaskRequest
|
||||
team: Team
|
||||
uid: str
|
||||
def __init__(self, cot_type_id: _Optional[_Union[CotType, str]] = ..., how: _Optional[_Union[CotHow, str]] = ..., callsign: _Optional[str] = ..., team: _Optional[_Union[Team, str]] = ..., role: _Optional[_Union[MemberRole, str]] = ..., latitude_i: _Optional[int] = ..., longitude_i: _Optional[int] = ..., altitude: _Optional[int] = ..., speed: _Optional[int] = ..., course: _Optional[int] = ..., battery: _Optional[int] = ..., geo_src: _Optional[_Union[GeoPointSource, str]] = ..., alt_src: _Optional[_Union[GeoPointSource, str]] = ..., uid: _Optional[str] = ..., device_callsign: _Optional[str] = ..., stale_seconds: _Optional[int] = ..., tak_version: _Optional[str] = ..., tak_device: _Optional[str] = ..., tak_platform: _Optional[str] = ..., tak_os: _Optional[str] = ..., endpoint: _Optional[str] = ..., phone: _Optional[str] = ..., cot_type_str: _Optional[str] = ..., remarks: _Optional[str] = ..., environment: _Optional[_Union[TAKEnvironment, _Mapping]] = ..., sensor_fov: _Optional[_Union[SensorFov, _Mapping]] = ..., marti: _Optional[_Union[Marti, _Mapping]] = ..., chat: _Optional[_Union[GeoChat, _Mapping]] = ..., aircraft: _Optional[_Union[AircraftTrack, _Mapping]] = ..., raw_detail: _Optional[bytes] = ..., shape: _Optional[_Union[DrawnShape, _Mapping]] = ..., marker: _Optional[_Union[Marker, _Mapping]] = ..., rab: _Optional[_Union[RangeAndBearing, _Mapping]] = ..., route: _Optional[_Union[Route, _Mapping]] = ..., casevac: _Optional[_Union[CasevacReport, _Mapping]] = ..., emergency: _Optional[_Union[EmergencyAlert, _Mapping]] = ..., task: _Optional[_Union[TaskRequest, _Mapping]] = ..., taktalk: _Optional[_Union[TakTalkMessage, _Mapping]] = ..., taktalk_room: _Optional[_Union[TakTalkRoomData, _Mapping]] = ...) -> None: ...
|
||||
def __init__(self, cot_type_id: _Optional[_Union[CotType, str]] = ..., how: _Optional[_Union[CotHow, str]] = ..., callsign: _Optional[str] = ..., team: _Optional[_Union[Team, str]] = ..., role: _Optional[_Union[MemberRole, str]] = ..., latitude_i: _Optional[int] = ..., longitude_i: _Optional[int] = ..., altitude: _Optional[int] = ..., speed: _Optional[int] = ..., course: _Optional[int] = ..., battery: _Optional[int] = ..., geo_src: _Optional[_Union[GeoPointSource, str]] = ..., alt_src: _Optional[_Union[GeoPointSource, str]] = ..., uid: _Optional[str] = ..., device_callsign: _Optional[str] = ..., stale_seconds: _Optional[int] = ..., tak_version: _Optional[str] = ..., tak_device: _Optional[str] = ..., tak_platform: _Optional[str] = ..., tak_os: _Optional[str] = ..., endpoint: _Optional[str] = ..., phone: _Optional[str] = ..., cot_type_str: _Optional[str] = ..., remarks: _Optional[str] = ..., environment: _Optional[_Union[TAKEnvironment, _Mapping]] = ..., sensor_fov: _Optional[_Union[SensorFov, _Mapping]] = ..., pli: bool = ..., chat: _Optional[_Union[GeoChat, _Mapping]] = ..., aircraft: _Optional[_Union[AircraftTrack, _Mapping]] = ..., raw_detail: _Optional[bytes] = ..., shape: _Optional[_Union[DrawnShape, _Mapping]] = ..., marker: _Optional[_Union[Marker, _Mapping]] = ..., rab: _Optional[_Union[RangeAndBearing, _Mapping]] = ..., route: _Optional[_Union[Route, _Mapping]] = ..., casevac: _Optional[_Union[CasevacReport, _Mapping]] = ..., emergency: _Optional[_Union[EmergencyAlert, _Mapping]] = ..., task: _Optional[_Union[TaskRequest, _Mapping]] = ..., taktalk: _Optional[_Union[TakTalkMessage, _Mapping]] = ..., taktalk_room: _Optional[_Union[TakTalkRoomData, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class TakTalkMessage(_message.Message):
|
||||
__slots__ = ["chatroom_id", "from_voice", "lang", "text"]
|
||||
|
||||
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!meshtastic/protobuf/channel.proto\x12\x13meshtastic.protobuf\"\xd3\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\x12\x10\n\x08use_aead\x18\x08 \x01(\x08\">\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')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.channel_pb2', globals())
|
||||
@@ -24,11 +24,11 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
_CHANNELSETTINGS.fields_by_name['channel_num']._options = None
|
||||
_CHANNELSETTINGS.fields_by_name['channel_num']._serialized_options = b'\030\001'
|
||||
_CHANNELSETTINGS._serialized_start=59
|
||||
_CHANNELSETTINGS._serialized_end=270
|
||||
_MODULESETTINGS._serialized_start=272
|
||||
_MODULESETTINGS._serialized_end=334
|
||||
_CHANNEL._serialized_start=337
|
||||
_CHANNEL._serialized_end=516
|
||||
_CHANNEL_ROLE._serialized_start=468
|
||||
_CHANNEL_ROLE._serialized_end=516
|
||||
_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)
|
||||
@@ -21,7 +21,7 @@ class Channel(_message.Message):
|
||||
def __init__(self, index: _Optional[int] = ..., settings: _Optional[_Union[ChannelSettings, _Mapping]] = ..., role: _Optional[_Union[Channel.Role, str]] = ...) -> None: ...
|
||||
|
||||
class ChannelSettings(_message.Message):
|
||||
__slots__ = ["channel_num", "downlink_enabled", "id", "module_settings", "name", "psk", "uplink_enabled", "use_aead"]
|
||||
__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]
|
||||
@@ -29,7 +29,6 @@ class ChannelSettings(_message.Message):
|
||||
NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
PSK_FIELD_NUMBER: _ClassVar[int]
|
||||
UPLINK_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
USE_AEAD_FIELD_NUMBER: _ClassVar[int]
|
||||
channel_num: int
|
||||
downlink_enabled: bool
|
||||
id: int
|
||||
@@ -37,8 +36,7 @@ class ChannelSettings(_message.Message):
|
||||
name: str
|
||||
psk: bytes
|
||||
uplink_enabled: bool
|
||||
use_aead: 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]] = ..., use_aead: bool = ...) -> None: ...
|
||||
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: ...
|
||||
|
||||
class ModuleSettings(_message.Message):
|
||||
__slots__ = ["is_muted", "position_precision"]
|
||||
|
||||
@@ -15,7 +15,7 @@ from meshtastic.protobuf import localonly_pb2 as meshtastic_dot_protobuf_dot_loc
|
||||
from meshtastic.protobuf import mesh_pb2 as meshtastic_dot_protobuf_dot_mesh__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$meshtastic/protobuf/clientonly.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/localonly.proto\x1a\x1emeshtastic/protobuf/mesh.proto\"\xa0\x04\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\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x08\x88\x01\x01\x12\x18\n\x0bis_licensed\x18\n \x01(\x08H\t\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_messagesB\x12\n\x10_is_unmessagableB\x0e\n\x0c_is_licensedBf\n\x14org.meshtastic.protoB\x10\x43lientOnlyProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.clientonly_pb2', globals())
|
||||
@@ -24,5 +24,5 @@ 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'
|
||||
_DEVICEPROFILE._serialized_start=131
|
||||
_DEVICEPROFILE._serialized_end=675
|
||||
_DEVICEPROFILE._serialized_end=583
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -7,13 +7,11 @@ from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Opti
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class DeviceProfile(_message.Message):
|
||||
__slots__ = ["canned_messages", "channel_url", "config", "fixed_position", "is_licensed", "is_unmessagable", "long_name", "module_config", "ringtone", "short_name"]
|
||||
__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]
|
||||
IS_LICENSED_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_UNMESSAGABLE_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
MODULE_CONFIG_FIELD_NUMBER: _ClassVar[int]
|
||||
RINGTONE_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -22,10 +20,8 @@ class DeviceProfile(_message.Message):
|
||||
channel_url: str
|
||||
config: _localonly_pb2.LocalConfig
|
||||
fixed_position: _mesh_pb2.Position
|
||||
is_licensed: bool
|
||||
is_unmessagable: bool
|
||||
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] = ..., is_unmessagable: bool = ..., is_licensed: bool = ...) -> None: ...
|
||||
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: ...
|
||||
@@ -12,10 +12,9 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from meshtastic.protobuf import device_ui_pb2 as meshtastic_dot_protobuf_dot_device__ui__pb2
|
||||
from meshtastic.protobuf import field_metadata_pb2 as meshtastic_dot_protobuf_dot_field__metadata__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/device_ui.proto\x1a(meshtastic/protobuf/field_metadata.proto\"\x93\x86\x01\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x12\x38\n\tdevice_ui\x18\n \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x1a\x80\x1f\n\x0c\x44\x65viceConfig\x12N\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.RoleB\x11\xca\xf3\x18\r:\x0b\x44\x65vice Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12u\n\x0b\x62utton_gpio\x18\x04 \x01(\rB`\xca\xf3\x18\\:\x0b\x42utton GPIOBMGPIO pin for the user button, can be remapped on boards with multiple buttons\x12\x43\n\x0b\x62uzzer_gpio\x18\x05 \x01(\rB.\xca\xf3\x18*:\x0b\x42uzzer GPIOB\x1bGPIO pin for the PWM buzzer\x12j\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastModeB\x16\xca\xf3\x18\x12:\x10Rebroadcast Mode\x12\x9a\x01\n\x18node_info_broadcast_secs\x18\x07 \x01(\rBx\xca\xf3\x18t\x19\x00\x00\x00\x00\x00 \xac@*\x01s:\x1cNode Info Broadcast IntervalBHHow often node information is sent. Defaults to 3 hours, minimum 1 hour.\x12\x84\x01\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x42`\xca\xf3\x18\\:\x14\x44ouble Tap as ButtonBDTreat double tap on supported accelerometers as a user button press.\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12i\n\x14\x64isable_triple_click\x18\n \x01(\x08\x42K\xca\xf3\x18G:\x14\x44isable Triple ClickB/Disables the user button triple-press shortcut.\x12@\n\x05tzdef\x18\x0b \x01(\tB1\xca\xf3\x18-:\tTime ZoneB POSIX timezone definition string\x12\xc5\x01\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x42\xa4\x01\xca\xf3\x18\x9f\x01:\x15\x44isable LED HeartbeatB\x85\x01Turns off the blinking LED on the device. On most devices this is one of up to 4 LEDs; the charger and GPS LEDs are not controllable.\x12U\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32\x33.meshtastic.protobuf.Config.DeviceConfig.BuzzerModeB\x0b\xca\xf3\x18\x07R\x05\x32.7.0\"\xef\x0b\n\x04Role\x12G\n\x06\x43LIENT\x10\x00\x1a;\xca\xf3\x18\x37:\x06\x43lientB-App connected or standalone messaging device.\x12\\\n\x0b\x43LIENT_MUTE\x10\x01\x1aK\xca\xf3\x18G:\x0b\x43lient MuteB8Device that does not forward packets from other devices.\x12\xae\x01\n\x06ROUTER\x10\x02\x1a\xa1\x01\xca\xf3\x18\x9c\x01:\x06RouterB\x91\x01Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list.\x12(\n\rROUTER_CLIENT\x10\x03\x1a\x15\x08\x01\xca\xf3\x18\x0f:\rRouter Client\x12\xb3\x01\n\x08REPEATER\x10\x04\x1a\xa4\x01\x08\x01\xca\xf3\x18\x9d\x01:\x08RepeaterB\x90\x01\x44\x65precated infrastructure role that creates gaps in the mesh rebroadcast chain. Switch this node to a Router-based role (Router or Router Late).\x12H\n\x07TRACKER\x10\x05\x1a;\xca\xf3\x18\x37:\x07TrackerB,Broadcasts GPS position packets as priority.\x12\x43\n\x06SENSOR\x10\x06\x1a\x37\xca\xf3\x18\x33:\x06SensorB)Broadcasts telemetry packets as priority.\x12X\n\x03TAK\x10\x07\x1aO\xca\xf3\x18K:\x03TAKBDOptimized for ATAK system communication, reduces routine broadcasts.\x12k\n\rCLIENT_HIDDEN\x10\x08\x1aX\xca\xf3\x18T:\rClient HiddenBCDevice that only broadcasts as needed for stealth or power savings.\x12\x85\x01\n\x0eLOST_AND_FOUND\x10\t\x1aq\xca\xf3\x18m:\x0eLost and FoundB[Broadcasts location as message to default channel regularly to assist with device recovery.\x12h\n\x0bTAK_TRACKER\x10\n\x1aW\xca\xf3\x18S:\x0bTAK TrackerBDEnables automatic TAK PLI broadcasts and reduces routine broadcasts.\x12\xbc\x01\n\x0bROUTER_LATE\x10\x0b\x1a\xaa\x01\xca\xf3\x18\xa5\x01:\x0bRouter LateB\x95\x01Infrastructure node that always rebroadcasts packets once but only after all other modes. Visible in Nodes list. Not a good choice for rooftop nodes.\x12\xa7\x01\n\x0b\x43LIENT_BASE\x10\x0c\x1a\x95\x01\xca\xf3\x18\x90\x01:\x0b\x43lient BaseB\x80\x01Rooftop or attic node that rebroadcasts like Router Late for packets from or to favorited nodes, and like Client for all others.\"\xf6\x08\n\x0fRebroadcastMode\x12\x8c\x01\n\x03\x41LL\x10\x00\x1a\x82\x01\xca\xf3\x18~:\x03\x41llBwRebroadcast anLine truncated
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n meshtastic/protobuf/config.proto\x12\x13meshtastic.protobuf\x1a#meshtastic/protobuf/device_ui.proto\"\xeb-\n\x06\x43onfig\x12:\n\x06\x64\x65vice\x18\x01 \x01(\x0b\x32(.meshtastic.protobuf.Config.DeviceConfigH\x00\x12>\n\x08position\x18\x02 \x01(\x0b\x32*.meshtastic.protobuf.Config.PositionConfigH\x00\x12\x38\n\x05power\x18\x03 \x01(\x0b\x32\'.meshtastic.protobuf.Config.PowerConfigH\x00\x12<\n\x07network\x18\x04 \x01(\x0b\x32).meshtastic.protobuf.Config.NetworkConfigH\x00\x12<\n\x07\x64isplay\x18\x05 \x01(\x0b\x32).meshtastic.protobuf.Config.DisplayConfigH\x00\x12\x36\n\x04lora\x18\x06 \x01(\x0b\x32&.meshtastic.protobuf.Config.LoRaConfigH\x00\x12@\n\tbluetooth\x18\x07 \x01(\x0b\x32+.meshtastic.protobuf.Config.BluetoothConfigH\x00\x12>\n\x08security\x18\x08 \x01(\x0b\x32*.meshtastic.protobuf.Config.SecurityConfigH\x00\x12\x42\n\nsessionkey\x18\t \x01(\x0b\x32,.meshtastic.protobuf.Config.SessionkeyConfigH\x00\x12\x38\n\tdevice_ui\x18\n \x01(\x0b\x32#.meshtastic.protobuf.DeviceUIConfigH\x00\x1a\x91\x07\n\x0c\x44\x65viceConfig\x12;\n\x04role\x18\x01 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x1a\n\x0eserial_enabled\x18\x02 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0b\x62utton_gpio\x18\x04 \x01(\r\x12\x13\n\x0b\x62uzzer_gpio\x18\x05 \x01(\r\x12R\n\x10rebroadcast_mode\x18\x06 \x01(\x0e\x32\x38.meshtastic.protobuf.Config.DeviceConfig.RebroadcastMode\x12 \n\x18node_info_broadcast_secs\x18\x07 \x01(\r\x12\"\n\x1a\x64ouble_tap_as_button_press\x18\x08 \x01(\x08\x12\x16\n\nis_managed\x18\t \x01(\x08\x42\x02\x18\x01\x12\x1c\n\x14\x64isable_triple_click\x18\n \x01(\x08\x12\r\n\x05tzdef\x18\x0b \x01(\t\x12\x1e\n\x16led_heartbeat_disabled\x18\x0c \x01(\x08\x12H\n\x0b\x62uzzer_mode\x18\r \x01(\x0e\x32\x33.meshtastic.protobuf.Config.DeviceConfig.BuzzerMode\"\xd4\x01\n\x04Role\x12\n\n\x06\x43LIENT\x10\x00\x12\x0f\n\x0b\x43LIENT_MUTE\x10\x01\x12\n\n\x06ROUTER\x10\x02\x12\x15\n\rROUTER_CLIENT\x10\x03\x1a\x02\x08\x01\x12\x10\n\x08REPEATER\x10\x04\x1a\x02\x08\x01\x12\x0b\n\x07TRACKER\x10\x05\x12\n\n\x06SENSOR\x10\x06\x12\x07\n\x03TAK\x10\x07\x12\x11\n\rCLIENT_HIDDEN\x10\x08\x12\x12\n\x0eLOST_AND_FOUND\x10\t\x12\x0f\n\x0bTAK_TRACKER\x10\n\x12\x0f\n\x0bROUTER_LATE\x10\x0b\x12\x0f\n\x0b\x43LIENT_BASE\x10\x0c\"s\n\x0fRebroadcastMode\x12\x07\n\x03\x41LL\x10\x00\x12\x15\n\x11\x41LL_SKIP_DECODING\x10\x01\x12\x0e\n\nLOCAL_ONLY\x10\x02\x12\x0e\n\nKNOWN_ONLY\x10\x03\x12\x08\n\x04NONE\x10\x04\x12\x16\n\x12\x43ORE_PORTNUMS_ONLY\x10\x05\"i\n\nBuzzerMode\x12\x0f\n\x0b\x41LL_ENABLED\x10\x00\x12\x0c\n\x08\x44ISABLED\x10\x01\x12\x16\n\x12NOTIFICATIONS_ONLY\x10\x02\x12\x0f\n\x0bSYSTEM_ONLY\x10\x03\x12\x13\n\x0f\x44IRECT_MSG_ONLY\x10\x04\x1a\x9a\x05\n\x0ePositionConfig\x12\x1f\n\x17position_broadcast_secs\x18\x01 \x01(\r\x12(\n position_broadcast_smart_enabled\x18\x02 \x01(\x08\x12\x16\n\x0e\x66ixed_position\x18\x03 \x01(\x08\x12\x17\n\x0bgps_enabled\x18\x04 \x01(\x08\x42\x02\x18\x01\x12\x1b\n\x13gps_update_interval\x18\x05 \x01(\r\x12\x1c\n\x10gps_attempt_time\x18\x06 \x01(\rB\x02\x18\x01\x12\x16\n\x0eposition_flags\x18\x07 \x01(\r\x12\x0f\n\x07rx_gpio\x18\x08 \x01(\r\x12\x0f\n\x07tx_gpio\x18\t \x01(\r\x12(\n broadcast_smart_minimum_distance\x18\n \x01(\r\x12-\n%broadcast_smart_minimum_interval_secs\x18\x0b \x01(\r\x12\x13\n\x0bgps_en_gpio\x18\x0c \x01(\r\x12\x44\n\x08gps_mode\x18\r \x01(\x0e\x32\x32.meshtastic.protobuf.Config.PositionConfig.GpsMode\"\xab\x01\n\rPositionFlags\x12\t\n\x05UNSET\x10\x00\x12\x0c\n\x08\x41LTITUDE\x10\x01\x12\x10\n\x0c\x41LTITUDE_MSL\x10\x02\x12\x16\n\x12GEOIDAL_SEPARATION\x10\x04\x12\x07\n\x03\x44OP\x10\x08\x12\t\n\x05HVDOP\x10\x10\x12\r\n\tSATINVIEW\x10 \x12\n\n\x06SEQ_NO\x10@\x12\x0e\n\tTIMESTAMP\x10\x80\x01\x12\x0c\n\x07HEADING\x10\x80\x02\x12\n\n\x05SPEED\x10\x80\x04\"5\n\x07GpsMode\x12\x0c\n\x08\x44ISABLED\x10\x00\x12\x0b\n\x07\x45NABLED\x10\x01\x12\x0f\n\x0bNOT_PRESENT\x10\x02\x1a\x84\x02\n\x0bPowerConfig\x12\x17\n\x0fis_power_saving\x18\x01 \x01(\x08\x12&\n\x1eon_battery_shutdown_after_secs\x18\x02 \x01(\r\x12\x1f\n\x17\x61\x64\x63_multiplier_override\x18\x03 \x01(\x02\x12\x1b\n\x13wait_bluetooth_secs\x18\x04 \x01(\r\x12\x10\n\x08sds_secs\x18\x06 \x01(\r\x12\x0f\n\x07ls_secs\x18\x07 \x01(\r\x12\x15\n\rmin_wake_secs\x18\x08 \x01(\r\x12\"\n\x1a\x64\x65vice_battery_ina_address\x18\t \x01(\r\x12\x18\n\x10powermon_enables\x18 \x01(\x04\x1a\xf7\x03\n\rNetworkConfig\x12\x14\n\x0cwifi_enabled\x18\x01 \x01(\x08\x12\x11\n\twifi_ssid\x18\x03 \x01(\t\x12\x10\n\x08wifi_psk\x18\x04 \x01(\t\x12\x12\n\nntp_server\x18\x05 \x01(\t\x12\x13\n\x0b\x65th_enabled\x18\x06 \x01(\x08\x12K\n\x0c\x61\x64\x64ress_mode\x18\x07 \x01(\x0e\x32\x35.meshtastic.protobuf.Config.NetworkConfig.AddressMode\x12I\n\x0bipv4_config\x18\x08 \x01(\x0b\x32\x34.meshtastic.protobuf.Config.NetworkConfig.IpV4Config\x12\x16\n\x0ersyslog_server\x18\t \x01(\t\x12\x19\n\x11\x65nabled_protocols\x18\n \x01(\r\x12\x14\n\x0cipv6_enabled\x18\x0b \x01(\x08\x1a\x46\n\nIpV4Config\x12\n\n\x02ip\xLine truncated
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.config_pb2', globals())
|
||||
@@ -23,462 +22,78 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\014ConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT"]._serialized_options = b'\312\363\0307:\006ClientB-App connected or standalone messaging device.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT_MUTE"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT_MUTE"]._serialized_options = b'\312\363\030G:\013Client MuteB8Device that does not forward packets from other devices.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER"]._serialized_options = b'\312\363\030\234\001:\006RouterB\221\001Infrastructure node on a tower or mountain top only. Not to be used for roofs or mobile nodes. Needs exceptional coverage. Visible in Nodes list.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_CLIENT"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_CLIENT"]._serialized_options = b'\010\001\312\363\030\017:\rRouter Client'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_CLIENT"]._serialized_options = b'\010\001'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["REPEATER"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["REPEATER"]._serialized_options = b'\010\001\312\363\030\235\001:\010RepeaterB\220\001Deprecated infrastructure role that creates gaps in the mesh rebroadcast chain. Switch this node to a Router-based role (Router or Router Late).'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["TRACKER"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["TRACKER"]._serialized_options = b'\312\363\0307:\007TrackerB,Broadcasts GPS position packets as priority.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["SENSOR"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["SENSOR"]._serialized_options = b'\312\363\0303:\006SensorB)Broadcasts telemetry packets as priority.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["TAK"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["TAK"]._serialized_options = b'\312\363\030K:\003TAKBDOptimized for ATAK system communication, reduces routine broadcasts.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT_HIDDEN"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT_HIDDEN"]._serialized_options = b'\312\363\030T:\rClient HiddenBCDevice that only broadcasts as needed for stealth or power savings.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["LOST_AND_FOUND"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["LOST_AND_FOUND"]._serialized_options = b'\312\363\030m:\016Lost and FoundB[Broadcasts location as message to default channel regularly to assist with device recovery.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["TAK_TRACKER"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["TAK_TRACKER"]._serialized_options = b'\312\363\030S:\013TAK TrackerBDEnables automatic TAK PLI broadcasts and reduces routine broadcasts.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_LATE"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["ROUTER_LATE"]._serialized_options = b'\312\363\030\245\001:\013Router LateB\225\001Infrastructure node that always rebroadcasts packets once but only after all other modes. Visible in Nodes list. Not a good choice for rooftop nodes.'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT_BASE"]._options = None
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["CLIENT_BASE"]._serialized_options = b'\312\363\030\220\001:\013Client BaseB\200\001Rooftop or attic node that rebroadcasts like Router Late for packets from or to favorited nodes, and like Client for all others.'
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["ALL"]._options = None
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["ALL"]._serialized_options = b'\312\363\030~:\003AllBwRebroadcast any observed message, if it was on our private channel or from another channel with the same LoRa settings.'
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["ALL_SKIP_DECODING"]._options = None
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["ALL_SKIP_DECODING"]._serialized_options = b'\312\363\030~:\021All Skip DecodingBiBehaves as All. Skipping packet decoding applied only to the Repeater role, which is no longer supported.'
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["LOCAL_ONLY"]._options = None
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["LOCAL_ONLY"]._serialized_options = b'\312\363\030\271\001:\nLocal OnlyB\252\001Ignores observed messages from foreign meshes that are open or those which it cannot decrypt. Only rebroadcasts messages on the node\'s local primary / secondary channels.'
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["KNOWN_ONLY"]._options = None
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["KNOWN_ONLY"]._serialized_options = b'\312\363\030\264\001:\nKnown OnlyB\245\001Ignores observed messages from foreign meshes like Local Only, but takes it a step further by also ignoring messages from nodes not already in the node\'s known list.'
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["NONE"]._options = None
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["NONE"]._serialized_options = b'\312\363\030n:\004NoneBfInhibits all rebroadcasts, like the Client Mute role. Not allowed on the Router and Router Late roles.'
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["CORE_PORTNUMS_ONLY"]._options = None
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE.values_by_name["CORE_PORTNUMS_ONLY"]._serialized_options = b'\312\363\030\373\001:\022Core Portnums OnlyB\344\001Ignores packets on non-core portnums such as Range Test, PAX Counter and ATAK, and does not rebroadcast them. Core portnums include Text, Position, NodeInfo, Telemetry, Routing, Admin, Waypoint, Traceroute and Store and Forward.'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['role']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['role']._serialized_options = b'\312\363\030\r:\013Device Role'
|
||||
_CONFIG_DEVICECONFIG_ROLE.values_by_name["REPEATER"]._serialized_options = b'\010\001'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['serial_enabled']._serialized_options = b'\030\001'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['button_gpio']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['button_gpio']._serialized_options = b'\312\363\030\\:\013Button GPIOBMGPIO pin for the user button, can be remapped on boards with multiple buttons'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['buzzer_gpio']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['buzzer_gpio']._serialized_options = b'\312\363\030*:\013Buzzer GPIOB\033GPIO pin for the PWM buzzer'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['rebroadcast_mode']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['rebroadcast_mode']._serialized_options = b'\312\363\030\022:\020Rebroadcast Mode'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['node_info_broadcast_secs']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['node_info_broadcast_secs']._serialized_options = b'\312\363\030t\031\000\000\000\000\000 \254@*\001s:\034Node Info Broadcast IntervalBHHow often node information is sent. Defaults to 3 hours, minimum 1 hour.'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['double_tap_as_button_press']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['double_tap_as_button_press']._serialized_options = b'\312\363\030\\:\024Double Tap as ButtonBDTreat double tap on supported accelerometers as a user button press.'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['is_managed']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['is_managed']._serialized_options = b'\030\001'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['disable_triple_click']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['disable_triple_click']._serialized_options = b'\312\363\030G:\024Disable Triple ClickB/Disables the user button triple-press shortcut.'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['tzdef']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['tzdef']._serialized_options = b'\312\363\030-:\tTime ZoneB POSIX timezone definition string'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['led_heartbeat_disabled']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['led_heartbeat_disabled']._serialized_options = b'\312\363\030\237\001:\025Disable LED HeartbeatB\205\001Turns off the blinking LED on the device. On most devices this is one of up to 4 LEDs; the charger and GPS LEDs are not controllable.'
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['buzzer_mode']._options = None
|
||||
_CONFIG_DEVICECONFIG.fields_by_name['buzzer_mode']._serialized_options = b'\312\363\030\007R\0052.7.0'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["ALTITUDE"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["ALTITUDE"]._serialized_options = b'\312\363\030Q:\010AltitudeBEInclude an altitude value in position reports, when one is available.'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["ALTITUDE_MSL"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["ALTITUDE_MSL"]._serialized_options = b'\312\363\030\034:\032Altitude is Mean Sea Level'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["GEOIDAL_SEPARATION"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["GEOIDAL_SEPARATION"]._serialized_options = b'\312\363\030\035:\033Altitude Geoidal Separation'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["DOP"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["DOP"]._serialized_options = b'\312\363\030H:\003DOPBAInclude the dilution of precision value. PDOP is used by default.'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["HVDOP"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["HVDOP"]._serialized_options = b'\312\363\030Q:\013HDOP / VDOPBBIf DOP is set, send separate HDOP and VDOP values instead of PDOP.'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["SATINVIEW"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["SATINVIEW"]._serialized_options = b'\312\363\030\026:\024Number of satellites'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["SEQ_NO"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["SEQ_NO"]._serialized_options = b'\312\363\030\021:\017Sequence number'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["TIMESTAMP"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["TIMESTAMP"]._serialized_options = b'\312\363\030\013:\tTimestamp'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["HEADING"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["HEADING"]._serialized_options = b'\312\363\030\021:\017Vehicle heading'
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["SPEED"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS.values_by_name["SPEED"]._serialized_options = b'\312\363\030\017:\rVehicle speed'
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE.values_by_name["DISABLED"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE.values_by_name["DISABLED"]._serialized_options = b'\312\363\030\n:\010Disabled'
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE.values_by_name["ENABLED"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE.values_by_name["ENABLED"]._serialized_options = b'\312\363\030\t:\007Enabled'
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE.values_by_name["NOT_PRESENT"]._options = None
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE.values_by_name["NOT_PRESENT"]._serialized_options = b'\312\363\030\r:\013Not Present'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['position_broadcast_secs']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['position_broadcast_secs']._serialized_options = b'\312\363\030T*\001s:\022Broadcast IntervalB;The longest a node will go without broadcasting a position.'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['position_broadcast_smart_enabled']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['position_broadcast_smart_enabled']._serialized_options = b'\312\363\030\020:\016Smart Position'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['fixed_position']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['fixed_position']._serialized_options = b'\312\363\030\224\001:\016Fixed PositionB\201\001The last known latitude, longitude and altitude are broadcast over the mesh on the position interval, rather than a live GPS fix.'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_enabled']._serialized_options = b'\030\001'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_update_interval']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_update_interval']._serialized_options = b'\312\363\030=*\001s:\017Update IntervalB\'How often to try to get a GPS position.'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_attempt_time']._serialized_options = b'\030\001'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['position_flags']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['position_flags']._serialized_options = b'\312\363\030N:\016Position FlagsB<Optional fields to include when assembling position messages'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['rx_gpio']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['rx_gpio']._serialized_options = b'\312\363\030)\010\001:\020GPS Receive GPIOB\023GPIO pin for GPS RX'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['tx_gpio']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['tx_gpio']._serialized_options = b'\312\363\030*\010\001:\021GPS Transmit GPIOB\023GPIO pin for GPS TX'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['broadcast_smart_minimum_distance']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['broadcast_smart_minimum_distance']._serialized_options = b'\312\363\030f*\001m:\020Minimum DistanceBOThe minimum change in distance before a smart position broadcast is considered.'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['broadcast_smart_minimum_interval_secs']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['broadcast_smart_minimum_interval_secs']._serialized_options = b'\312\363\030m*\001s:\020Minimum IntervalBVThe shortest interval between position updates once the minimum distance has been met.'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_en_gpio']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_en_gpio']._serialized_options = b'\312\363\030,\010\001:\017GPS Enable GPIOB\027GPIO pin for GPS enable'
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_mode']._options = None
|
||||
_CONFIG_POSITIONCONFIG.fields_by_name['gps_mode']._serialized_options = b'\312\363\030\n:\010GPS Mode'
|
||||
_CONFIG_POWERCONFIG.fields_by_name['is_power_saving']._options = None
|
||||
_CONFIG_POWERCONFIG.fields_by_name['is_power_saving']._serialized_options = b'\312\363\030\366\001:\014Power SavingB\345\001Will sleep everything as much as possible, for the Tracker and Sensor roles this also includes the LoRa radio. Don\'t use this setting if you want to use your device with the phone apps or are using a device without a user button.'
|
||||
_CONFIG_POWERCONFIG.fields_by_name['on_battery_shutdown_after_secs']._options = None
|
||||
_CONFIG_POWERCONFIG.fields_by_name['on_battery_shutdown_after_secs']._serialized_options = b'\312\363\030\237\001*\001s:\026Shutdown on Power LossB\201\001How long after external power is removed before the device powers off. Zero to disable; values under 30 seconds are raised to 30.'
|
||||
_CONFIG_POWERCONFIG.fields_by_name['adc_multiplier_override']._options = None
|
||||
_CONFIG_POWERCONFIG.fields_by_name['adc_multiplier_override']._serialized_options = b'\312\363\030\016:\014ADC Override'
|
||||
_CONFIG_POWERCONFIG.fields_by_name['wait_bluetooth_secs']._options = None
|
||||
_CONFIG_POWERCONFIG.fields_by_name['wait_bluetooth_secs']._serialized_options = b'\312\363\030 *\001s:\033Wait for Bluetooth Duration'
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['ip']._options = None
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['ip']._serialized_options = b'\312\363\030\004:\002IP'
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['gateway']._options = None
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['gateway']._serialized_options = b'\312\363\030\t:\007Gateway'
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['subnet']._options = None
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['subnet']._serialized_options = b'\312\363\030\010:\006Subnet'
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['dns']._options = None
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG.fields_by_name['dns']._serialized_options = b'\312\363\030\005:\003DNS'
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE.values_by_name["DHCP"]._options = None
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE.values_by_name["DHCP"]._serialized_options = b'\312\363\030\006:\004DHCP'
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE.values_by_name["STATIC"]._options = None
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE.values_by_name["STATIC"]._serialized_options = b'\312\363\030\010:\006Static'
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS.values_by_name["NO_BROADCAST"]._options = None
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS.values_by_name["NO_BROADCAST"]._serialized_options = b'\312\363\030\006:\004None'
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS.values_by_name["UDP_BROADCAST"]._options = None
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS.values_by_name["UDP_BROADCAST"]._serialized_options = b'\312\363\030\017:\rUDP Broadcast'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['wifi_enabled']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['wifi_enabled']._serialized_options = b'\312\363\030O:\014WiFi EnabledB?Enabling WiFi will disable the Bluetooth connection to the app.'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['wifi_ssid']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['wifi_ssid']._serialized_options = b'\312\363\030\':\004SSIDB\037WiFi network name to connect to'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['wifi_psk']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['wifi_psk']._serialized_options = b'\312\363\030,:\010PasswordB WiFi password for authentication'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['ntp_server']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['ntp_server']._serialized_options = b'\312\363\030E:\nNTP ServerB7NTP server address. Defaults to meshtastic.pool.ntp.org'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['eth_enabled']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['eth_enabled']._serialized_options = b'\312\363\030h:\020Ethernet EnabledBTOn ESP32 boards, enabling Ethernet will disable the Bluetooth connection to the app.'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['address_mode']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['address_mode']._serialized_options = b'\312\363\030\016:\014Address Mode'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['rsyslog_server']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['rsyslog_server']._serialized_options = b'\312\363\030\020:\016Rsyslog Server'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['enabled_protocols']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['enabled_protocols']._serialized_options = b'\312\363\030W:\021Enabled ProtocolsB;Enable broadcasting packets via UDP over the local network.R\0052.6.0'
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['ipv6_enabled']._options = None
|
||||
_CONFIG_NETWORKCONFIG.fields_by_name['ipv6_enabled']._serialized_options = b'\312\363\030\010R\0062.7.16'
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS.values_by_name["METRIC"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS.values_by_name["METRIC"]._serialized_options = b'\312\363\030\010:\006Metric'
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS.values_by_name["IMPERIAL"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS.values_by_name["IMPERIAL"]._serialized_options = b'\312\363\030\n:\010Imperial'
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_AUTO"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_AUTO"]._serialized_options = b'\312\363\030\026:\024Detect Automatically'
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SSD1306"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SSD1306"]._serialized_options = b'\312\363\030\t:\007SSD1306'
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1106"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1106"]._serialized_options = b'\312\363\030\010:\006SH1106'
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1107"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1107"]._serialized_options = b'\312\363\030\010:\006SH1107'
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1107_128_128"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1107_128_128"]._serialized_options = b'\312\363\030\020:\016SH1107 128x128'
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1107_ROTATED"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE.values_by_name["OLED_SH1107_ROTATED"]._serialized_options = b'\312\363\030\020:\016SH1107 Rotated'
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["DEFAULT"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["DEFAULT"]._serialized_options = b'\312\363\030\036:\034Default 128x64 screen layout'
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["TWOCOLOR"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["TWOCOLOR"]._serialized_options = b'\312\363\030 :\036Optimized for 2 color displays'
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["INVERTED"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["INVERTED"]._serialized_options = b'\312\363\030\':%Inverted top bar for 2 color displays'
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["COLOR"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE.values_by_name["COLOR"]._serialized_options = b'\312\363\030\031:\027TFT Full Color Displays'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_0"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_0"]._serialized_options = b'\312\363\030\005:\0030\302\260'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_90"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_90"]._serialized_options = b'\312\363\030\006:\00490\302\260'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_180"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_180"]._serialized_options = b'\312\363\030\007:\005180\302\260'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_270"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_270"]._serialized_options = b'\312\363\030\007:\005270\302\260'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_0_INVERTED"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_0_INVERTED"]._serialized_options = b'\312\363\030\016:\0140\302\260 Inverted'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_90_INVERTED"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_90_INVERTED"]._serialized_options = b'\312\363\030\017:\r90\302\260 Inverted'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_180_INVERTED"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_180_INVERTED"]._serialized_options = b'\312\363\030\020:\016180\302\260 Inverted'
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_270_INVERTED"]._options = None
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION.values_by_name["DEGREES_270_INVERTED"]._serialized_options = b'\312\363\030\020:\016270\302\260 Inverted'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['screen_on_secs']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['screen_on_secs']._serialized_options = b'\312\363\030m*\001s:\rScreen on forBYHow long the screen remains on after the user button is pressed or messages are received.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['gps_format']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['gps_format']._serialized_options = b'\030\001\312\363\030\010Z\0062.7.10'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['auto_screen_carousel_secs']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['auto_screen_carousel_secs']._serialized_options = b'\312\363\030g*\001s:\021Carousel IntervalBOAutomatically moves to the next screen page, like a carousel, on this interval.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['gps_format']._serialized_options = b'\030\001'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['compass_north_top']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['compass_north_top']._serialized_options = b'\030\001\312\363\030m:\022Always point northBPThe compass heading on the screen outside of the circle will always point north.Z\0052.7.1'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['flip_screen']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['flip_screen']._serialized_options = b'\312\363\030%:\013Flip ScreenB\026Flip screen vertically'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['units']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['units']._serialized_options = b'\312\363\0302:\rDisplay UnitsB!Units shown on the device screen.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['oled']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['oled']._serialized_options = b'\312\363\0306:\tOLED TypeB)Override automatic OLED screen detection.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['displaymode']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['displaymode']._serialized_options = b'\312\363\030/:\014Display ModeB\037Override default screen layout.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['heading_bold']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['heading_bold']._serialized_options = b'\312\363\0304:\014Bold HeadingB$Bold the heading text on the screen.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['wake_on_tap_or_motion']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['wake_on_tap_or_motion']._serialized_options = b'\312\363\030W:\034Wake Screen on tap or motionB7Requires that there be an accelerometer on your device.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['compass_orientation']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['compass_orientation']._serialized_options = b'\312\363\030a:\023Compass OrientationBJIndicates how to rotate or invert the compass output for accurate display.'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['use_12h_clock']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['use_12h_clock']._serialized_options = b'\312\363\030A:\r12 Hour ClockB(Sets the screen clock format to 12-hour.R\0062.5.22'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['use_long_node_name']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['use_long_node_name']._serialized_options = b'\312\363\030\010R\0062.7.13'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['enable_message_bubbles']._options = None
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['enable_message_bubbles']._serialized_options = b'\312\363\030\010R\0062.7.19'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["UNSET"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["UNSET"]._serialized_options = b'\312\363\030\025:\023Please set a region'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["US"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["US"]._serialized_options = b'\312\363\030\017:\rUnited States'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_433"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_433"]._serialized_options = b'\312\363\030\027:\025European Union 433MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_868"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_868"]._serialized_options = b'\312\363\030\027:\025European Union 868MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["CN"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["CN"]._serialized_options = b'\312\363\030\007:\005China'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["JP"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["JP"]._serialized_options = b'\312\363\030\007:\005Japan'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ANZ"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ANZ"]._serialized_options = b'\312\363\030\031:\027Australia / New Zealand'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["KR"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["KR"]._serialized_options = b'\312\363\030\007:\005Korea'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["TW"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["TW"]._serialized_options = b'\312\363\030\010:\006Taiwan'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["RU"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["RU"]._serialized_options = b'\312\363\030\010:\006Russia'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["IN"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["IN"]._serialized_options = b'\312\363\030\007:\005India'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["NZ_865"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["NZ_865"]._serialized_options = b'\312\363\030\024:\022New Zealand 865MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["TH"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["TH"]._serialized_options = b'\312\363\030\n:\010Thailand'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["LORA_24"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["LORA_24"]._serialized_options = b'\312\363\030\t:\0072.4 GHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["UA_433"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["UA_433"]._serialized_options = b'\312\363\030\020:\016Ukraine 433MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["UA_868"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["UA_868"]._serialized_options = b'\010\001\312\363\030\020:\016Ukraine 868MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["MY_433"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["MY_433"]._serialized_options = b'\312\363\030\021:\017Malaysia 433MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["MY_919"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["MY_919"]._serialized_options = b'\312\363\030\021:\017Malaysia 919MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["SG_923"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["SG_923"]._serialized_options = b'\312\363\030\022:\020Singapore 923MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["PH_433"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["PH_433"]._serialized_options = b'\312\363\030\024:\022Philippines 433MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["PH_868"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["PH_868"]._serialized_options = b'\312\363\030\024:\022Philippines 868MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["PH_915"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["PH_915"]._serialized_options = b'\312\363\030\024:\022Philippines 915MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ANZ_433"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ANZ_433"]._serialized_options = b'\312\363\030 :\036Australia / New Zealand 433MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["KZ_433"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["KZ_433"]._serialized_options = b'\312\363\030\023:\021Kazakhstan 433MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["KZ_863"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["KZ_863"]._serialized_options = b'\312\363\030\023:\021Kazakhstan 863MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["NP_865"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["NP_865"]._serialized_options = b'\312\363\030\016:\014Nepal 865MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["BR_902"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["BR_902"]._serialized_options = b'\312\363\030\017:\rBrazil 902MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU1_2M"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU1_2M"]._serialized_options = b'\312\363\030\033:\031ITU Region 1 / Amateur 2m'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU2_2M"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU2_2M"]._serialized_options = b'\312\363\030\033:\031ITU Region 2 / Amateur 2m'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_866"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_866"]._serialized_options = b'\312\363\030\027:\025European Union 866MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_874"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_874"]._serialized_options = b'\312\363\030\027:\025European Union 874MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_917"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_917"]._serialized_options = b'\312\363\030\027:\025European Union 917MHz'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_N_868"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["EU_N_868"]._serialized_options = b'\312\363\030 :\036European Union 868MHz (Narrow)'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU3_2M"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU3_2M"]._serialized_options = b'\312\363\030\033:\031ITU Region 3 / Amateur 2m'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU1_70CM"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU1_70CM"]._serialized_options = b'\312\363\030\035:\033ITU Region 1 / Amateur 70cm'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU2_70CM"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU2_70CM"]._serialized_options = b'\312\363\030\035:\033ITU Region 2 / Amateur 70cm'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU3_70CM"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU3_70CM"]._serialized_options = b'\312\363\030\035:\033ITU Region 3 / Amateur 70cm'
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU2_125CM"]._options = None
|
||||
_CONFIG_LORACONFIG_REGIONCODE.values_by_name["ITU2_125CM"]._serialized_options = b'\312\363\030\036:\034ITU Region 2 / Amateur 1.25m'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_FAST"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_FAST"]._serialized_options = b'\312\363\030%:\021Long Range - FastJ\020longfast|default'
|
||||
_CONFIG_DISPLAYCONFIG.fields_by_name['compass_north_top']._serialized_options = b'\030\001'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_SLOW"]._serialized_options = b'\010\001\312\363\030\023:\021Long Range - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_SLOW"]._serialized_options = b'\010\001'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._serialized_options = b'\010\001\312\363\030\030:\026Very Long Range - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["MEDIUM_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["MEDIUM_SLOW"]._serialized_options = b'\312\363\030\025:\023Medium Range - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["MEDIUM_FAST"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["MEDIUM_FAST"]._serialized_options = b'\312\363\030\025:\023Medium Range - Fast'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["SHORT_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["SHORT_SLOW"]._serialized_options = b'\312\363\030\024:\022Short Range - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["SHORT_FAST"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["SHORT_FAST"]._serialized_options = b'\312\363\030\024:\022Short Range - Fast'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_MODERATE"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_MODERATE"]._serialized_options = b'\312\363\030\027:\025Long Range - Moderate'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["SHORT_TURBO"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["SHORT_TURBO"]._serialized_options = b'\312\363\030\025:\023Short Range - Turbo'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_TURBO"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LONG_TURBO"]._serialized_options = b'\312\363\030\024:\022Long Range - Turbo'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LITE_FAST"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LITE_FAST"]._serialized_options = b'\312\363\030\r:\013Lite - Fast'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LITE_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["LITE_SLOW"]._serialized_options = b'\312\363\030\r:\013Lite - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["NARROW_FAST"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["NARROW_FAST"]._serialized_options = b'\312\363\030\017:\rNarrow - Fast'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["NARROW_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["NARROW_SLOW"]._serialized_options = b'\312\363\030\017:\rNarrow - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["TINY_FAST"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["TINY_FAST"]._serialized_options = b'\312\363\030\r:\013Tiny - Fast'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["TINY_SLOW"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["TINY_SLOW"]._serialized_options = b'\312\363\030\r:\013Tiny - Slow'
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["MEDIUM_TURBO"]._options = None
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["MEDIUM_TURBO"]._serialized_options = b'\312\363\030\026:\024Medium Range - Turbo'
|
||||
_CONFIG_LORACONFIG.fields_by_name['use_preset']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['use_preset']._serialized_options = b'\312\363\030h:\nUse PresetBZUse the modem preset settings instead of a manual bandwidth, spread factor and coding rate'
|
||||
_CONFIG_LORACONFIG.fields_by_name['modem_preset']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['modem_preset']._serialized_options = b'\312\363\030\t:\007Presets'
|
||||
_CONFIG_LORACONFIG.fields_by_name['bandwidth']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['bandwidth']._serialized_options = b'\312\363\030\020*\003kHz:\tBandwidth'
|
||||
_CONFIG_LORACONFIG.fields_by_name['spread_factor']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['spread_factor']._serialized_options = b'\312\363\030Z\031\000\000\000\000\000\000\024@!\000\000\000\000\000\000(@:\rSpread FactorB7Number of chirps per symbol, as 2 raised to this value.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['coding_rate']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['coding_rate']._serialized_options = b'\312\363\030\210\001:\013Coding RateByError-correction redundancy, as the denominator of 4/n. Higher values survive noisier links but make every packet longer.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['region']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['region']._serialized_options = b'\312\363\0309:\006RegionB/The region where you will be using your radios.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['hop_limit']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['hop_limit']._serialized_options = b'\312\363\030\204\001\031\000\000\000\000\000\000\000\000!\000\000\000\000\000\000\034@:\tHop LimitBIHow many times a message may be repeated before it stops being forwarded.J\032hops|ttl|range|rebroadcast'
|
||||
_CONFIG_LORACONFIG.fields_by_name['tx_enabled']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['tx_enabled']._serialized_options = b'\312\363\030l:\020Transmit EnabledBXAllow the LoRa radio to transmit. Turn off while hot-swapping antennas or bench testing.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['tx_power']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['tx_power']._serialized_options = b'\312\363\030\266\001\031\000\000\000\000\000\000\000\000!\000\000\000\000\000\000B@*\003dBm:\016Transmit PowerBxRadio transmit power. Leave at zero to use the highest level legal for the region, which is what most radios should use.J\023tx|power|dbm|output'
|
||||
_CONFIG_LORACONFIG.fields_by_name['channel_num']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['channel_num']._serialized_options = b'\312\363\030\275\001:\016Frequency SlotB\252\001Your node\'s operating frequency is calculated based on the region, modem preset, and this field. When 0, the region picks the slot, usually from the primary channel name.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['override_duty_cycle']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['override_duty_cycle']._serialized_options = b'\312\363\030\025:\023Override Duty Cycle'
|
||||
_CONFIG_LORACONFIG.fields_by_name['sx126x_rx_boosted_gain']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['sx126x_rx_boosted_gain']._serialized_options = b'\312\363\030F:\017RX Boosted GainB3Enable RX boosted gain mode on SX126x-based radios.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['override_frequency']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['override_frequency']._serialized_options = b'\312\363\030\031*\003MHz:\022Frequency Override'
|
||||
_CONFIG_LORACONFIG.fields_by_name['pa_fan_disabled']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['pa_fan_disabled']._serialized_options = b'\312\363\030\021:\017PA Fan Disabled'
|
||||
_CONFIG_LORACONFIG.fields_by_name['ignore_incoming']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['ignore_incoming']._serialized_options = b'\312\363\030\021:\017Ignore Incoming'
|
||||
_CONFIG_LORACONFIG.fields_by_name['ignore_mqtt']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['ignore_mqtt']._serialized_options = b'\312\363\030`:\013Ignore MQTTBQIgnore packets received over LoRa that travelled via MQTT anywhere on their path.'
|
||||
_CONFIG_LORACONFIG.fields_by_name['config_ok_to_mqtt']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['config_ok_to_mqtt']._serialized_options = b'\312\363\030\014:\nOK to MQTT'
|
||||
_CONFIG_LORACONFIG.fields_by_name['fem_lna_mode']._options = None
|
||||
_CONFIG_LORACONFIG.fields_by_name['fem_lna_mode']._serialized_options = b'\312\363\030\010R\0062.7.20'
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE.values_by_name["RANDOM_PIN"]._options = None
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE.values_by_name["RANDOM_PIN"]._serialized_options = b'\312\363\030\014:\nRandom PIN'
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE.values_by_name["FIXED_PIN"]._options = None
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE.values_by_name["FIXED_PIN"]._serialized_options = b'\312\363\030\013:\tFixed PIN'
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE.values_by_name["NO_PIN"]._options = None
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE.values_by_name["NO_PIN"]._serialized_options = b'\312\363\030\025:\023No PIN (Just Works)'
|
||||
_CONFIG_BLUETOOTHCONFIG.fields_by_name['enabled']._options = None
|
||||
_CONFIG_BLUETOOTHCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\0303:\021Bluetooth EnabledB\036Enable Bluetooth on the device'
|
||||
_CONFIG_BLUETOOTHCONFIG.fields_by_name['mode']._options = None
|
||||
_CONFIG_BLUETOOTHCONFIG.fields_by_name['mode']._serialized_options = b'\312\363\030*:\014Pairing ModeB\032Bluetooth pairing strategy'
|
||||
_CONFIG_BLUETOOTHCONFIG.fields_by_name['fixed_pin']._options = None
|
||||
_CONFIG_BLUETOOTHCONFIG.fields_by_name['fixed_pin']._serialized_options = b'\312\363\030X:\tFixed PinBKFixed PIN for Bluetooth pairing. Used when pairing mode is set to fixed PIN'
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY.values_by_name["PACKET_SIGNATURE_POLICY_COMPATIBLE"]._options = None
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY.values_by_name["PACKET_SIGNATURE_POLICY_COMPATIBLE"]._serialized_options = b'\312\363\030\227\001:\034Compatible - Accept UnsignedBwAccept unsigned traffic for maximum compatibility. A signature that can be checked and is wrong still drops the packet.'
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY.values_by_name["PACKET_SIGNATURE_POLICY_BALANCED"]._options = None
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY.values_by_name["PACKET_SIGNATURE_POLICY_BALANCED"]._serialized_options = b'\312\363\030\200\001:\037Balanced - Prefer AuthenticatedB]Prefer authenticated packets, but still accept unsigned traffic from nodes not known to sign.'
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY.values_by_name["PACKET_SIGNATURE_POLICY_STRICT"]._options = None
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY.values_by_name["PACKET_SIGNATURE_POLICY_STRICT"]._serialized_options = b'\312\363\030\227\001:\037Strict - Require AuthenticationBtAccept only packets with a verified signature or successful PKI decryption. Packets from older nodes may be ignored.'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['public_key']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['public_key']._serialized_options = b'\312\363\030\202\001:\nPublic KeyBtGenerated from your private key and sent out to other nodes on the mesh to allow them to compute a shared secret key'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['private_key']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['private_key']._serialized_options = b'\312\363\030?:\013Private KeyB0Used to create a shared key with a remote device'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['admin_key']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['admin_key']._serialized_options = b'\312\363\030V:\tAdmin KeyBIPublic keys (up to three) authorized to send admin messages to this node.'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['is_managed']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['is_managed']._serialized_options = b'\312\363\030\210\001:\016Managed DeviceBvSettings are changed by a mesh administrator using an admin key, not from the local app. Needs at least one admin key.'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['serial_enabled']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['serial_enabled']._serialized_options = b'\312\363\0305:\016Serial ConsoleB#Serial Console over the Stream API.'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['debug_log_api_enabled']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['debug_log_api_enabled']._serialized_options = b'\312\363\030r:\nDebug LogsBdOutput live debug logging over serial, view and export position-redacted device logs over Bluetooth.'
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['packet_signature_policy']._options = None
|
||||
_CONFIG_SECURITYCONFIG.fields_by_name['packet_signature_policy']._serialized_options = b'\312\363\030\007R\0052.8.0'
|
||||
_CONFIG._serialized_start=138
|
||||
_CONFIG._serialized_end=17309
|
||||
_CONFIG_DEVICECONFIG._serialized_start=767
|
||||
_CONFIG_DEVICECONFIG._serialized_end=4735
|
||||
_CONFIG_DEVICECONFIG_ROLE._serialized_start=1964
|
||||
_CONFIG_DEVICECONFIG_ROLE._serialized_end=3483
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE._serialized_start=3486
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE._serialized_end=4628
|
||||
_CONFIG_DEVICECONFIG_BUZZERMODE._serialized_start=4630
|
||||
_CONFIG_DEVICECONFIG_BUZZERMODE._serialized_end=4735
|
||||
_CONFIG_POSITIONCONFIG._serialized_start=4738
|
||||
_CONFIG_POSITIONCONFIG._serialized_end=6693
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_start=5984
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_end=6588
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE._serialized_start=6590
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE._serialized_end=6693
|
||||
_CONFIG_POWERCONFIG._serialized_start=6696
|
||||
_CONFIG_POWERCONFIG._serialized_end=7437
|
||||
_CONFIG_NETWORKCONFIG._serialized_start=7440
|
||||
_CONFIG_NETWORKCONFIG._serialized_end=8567
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG._serialized_start=8297
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG._serialized_end=8417
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE._serialized_start=8419
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE._serialized_end=8480
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS._serialized_start=8482
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS._serialized_end=8567
|
||||
_CONFIG_DISPLAYCONFIG._serialized_start=8570
|
||||
_CONFIG_DISPLAYCONFIG._serialized_end=11054
|
||||
_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT._serialized_start=10153
|
||||
_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT._serialized_end=10196
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS._serialized_start=10198
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS._serialized_end=10268
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE._serialized_start=10271
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE._serialized_end=10513
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE._serialized_start=10516
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE._serialized_end=10731
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION._serialized_start=10734
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION._serialized_end=11054
|
||||
_CONFIG_LORACONFIG._serialized_start=11057
|
||||
_CONFIG_LORACONFIG._serialized_end=15305
|
||||
_CONFIG_LORACONFIG_REGIONCODE._serialized_start=13099
|
||||
_CONFIG_LORACONFIG_REGIONCODE._serialized_end=14513
|
||||
_CONFIG_LORACONFIG_MODEMPRESET._serialized_start=14516
|
||||
_CONFIG_LORACONFIG_MODEMPRESET._serialized_end=15245
|
||||
_CONFIG_LORACONFIG_FEM_LNA_MODE._serialized_start=15247
|
||||
_CONFIG_LORACONFIG_FEM_LNA_MODE._serialized_end=15305
|
||||
_CONFIG_BLUETOOTHCONFIG._serialized_start=15308
|
||||
_CONFIG_BLUETOOTHCONFIG._serialized_end=15751
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE._serialized_start=15633
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE._serialized_end=15751
|
||||
_CONFIG_SECURITYCONFIG._serialized_start=15754
|
||||
_CONFIG_SECURITYCONFIG._serialized_end=17270
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY._serialized_start=16676
|
||||
_CONFIG_SECURITYCONFIG_PACKETSIGNATUREPOLICY._serialized_end=17270
|
||||
_CONFIG_SESSIONKEYCONFIG._serialized_start=17272
|
||||
_CONFIG_SESSIONKEYCONFIG._serialized_end=17290
|
||||
_CONFIG_LORACONFIG_MODEMPRESET.values_by_name["VERY_LONG_SLOW"]._serialized_options = b'\010\001'
|
||||
_CONFIG._serialized_start=95
|
||||
_CONFIG._serialized_end=5962
|
||||
_CONFIG_DEVICECONFIG._serialized_start=724
|
||||
_CONFIG_DEVICECONFIG._serialized_end=1637
|
||||
_CONFIG_DEVICECONFIG_ROLE._serialized_start=1201
|
||||
_CONFIG_DEVICECONFIG_ROLE._serialized_end=1413
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE._serialized_start=1415
|
||||
_CONFIG_DEVICECONFIG_REBROADCASTMODE._serialized_end=1530
|
||||
_CONFIG_DEVICECONFIG_BUZZERMODE._serialized_start=1532
|
||||
_CONFIG_DEVICECONFIG_BUZZERMODE._serialized_end=1637
|
||||
_CONFIG_POSITIONCONFIG._serialized_start=1640
|
||||
_CONFIG_POSITIONCONFIG._serialized_end=2306
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_start=2080
|
||||
_CONFIG_POSITIONCONFIG_POSITIONFLAGS._serialized_end=2251
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE._serialized_start=2253
|
||||
_CONFIG_POSITIONCONFIG_GPSMODE._serialized_end=2306
|
||||
_CONFIG_POWERCONFIG._serialized_start=2309
|
||||
_CONFIG_POWERCONFIG._serialized_end=2569
|
||||
_CONFIG_NETWORKCONFIG._serialized_start=2572
|
||||
_CONFIG_NETWORKCONFIG._serialized_end=3075
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG._serialized_start=2914
|
||||
_CONFIG_NETWORKCONFIG_IPV4CONFIG._serialized_end=2984
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE._serialized_start=2986
|
||||
_CONFIG_NETWORKCONFIG_ADDRESSMODE._serialized_end=3021
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS._serialized_start=3023
|
||||
_CONFIG_NETWORKCONFIG_PROTOCOLFLAGS._serialized_end=3075
|
||||
_CONFIG_DISPLAYCONFIG._serialized_start=3078
|
||||
_CONFIG_DISPLAYCONFIG._serialized_end=4213
|
||||
_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT._serialized_start=3743
|
||||
_CONFIG_DISPLAYCONFIG_DEPRECATEDGPSCOORDINATEFORMAT._serialized_end=3786
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS._serialized_start=3788
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYUNITS._serialized_end=3828
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE._serialized_start=3830
|
||||
_CONFIG_DISPLAYCONFIG_OLEDTYPE._serialized_end=3957
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE._serialized_start=3959
|
||||
_CONFIG_DISPLAYCONFIG_DISPLAYMODE._serialized_end=4024
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION._serialized_start=4027
|
||||
_CONFIG_DISPLAYCONFIG_COMPASSORIENTATION._serialized_end=4213
|
||||
_CONFIG_LORACONFIG._serialized_start=4216
|
||||
_CONFIG_LORACONFIG._serialized_end=5553
|
||||
_CONFIG_LORACONFIG_REGIONCODE._serialized_start=4846
|
||||
_CONFIG_LORACONFIG_REGIONCODE._serialized_end=5237
|
||||
_CONFIG_LORACONFIG_MODEMPRESET._serialized_start=5240
|
||||
_CONFIG_LORACONFIG_MODEMPRESET._serialized_end=5493
|
||||
_CONFIG_LORACONFIG_FEM_LNA_MODE._serialized_start=5495
|
||||
_CONFIG_LORACONFIG_FEM_LNA_MODE._serialized_end=5553
|
||||
_CONFIG_BLUETOOTHCONFIG._serialized_start=5556
|
||||
_CONFIG_BLUETOOTHCONFIG._serialized_end=5738
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE._serialized_start=5682
|
||||
_CONFIG_BLUETOOTHCONFIG_PAIRINGMODE._serialized_end=5738
|
||||
_CONFIG_SECURITYCONFIG._serialized_start=5741
|
||||
_CONFIG_SECURITYCONFIG._serialized_end=5923
|
||||
_CONFIG_SESSIONKEYCONFIG._serialized_start=5925
|
||||
_CONFIG_SESSIONKEYCONFIG._serialized_end=5943
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,5 +1,4 @@
|
||||
from meshtastic.protobuf import device_ui_pb2 as _device_ui_pb2
|
||||
from meshtastic.protobuf import field_metadata_pb2 as _field_metadata_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
|
||||
@@ -174,12 +173,8 @@ class Config(_message.Message):
|
||||
IGNORE_MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
IN: Config.LoRaConfig.RegionCode
|
||||
ITU1_2M: Config.LoRaConfig.RegionCode
|
||||
ITU1_70CM: Config.LoRaConfig.RegionCode
|
||||
ITU2_125CM: Config.LoRaConfig.RegionCode
|
||||
ITU2_2M: Config.LoRaConfig.RegionCode
|
||||
ITU2_70CM: Config.LoRaConfig.RegionCode
|
||||
ITU3_2M: Config.LoRaConfig.RegionCode
|
||||
ITU3_70CM: Config.LoRaConfig.RegionCode
|
||||
JP: Config.LoRaConfig.RegionCode
|
||||
KR: Config.LoRaConfig.RegionCode
|
||||
KZ_433: Config.LoRaConfig.RegionCode
|
||||
@@ -193,7 +188,6 @@ class Config(_message.Message):
|
||||
LORA_24: Config.LoRaConfig.RegionCode
|
||||
MEDIUM_FAST: Config.LoRaConfig.ModemPreset
|
||||
MEDIUM_SLOW: Config.LoRaConfig.ModemPreset
|
||||
MEDIUM_TURBO: Config.LoRaConfig.ModemPreset
|
||||
MODEM_PRESET_FIELD_NUMBER: _ClassVar[int]
|
||||
MY_433: Config.LoRaConfig.RegionCode
|
||||
MY_919: Config.LoRaConfig.RegionCode
|
||||
@@ -218,8 +212,6 @@ class Config(_message.Message):
|
||||
SPREAD_FACTOR_FIELD_NUMBER: _ClassVar[int]
|
||||
SX126X_RX_BOOSTED_GAIN_FIELD_NUMBER: _ClassVar[int]
|
||||
TH: Config.LoRaConfig.RegionCode
|
||||
TINY_FAST: Config.LoRaConfig.ModemPreset
|
||||
TINY_SLOW: Config.LoRaConfig.ModemPreset
|
||||
TW: Config.LoRaConfig.RegionCode
|
||||
TX_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
TX_POWER_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -361,17 +353,11 @@ class Config(_message.Message):
|
||||
wait_bluetooth_secs: int
|
||||
def __init__(self, is_power_saving: bool = ..., on_battery_shutdown_after_secs: _Optional[int] = ..., adc_multiplier_override: _Optional[float] = ..., wait_bluetooth_secs: _Optional[int] = ..., sds_secs: _Optional[int] = ..., ls_secs: _Optional[int] = ..., min_wake_secs: _Optional[int] = ..., device_battery_ina_address: _Optional[int] = ..., powermon_enables: _Optional[int] = ...) -> None: ...
|
||||
class SecurityConfig(_message.Message):
|
||||
__slots__ = ["admin_channel_enabled", "admin_key", "debug_log_api_enabled", "is_managed", "packet_signature_policy", "private_key", "public_key", "serial_enabled"]
|
||||
class PacketSignaturePolicy(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
__slots__ = ["admin_channel_enabled", "admin_key", "debug_log_api_enabled", "is_managed", "private_key", "public_key", "serial_enabled"]
|
||||
ADMIN_CHANNEL_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
ADMIN_KEY_FIELD_NUMBER: _ClassVar[int]
|
||||
DEBUG_LOG_API_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_MANAGED_FIELD_NUMBER: _ClassVar[int]
|
||||
PACKET_SIGNATURE_POLICY_BALANCED: Config.SecurityConfig.PacketSignaturePolicy
|
||||
PACKET_SIGNATURE_POLICY_COMPATIBLE: Config.SecurityConfig.PacketSignaturePolicy
|
||||
PACKET_SIGNATURE_POLICY_FIELD_NUMBER: _ClassVar[int]
|
||||
PACKET_SIGNATURE_POLICY_STRICT: Config.SecurityConfig.PacketSignaturePolicy
|
||||
PRIVATE_KEY_FIELD_NUMBER: _ClassVar[int]
|
||||
PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int]
|
||||
SERIAL_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -379,11 +365,10 @@ class Config(_message.Message):
|
||||
admin_key: _containers.RepeatedScalarFieldContainer[bytes]
|
||||
debug_log_api_enabled: bool
|
||||
is_managed: bool
|
||||
packet_signature_policy: Config.SecurityConfig.PacketSignaturePolicy
|
||||
private_key: bytes
|
||||
public_key: bytes
|
||||
serial_enabled: bool
|
||||
def __init__(self, public_key: _Optional[bytes] = ..., private_key: _Optional[bytes] = ..., admin_key: _Optional[_Iterable[bytes]] = ..., is_managed: bool = ..., serial_enabled: bool = ..., debug_log_api_enabled: bool = ..., admin_channel_enabled: bool = ..., packet_signature_policy: _Optional[_Union[Config.SecurityConfig.PacketSignaturePolicy, str]] = ...) -> None: ...
|
||||
def __init__(self, public_key: _Optional[bytes] = ..., private_key: _Optional[bytes] = ..., admin_key: _Optional[_Iterable[bytes]] = ..., is_managed: bool = ..., serial_enabled: bool = ..., debug_log_api_enabled: bool = ..., admin_channel_enabled: bool = ...) -> None: ...
|
||||
class SessionkeyConfig(_message.Message):
|
||||
__slots__ = []
|
||||
def __init__(self) -> None: ...
|
||||
|
||||
@@ -13,7 +13,7 @@ _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*\xe0\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\r\n\tHUNGARIAN\x10\x14\x12\x0f\n\x0b\x41ZERBAIJANI\x10\x15\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')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.device_ui_pb2', globals())
|
||||
@@ -26,7 +26,7 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
_THEME._serialized_start=1342
|
||||
_THEME._serialized_end=1379
|
||||
_LANGUAGE._serialized_start=1382
|
||||
_LANGUAGE._serialized_end=1734
|
||||
_LANGUAGE._serialized_end=1702
|
||||
_DEVICEUICONFIG._serialized_start=61
|
||||
_DEVICEUICONFIG._serialized_end=828
|
||||
_DEVICEUICONFIG_GPSCOORDINATEFORMAT._serialized_start=742
|
||||
|
||||
@@ -3,7 +3,6 @@ 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
|
||||
|
||||
AZERBAIJANI: Language
|
||||
BULGARIAN: Language
|
||||
CZECH: Language
|
||||
DANISH: Language
|
||||
@@ -18,7 +17,6 @@ FREEZE_HEADING: CompassMode
|
||||
FRENCH: Language
|
||||
GERMAN: Language
|
||||
GREEK: Language
|
||||
HUNGARIAN: Language
|
||||
ITALIAN: Language
|
||||
LIGHT: Theme
|
||||
NORWEGIAN: Language
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/deviceonly_legacy.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 meshtastic.protobuf import deviceonly_pb2 as meshtastic_dot_protobuf_dot_deviceonly__pb2
|
||||
from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_telemetry__pb2
|
||||
from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n+meshtastic/protobuf/deviceonly_legacy.proto\x12\x13meshtastic.protobuf\x1a$meshtastic/protobuf/deviceonly.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/nanopb.proto\"\xf7\x02\n\x13NodeInfoLite_Legacy\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\"\x92\x01\n\x13NodeDatabase_Legacy\x12\x0f\n\x07version\x18\x01 \x01(\r\x12j\n\x05nodes\x18\x02 \x03(\x0b\x32(.meshtastic.protobuf.NodeInfoLite_LegacyB1\x92?.\x92\x01+std::vector<meshtastic_NodeInfoLite_Legacy>Bt\n\x14org.meshtastic.protoB\x10\x44\x65viceOnlyLegacyZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x92?\x0b\xc2\x01\x08<vector>b\x06proto3')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceonly_legacy_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020DeviceOnlyLegacyZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000\222?\013\302\001\010<vector>'
|
||||
_NODEDATABASE_LEGACY.fields_by_name['nodes']._options = None
|
||||
_NODEDATABASE_LEGACY.fields_by_name['nodes']._serialized_options = b'\222?.\222\001+std::vector<meshtastic_NodeInfoLite_Legacy>'
|
||||
_NODEINFOLITE_LEGACY._serialized_start=178
|
||||
_NODEINFOLITE_LEGACY._serialized_end=553
|
||||
_NODEDATABASE_LEGACY._serialized_start=556
|
||||
_NODEDATABASE_LEGACY._serialized_end=702
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,47 +0,0 @@
|
||||
from meshtastic.protobuf import deviceonly_pb2 as _deviceonly_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
|
||||
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class NodeDatabase_Legacy(_message.Message):
|
||||
__slots__ = ["nodes", "version"]
|
||||
NODES_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
nodes: _containers.RepeatedCompositeFieldContainer[NodeInfoLite_Legacy]
|
||||
version: int
|
||||
def __init__(self, version: _Optional[int] = ..., nodes: _Optional[_Iterable[_Union[NodeInfoLite_Legacy, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
class NodeInfoLite_Legacy(_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: _deviceonly_pb2.PositionLite
|
||||
snr: float
|
||||
user: _deviceonly_pb2.UserLite
|
||||
via_mqtt: bool
|
||||
def __init__(self, num: _Optional[int] = ..., user: _Optional[_Union[_deviceonly_pb2.UserLite, _Mapping]] = ..., position: _Optional[_Union[_deviceonly_pb2.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: ...
|
||||
@@ -19,7 +19,7 @@ from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_tel
|
||||
from meshtastic.protobuf import nanopb_pb2 as meshtastic_dot_protobuf_dot_nanopb__pb2
|
||||
|
||||
|
||||
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\"\xb1\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\x12\x16\n\x0eprecision_bits\x18\x06 \x01(\r\"\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\"\xbc\x03\n\x0cNodeInfoLite\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x0b\n\x03snr\x18\x04 \x01(\x02\x12\x12\n\nlast_heard\x18\x05 \x01(\x07\x12\x0f\n\x07\x63hannel\x18\x07 \x01(\r\x12\x16\n\thops_away\x18\t \x01(\rH\x00\x88\x01\x01\x12\x10\n\x08next_hop\x18\x0c \x01(\r\x12\x10\n\x08\x62itfield\x18\r \x01(\r\x12\x11\n\tlong_name\x18\x0e \x01(\t\x12\x12\n\nshort_name\x18\x0f \x01(\t\x12\x34\n\x08hw_model\x18\x10 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12;\n\x04role\x18\x11 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x12 \x01(\x0c\x12\x0e\n\x06snr_q4\x18\x13 \x01(\x11\x42\x0c\n\n_hops_awayJ\x04\x08\x02\x10\x03J\x04\x08\x03\x10\x04J\x04\x08\x06\x10\x07J\x04\x08\x08\x10\tJ\x04\x08\n\x10\x0bJ\x04\x08\x0b\x10\x0cR\x04userR\x08positionR\x0e\x64\x65vice_metricsR\x08via_mqttR\x0bis_favoriteR\nis_ignored\"\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\"U\n\x11NodePositionEntry\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x33\n\x08position\x18\x02 \x01(\x0b\x32!.meshtastic.protobuf.PositionLite\"]\n\x12NodeTelemetryEntry\x12\x0b\n\x03num\x18\x01 \x01(\r\x12:\n\x0e\x64\x65vice_metrics\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.DeviceMetrics\"i\n\x14NodeEnvironmentEntry\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x44\n\x13\x65nvironment_metrics\x18\x02 \x01(\x0b\x32\'.meshtastic.protobuf.EnvironmentMetrics\"R\n\x0fNodeStatusEntry\x12\x0b\n\x03num\x18\x01 \x01(\r\x12\x32\n\x06status\x18\x02 \x01(\x0b\x32\".meshtastic.protobuf.StatusMessage\"\xb0\x04\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>\x12j\n\tpositions\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.NodePositionEntryB/\x92?,\x92\x01)std::vector<meshtastic_NodePositionEntry>\x12l\n\ttelemetry\x18\x04 \x03(\x0b\x32\'.meshtastic.protobuf.NodeTelemetryEntryB0\x92?-\x92\x01*std::vector<meshtastic_NodeTelemetryEntry>\x12\x63\n\x06status\x18\x05 \x03(\x0b\x32$.meshtastic.protobuf.NodeStatusEntryB-\x92?*\x92\x01\'std::vector<meshtastic_NodeStatusEntry>\x12r\n\x0b\x65nvironment\x18\x06 \x03(\x0b\x32).meshtastic.protobuf.NodeEnvironmentEntryB2\x92?/\x92\x01,std::vector<meshtastic_NodeEnvironmentEntry>\"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')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.deviceonly_pb2', globals())
|
||||
@@ -35,34 +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>'
|
||||
_NODEDATABASE.fields_by_name['positions']._options = None
|
||||
_NODEDATABASE.fields_by_name['positions']._serialized_options = b'\222?,\222\001)std::vector<meshtastic_NodePositionEntry>'
|
||||
_NODEDATABASE.fields_by_name['telemetry']._options = None
|
||||
_NODEDATABASE.fields_by_name['telemetry']._serialized_options = b'\222?-\222\001*std::vector<meshtastic_NodeTelemetryEntry>'
|
||||
_NODEDATABASE.fields_by_name['status']._options = None
|
||||
_NODEDATABASE.fields_by_name['status']._serialized_options = b'\222?*\222\001\'std::vector<meshtastic_NodeStatusEntry>'
|
||||
_NODEDATABASE.fields_by_name['environment']._options = None
|
||||
_NODEDATABASE.fields_by_name['environment']._serialized_options = b'\222?/\222\001,std::vector<meshtastic_NodeEnvironmentEntry>'
|
||||
_POSITIONLITE._serialized_start=271
|
||||
_POSITIONLITE._serialized_end=448
|
||||
_USERLITE._serialized_start=451
|
||||
_USERLITE._serialized_end=727
|
||||
_NODEINFOLITE._serialized_start=730
|
||||
_NODEINFOLITE._serialized_end=1174
|
||||
_DEVICESTATE._serialized_start=1177
|
||||
_DEVICESTATE._serialized_end=1594
|
||||
_NODEPOSITIONENTRY._serialized_start=1596
|
||||
_NODEPOSITIONENTRY._serialized_end=1681
|
||||
_NODETELEMETRYENTRY._serialized_start=1683
|
||||
_NODETELEMETRYENTRY._serialized_end=1776
|
||||
_NODEENVIRONMENTENTRY._serialized_start=1778
|
||||
_NODEENVIRONMENTENTRY._serialized_end=1883
|
||||
_NODESTATUSENTRY._serialized_start=1885
|
||||
_NODESTATUSENTRY._serialized_end=1967
|
||||
_NODEDATABASE._serialized_start=1970
|
||||
_NODEDATABASE._serialized_end=2530
|
||||
_CHANNELFILE._serialized_start=2532
|
||||
_CHANNELFILE._serialized_end=2610
|
||||
_BACKUPPREFERENCES._serialized_start=2613
|
||||
_BACKUPPREFERENCES._serialized_end=2875
|
||||
_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)
|
||||
@@ -58,98 +58,56 @@ class DeviceState(_message.Message):
|
||||
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: ...
|
||||
|
||||
class NodeDatabase(_message.Message):
|
||||
__slots__ = ["environment", "nodes", "positions", "status", "telemetry", "version"]
|
||||
ENVIRONMENT_FIELD_NUMBER: _ClassVar[int]
|
||||
__slots__ = ["nodes", "version"]
|
||||
NODES_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITIONS_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
TELEMETRY_FIELD_NUMBER: _ClassVar[int]
|
||||
VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
environment: _containers.RepeatedCompositeFieldContainer[NodeEnvironmentEntry]
|
||||
nodes: _containers.RepeatedCompositeFieldContainer[NodeInfoLite]
|
||||
positions: _containers.RepeatedCompositeFieldContainer[NodePositionEntry]
|
||||
status: _containers.RepeatedCompositeFieldContainer[NodeStatusEntry]
|
||||
telemetry: _containers.RepeatedCompositeFieldContainer[NodeTelemetryEntry]
|
||||
version: int
|
||||
def __init__(self, version: _Optional[int] = ..., nodes: _Optional[_Iterable[_Union[NodeInfoLite, _Mapping]]] = ..., positions: _Optional[_Iterable[_Union[NodePositionEntry, _Mapping]]] = ..., telemetry: _Optional[_Iterable[_Union[NodeTelemetryEntry, _Mapping]]] = ..., status: _Optional[_Iterable[_Union[NodeStatusEntry, _Mapping]]] = ..., environment: _Optional[_Iterable[_Union[NodeEnvironmentEntry, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
class NodeEnvironmentEntry(_message.Message):
|
||||
__slots__ = ["environment_metrics", "num"]
|
||||
ENVIRONMENT_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
environment_metrics: _telemetry_pb2.EnvironmentMetrics
|
||||
num: int
|
||||
def __init__(self, num: _Optional[int] = ..., environment_metrics: _Optional[_Union[_telemetry_pb2.EnvironmentMetrics, _Mapping]] = ...) -> None: ...
|
||||
def __init__(self, version: _Optional[int] = ..., nodes: _Optional[_Iterable[_Union[NodeInfoLite, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
class NodeInfoLite(_message.Message):
|
||||
__slots__ = ["bitfield", "channel", "hops_away", "hw_model", "last_heard", "long_name", "next_hop", "num", "public_key", "role", "short_name", "snr", "snr_q4"]
|
||||
__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]
|
||||
HW_MODEL_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_FAVORITE_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_IGNORED_FIELD_NUMBER: _ClassVar[int]
|
||||
LAST_HEARD_FIELD_NUMBER: _ClassVar[int]
|
||||
LONG_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
NEXT_HOP_FIELD_NUMBER: _ClassVar[int]
|
||||
NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
PUBLIC_KEY_FIELD_NUMBER: _ClassVar[int]
|
||||
ROLE_FIELD_NUMBER: _ClassVar[int]
|
||||
SHORT_NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
SNR_FIELD_NUMBER: _ClassVar[int]
|
||||
SNR_Q4_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
|
||||
hw_model: _mesh_pb2.HardwareModel
|
||||
is_favorite: bool
|
||||
is_ignored: bool
|
||||
last_heard: int
|
||||
long_name: str
|
||||
next_hop: int
|
||||
num: int
|
||||
public_key: bytes
|
||||
role: _config_pb2.Config.DeviceConfig.Role
|
||||
short_name: str
|
||||
snr: float
|
||||
snr_q4: int
|
||||
def __init__(self, num: _Optional[int] = ..., snr: _Optional[float] = ..., last_heard: _Optional[int] = ..., channel: _Optional[int] = ..., hops_away: _Optional[int] = ..., next_hop: _Optional[int] = ..., bitfield: _Optional[int] = ..., long_name: _Optional[str] = ..., short_name: _Optional[str] = ..., hw_model: _Optional[_Union[_mesh_pb2.HardwareModel, str]] = ..., role: _Optional[_Union[_config_pb2.Config.DeviceConfig.Role, str]] = ..., public_key: _Optional[bytes] = ..., snr_q4: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class NodePositionEntry(_message.Message):
|
||||
__slots__ = ["num", "position"]
|
||||
NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
num: int
|
||||
position: PositionLite
|
||||
def __init__(self, num: _Optional[int] = ..., position: _Optional[_Union[PositionLite, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class NodeStatusEntry(_message.Message):
|
||||
__slots__ = ["num", "status"]
|
||||
NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
num: int
|
||||
status: _mesh_pb2.StatusMessage
|
||||
def __init__(self, num: _Optional[int] = ..., status: _Optional[_Union[_mesh_pb2.StatusMessage, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class NodeTelemetryEntry(_message.Message):
|
||||
__slots__ = ["device_metrics", "num"]
|
||||
DEVICE_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
NUM_FIELD_NUMBER: _ClassVar[int]
|
||||
device_metrics: _telemetry_pb2.DeviceMetrics
|
||||
num: int
|
||||
def __init__(self, num: _Optional[int] = ..., device_metrics: _Optional[_Union[_telemetry_pb2.DeviceMetrics, _Mapping]] = ...) -> None: ...
|
||||
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: ...
|
||||
|
||||
class PositionLite(_message.Message):
|
||||
__slots__ = ["altitude", "latitude_i", "location_source", "longitude_i", "precision_bits", "time"]
|
||||
__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]
|
||||
PRECISION_BITS_FIELD_NUMBER: _ClassVar[int]
|
||||
TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
altitude: int
|
||||
latitude_i: int
|
||||
location_source: _mesh_pb2.Position.LocSource
|
||||
longitude_i: int
|
||||
precision_bits: 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]] = ..., precision_bits: _Optional[int] = ...) -> None: ...
|
||||
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: ...
|
||||
|
||||
class UserLite(_message.Message):
|
||||
__slots__ = ["hw_model", "is_licensed", "is_unmessagable", "long_name", "macaddr", "public_key", "role", "short_name"]
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/field_metadata.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(meshtastic/protobuf/field_metadata.proto\x12\x13meshtastic.protobuf\x1a google/protobuf/descriptor.proto\"\xfc\x01\n\rFieldMetadata\x12\x10\n\x08\x64iy_only\x18\x01 \x01(\x08\x12\x12\n\nadmin_only\x18\x02 \x01(\x08\x12\x11\n\tmin_value\x18\x03 \x01(\x01\x12\x11\n\tmax_value\x18\x04 \x01(\x01\x12\x0c\n\x04unit\x18\x05 \x01(\t\x12\x12\n\ndeprecated\x18\x06 \x01(\x08\x12\r\n\x05label\x18\x07 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x08 \x01(\t\x12\x10\n\x08keywords\x18\t \x01(\t\x12\x16\n\x0esince_firmware\x18\n \x01(\t\x12\x18\n\x10\x64\x65precated_since\x18\x0b \x01(\t\x12\x15\n\roem_fixed_gps\x18\x0c \x01(\x08:[\n\x0e\x66ield_metadata\x12\x1d.google.protobuf.FieldOptions\x18\xb9\x8e\x03 \x01(\x0b\x32\".meshtastic.protobuf.FieldMetadata:d\n\x13\x65num_value_metadata\x12!.google.protobuf.EnumValueOptions\x18\xb9\x8e\x03 \x01(\x0b\x32\".meshtastic.protobuf.FieldMetadataBi\n\x14org.meshtastic.protoB\x13\x46ieldMetadataProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.field_metadata_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
google_dot_protobuf_dot_descriptor__pb2.FieldOptions.RegisterExtension(field_metadata)
|
||||
google_dot_protobuf_dot_descriptor__pb2.EnumValueOptions.RegisterExtension(enum_value_metadata)
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\023FieldMetadataProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_FIELDMETADATA._serialized_start=100
|
||||
_FIELDMETADATA._serialized_end=352
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,38 +0,0 @@
|
||||
from google.protobuf import descriptor_pb2 as _descriptor_pb2
|
||||
from google.protobuf import descriptor as _descriptor
|
||||
from google.protobuf import message as _message
|
||||
from typing import ClassVar as _ClassVar, Optional as _Optional
|
||||
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
ENUM_VALUE_METADATA_FIELD_NUMBER: _ClassVar[int]
|
||||
FIELD_METADATA_FIELD_NUMBER: _ClassVar[int]
|
||||
enum_value_metadata: _descriptor.FieldDescriptor
|
||||
field_metadata: _descriptor.FieldDescriptor
|
||||
|
||||
class FieldMetadata(_message.Message):
|
||||
__slots__ = ["admin_only", "deprecated", "deprecated_since", "description", "diy_only", "keywords", "label", "max_value", "min_value", "oem_fixed_gps", "since_firmware", "unit"]
|
||||
ADMIN_ONLY_FIELD_NUMBER: _ClassVar[int]
|
||||
DEPRECATED_FIELD_NUMBER: _ClassVar[int]
|
||||
DEPRECATED_SINCE_FIELD_NUMBER: _ClassVar[int]
|
||||
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
|
||||
DIY_ONLY_FIELD_NUMBER: _ClassVar[int]
|
||||
KEYWORDS_FIELD_NUMBER: _ClassVar[int]
|
||||
LABEL_FIELD_NUMBER: _ClassVar[int]
|
||||
MAX_VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
MIN_VALUE_FIELD_NUMBER: _ClassVar[int]
|
||||
OEM_FIXED_GPS_FIELD_NUMBER: _ClassVar[int]
|
||||
SINCE_FIRMWARE_FIELD_NUMBER: _ClassVar[int]
|
||||
UNIT_FIELD_NUMBER: _ClassVar[int]
|
||||
admin_only: bool
|
||||
deprecated: bool
|
||||
deprecated_since: str
|
||||
description: str
|
||||
diy_only: bool
|
||||
keywords: str
|
||||
label: str
|
||||
max_value: float
|
||||
min_value: float
|
||||
oem_fixed_gps: bool
|
||||
since_firmware: str
|
||||
unit: str
|
||||
def __init__(self, diy_only: bool = ..., admin_only: bool = ..., min_value: _Optional[float] = ..., max_value: _Optional[float] = ..., unit: _Optional[str] = ..., deprecated: bool = ..., label: _Optional[str] = ..., description: _Optional[str] = ..., keywords: _Optional[str] = ..., since_firmware: _Optional[str] = ..., deprecated_since: _Optional[str] = ..., oem_fixed_gps: bool = ...) -> None: ...
|
||||
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%meshtastic/protobuf/interdevice.proto\x12\x13meshtastic.protobuf\"\xde\x01\n\x0c\x46ileTransfer\x12\x35\n\toperation\x18\x01 \x01(\x0e\x32\".meshtastic.protobuf.FileOperation\x12\x10\n\x08\x66ilepath\x18\x02 \x01(\t\x12\x10\n\x08\x66iledata\x18\x03 \x01(\x0c\x12/\n\x06status\x18\x04 \x01(\x0e\x32\x1f.meshtastic.protobuf.FileStatus\x12\x0f\n\x07message\x18\x05 \x01(\t\x12\x0e\n\x06offset\x18\x06 \x01(\x04\x12\x0e\n\x06length\x18\x07 \x01(\r\x12\x11\n\tfile_size\x18\x08 \x01(\x04\"\x9f\x01\n\x10\x44irectoryListing\x12\x11\n\tdirectory\x18\x01 \x01(\t\x12\x11\n\tfilenames\x18\x02 \x03(\t\x12/\n\x06status\x18\x03 \x01(\x0e\x32\x1f.meshtastic.protobuf.FileStatus\x12\x0f\n\x07message\x18\x04 \x01(\t\x12\x0e\n\x06offset\x18\x05 \x01(\r\x12\x13\n\x0btotal_count\x18\x06 \x01(\r\"G\n\x0eI2CTransaction\x12\x0f\n\x07\x61\x64\x64ress\x18\x01 \x01(\r\x12\x12\n\nwrite_data\x18\x02 \x01(\x0c\x12\x10\n\x08read_len\x18\x03 \x01(\r\"\x92\x03\n\nSdCardInfo\x12\x0f\n\x07present\x18\x01 \x01(\x08\x12;\n\tcard_type\x18\x02 \x01(\x0e\x32(.meshtastic.protobuf.SdCardInfo.CardType\x12\x39\n\x08\x66\x61t_type\x18\x03 \x01(\x0e\x32\'.meshtastic.protobuf.SdCardInfo.FatType\x12\x11\n\tcard_size\x18\x04 \x01(\x04\x12\x12\n\nused_bytes\x18\x05 \x01(\x04\x12\x12\n\nfree_bytes\x18\x06 \x01(\x04\x12\x13\n\x0bstats_valid\x18\x07 \x01(\x08\x12\x0c\n\x04\x62usy\x18\x08 \x01(\x08\x12\x13\n\x0bunformatted\x18\t \x01(\x08\"K\n\x08\x43\x61rdType\x12\x08\n\x04NONE\x10\x00\x12\x07\n\x03MMC\x10\x01\x12\x06\n\x02SD\x10\x02\x12\x08\n\x04SDHC\x10\x03\x12\x08\n\x04SDXC\x10\x04\x12\x10\n\x0cUNKNOWN_CARD\x10\x05\";\n\x07\x46\x61tType\x12\x0f\n\x0bUNKNOWN_FAT\x10\x00\x12\t\n\x05\x46\x41T16\x10\x01\x12\t\n\x05\x46\x41T32\x10\x02\x12\t\n\x05\x45XFAT\x10\x03\"\xa4\x01\n\tI2CResult\x12\x35\n\x06status\x18\x01 \x01(\x0e\x32%.meshtastic.protobuf.I2CResult.Status\x12\x11\n\tread_data\x18\x02 \x01(\x0c\"M\n\x06Status\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x06\n\x02OK\x10\x01\x12\x10\n\x0cNACK_ADDRESS\x10\x02\x12\r\n\tNACK_DATA\x10\x03\x12\t\n\x05\x45RROR\x10\x04\"\xf0\x04\n\x12InterdeviceMessage\x12\n\n\x02id\x18\x0f \x01(\r\x12\x0e\n\x04nmea\x18\x01 \x01(\tH\x00\x12\x0e\n\x04\x62\x65\x65p\x18\x02 \x01(\rH\x00\x12>\n\x0fi2c_transaction\x18\x03 \x01(\x0b\x32#.meshtastic.protobuf.I2CTransactionH\x00\x12\x34\n\ni2c_result\x18\x04 \x01(\x0b\x32\x1e.meshtastic.protobuf.I2CResultH\x00\x12\x12\n\x08i2c_scan\x18\x05 \x01(\x08H\x00\x12\x19\n\x0fi2c_scan_result\x18\x06 \x01(\x0cH\x00\x12:\n\rfile_transfer\x18\x07 \x01(\x0b\x32!.meshtastic.protobuf.FileTransferH\x00\x12\x42\n\x11\x64irectory_listing\x18\x08 \x01(\x0b\x32%.meshtastic.protobuf.DirectoryListingH\x00\x12\x15\n\x0bget_sd_info\x18\t \x01(\x08H\x00\x12\x32\n\x07sd_info\x18\n \x01(\x0b\x32\x1f.meshtastic.protobuf.SdCardInfoH\x00\x12\x37\n\x04ping\x18\x0b \x01(\x0e\x32\'.meshtastic.protobuf.InterdeviceVersionH\x00\x12\x37\n\x04pong\x18\x0c \x01(\x0e\x32\'.meshtastic.protobuf.InterdeviceVersionH\x00\x12\x0e\n\x04nack\x18\r \x01(\x08H\x00\x12\x34\n\nsd_command\x18\x0e \x01(\x0e\x32\x1e.meshtastic.protobuf.SdCommandH\x00\x42\x06\n\x04\x64\x61ta*Z\n\x12InterdeviceVersion\x12#\n\x1fINTERDEVICE_VERSION_UNSPECIFIED\x10\x00\x12\x1f\n\x1bINTERDEVICE_VERSION_CURRENT\x10\x02*7\n\rFileOperation\x12\x07\n\x03GET\x10\x00\x12\x08\n\x04POST\x10\x01\x12\x07\n\x03PUT\x10\x02\x12\n\n\x06\x44\x45LETE\x10\x03*\xa6\x01\n\nFileStatus\x12\x14\n\x10\x46ILE_UNSPECIFIED\x10\x00\x12\x0b\n\x07\x46ILE_OK\x10\x01\x12\r\n\tFILE_BUSY\x10\x02\x12\x10\n\x0c\x46ILE_NO_CARD\x10\x03\x12\x12\n\x0e\x46ILE_NOT_FOUND\x10\x04\x12\x18\n\x14\x46ILE_OFFSET_CONFLICT\x10\x05\x12\x11\n\rFILE_IO_ERROR\x10\x06\x12\x13\n\x0f\x46ILE_NOT_A_FILE\x10\x07*R\n\tSdCommand\x12\x1a\n\x16SD_COMMAND_UNSPECIFIED\x10\x00\x12\x0c\n\x08SD_MOUNT\x10\x01\x12\x0c\n\x08SD_EJECT\x10\x02\x12\r\n\tSD_FORMAT\x10\x03\x42g\n\x14org.meshtastic.protoB\x11InterdeviceProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.interdevice_pb2', globals())
|
||||
@@ -21,30 +21,10 @@ 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'
|
||||
_INTERDEVICEVERSION._serialized_start=1721
|
||||
_INTERDEVICEVERSION._serialized_end=1811
|
||||
_FILEOPERATION._serialized_start=1813
|
||||
_FILEOPERATION._serialized_end=1868
|
||||
_FILESTATUS._serialized_start=1871
|
||||
_FILESTATUS._serialized_end=2037
|
||||
_SDCOMMAND._serialized_start=2039
|
||||
_SDCOMMAND._serialized_end=2121
|
||||
_FILETRANSFER._serialized_start=63
|
||||
_FILETRANSFER._serialized_end=285
|
||||
_DIRECTORYLISTING._serialized_start=288
|
||||
_DIRECTORYLISTING._serialized_end=447
|
||||
_I2CTRANSACTION._serialized_start=449
|
||||
_I2CTRANSACTION._serialized_end=520
|
||||
_SDCARDINFO._serialized_start=523
|
||||
_SDCARDINFO._serialized_end=925
|
||||
_SDCARDINFO_CARDTYPE._serialized_start=789
|
||||
_SDCARDINFO_CARDTYPE._serialized_end=864
|
||||
_SDCARDINFO_FATTYPE._serialized_start=866
|
||||
_SDCARDINFO_FATTYPE._serialized_end=925
|
||||
_I2CRESULT._serialized_start=928
|
||||
_I2CRESULT._serialized_end=1092
|
||||
_I2CRESULT_STATUS._serialized_start=1015
|
||||
_I2CRESULT_STATUS._serialized_end=1092
|
||||
_INTERDEVICEMESSAGE._serialized_start=1095
|
||||
_INTERDEVICEMESSAGE._serialized_end=1719
|
||||
_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,168 +1,39 @@
|
||||
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, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union
|
||||
|
||||
DELETE: FileOperation
|
||||
ACK: MessageType
|
||||
AHT20_HUMIDITY: MessageType
|
||||
AHT20_TEMP: MessageType
|
||||
BEEP_OFF: MessageType
|
||||
BEEP_ON: MessageType
|
||||
COLLECT_INTERVAL: MessageType
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
FILE_BUSY: FileStatus
|
||||
FILE_IO_ERROR: FileStatus
|
||||
FILE_NOT_A_FILE: FileStatus
|
||||
FILE_NOT_FOUND: FileStatus
|
||||
FILE_NO_CARD: FileStatus
|
||||
FILE_OFFSET_CONFLICT: FileStatus
|
||||
FILE_OK: FileStatus
|
||||
FILE_UNSPECIFIED: FileStatus
|
||||
GET: FileOperation
|
||||
INTERDEVICE_VERSION_CURRENT: InterdeviceVersion
|
||||
INTERDEVICE_VERSION_UNSPECIFIED: InterdeviceVersion
|
||||
POST: FileOperation
|
||||
PUT: FileOperation
|
||||
SD_COMMAND_UNSPECIFIED: SdCommand
|
||||
SD_EJECT: SdCommand
|
||||
SD_FORMAT: SdCommand
|
||||
SD_MOUNT: SdCommand
|
||||
|
||||
class DirectoryListing(_message.Message):
|
||||
__slots__ = ["directory", "filenames", "message", "offset", "status", "total_count"]
|
||||
DIRECTORY_FIELD_NUMBER: _ClassVar[int]
|
||||
FILENAMES_FIELD_NUMBER: _ClassVar[int]
|
||||
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFSET_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
TOTAL_COUNT_FIELD_NUMBER: _ClassVar[int]
|
||||
directory: str
|
||||
filenames: _containers.RepeatedScalarFieldContainer[str]
|
||||
message: str
|
||||
offset: int
|
||||
status: FileStatus
|
||||
total_count: int
|
||||
def __init__(self, directory: _Optional[str] = ..., filenames: _Optional[_Iterable[str]] = ..., status: _Optional[_Union[FileStatus, str]] = ..., message: _Optional[str] = ..., offset: _Optional[int] = ..., total_count: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class FileTransfer(_message.Message):
|
||||
__slots__ = ["file_size", "filedata", "filepath", "length", "message", "offset", "operation", "status"]
|
||||
FILEDATA_FIELD_NUMBER: _ClassVar[int]
|
||||
FILEPATH_FIELD_NUMBER: _ClassVar[int]
|
||||
FILE_SIZE_FIELD_NUMBER: _ClassVar[int]
|
||||
LENGTH_FIELD_NUMBER: _ClassVar[int]
|
||||
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFSET_FIELD_NUMBER: _ClassVar[int]
|
||||
OPERATION_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
file_size: int
|
||||
filedata: bytes
|
||||
filepath: str
|
||||
length: int
|
||||
message: str
|
||||
offset: int
|
||||
operation: FileOperation
|
||||
status: FileStatus
|
||||
def __init__(self, operation: _Optional[_Union[FileOperation, str]] = ..., filepath: _Optional[str] = ..., filedata: _Optional[bytes] = ..., status: _Optional[_Union[FileStatus, str]] = ..., message: _Optional[str] = ..., offset: _Optional[int] = ..., length: _Optional[int] = ..., file_size: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class I2CResult(_message.Message):
|
||||
__slots__ = ["read_data", "status"]
|
||||
class Status(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
ERROR: I2CResult.Status
|
||||
NACK_ADDRESS: I2CResult.Status
|
||||
NACK_DATA: I2CResult.Status
|
||||
OK: I2CResult.Status
|
||||
READ_DATA_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
UNSPECIFIED: I2CResult.Status
|
||||
read_data: bytes
|
||||
status: I2CResult.Status
|
||||
def __init__(self, status: _Optional[_Union[I2CResult.Status, str]] = ..., read_data: _Optional[bytes] = ...) -> None: ...
|
||||
|
||||
class I2CTransaction(_message.Message):
|
||||
__slots__ = ["address", "read_len", "write_data"]
|
||||
ADDRESS_FIELD_NUMBER: _ClassVar[int]
|
||||
READ_LEN_FIELD_NUMBER: _ClassVar[int]
|
||||
WRITE_DATA_FIELD_NUMBER: _ClassVar[int]
|
||||
address: int
|
||||
read_len: int
|
||||
write_data: bytes
|
||||
def __init__(self, address: _Optional[int] = ..., write_data: _Optional[bytes] = ..., read_len: _Optional[int] = ...) -> None: ...
|
||||
POWER_ON: MessageType
|
||||
SCD41_CO2: MessageType
|
||||
SCD41_HUMIDITY: MessageType
|
||||
SCD41_TEMP: MessageType
|
||||
SHUTDOWN: MessageType
|
||||
TVOC_INDEX: MessageType
|
||||
|
||||
class InterdeviceMessage(_message.Message):
|
||||
__slots__ = ["beep", "directory_listing", "file_transfer", "get_sd_info", "i2c_result", "i2c_scan", "i2c_scan_result", "i2c_transaction", "id", "nack", "nmea", "ping", "pong", "sd_command", "sd_info"]
|
||||
BEEP_FIELD_NUMBER: _ClassVar[int]
|
||||
DIRECTORY_LISTING_FIELD_NUMBER: _ClassVar[int]
|
||||
FILE_TRANSFER_FIELD_NUMBER: _ClassVar[int]
|
||||
GET_SD_INFO_FIELD_NUMBER: _ClassVar[int]
|
||||
I2C_RESULT_FIELD_NUMBER: _ClassVar[int]
|
||||
I2C_SCAN_FIELD_NUMBER: _ClassVar[int]
|
||||
I2C_SCAN_RESULT_FIELD_NUMBER: _ClassVar[int]
|
||||
I2C_TRANSACTION_FIELD_NUMBER: _ClassVar[int]
|
||||
ID_FIELD_NUMBER: _ClassVar[int]
|
||||
NACK_FIELD_NUMBER: _ClassVar[int]
|
||||
__slots__ = ["nmea", "sensor"]
|
||||
NMEA_FIELD_NUMBER: _ClassVar[int]
|
||||
PING_FIELD_NUMBER: _ClassVar[int]
|
||||
PONG_FIELD_NUMBER: _ClassVar[int]
|
||||
SD_COMMAND_FIELD_NUMBER: _ClassVar[int]
|
||||
SD_INFO_FIELD_NUMBER: _ClassVar[int]
|
||||
beep: int
|
||||
directory_listing: DirectoryListing
|
||||
file_transfer: FileTransfer
|
||||
get_sd_info: bool
|
||||
i2c_result: I2CResult
|
||||
i2c_scan: bool
|
||||
i2c_scan_result: bytes
|
||||
i2c_transaction: I2CTransaction
|
||||
id: int
|
||||
nack: bool
|
||||
SENSOR_FIELD_NUMBER: _ClassVar[int]
|
||||
nmea: str
|
||||
ping: InterdeviceVersion
|
||||
pong: InterdeviceVersion
|
||||
sd_command: SdCommand
|
||||
sd_info: SdCardInfo
|
||||
def __init__(self, id: _Optional[int] = ..., nmea: _Optional[str] = ..., beep: _Optional[int] = ..., i2c_transaction: _Optional[_Union[I2CTransaction, _Mapping]] = ..., i2c_result: _Optional[_Union[I2CResult, _Mapping]] = ..., i2c_scan: bool = ..., i2c_scan_result: _Optional[bytes] = ..., file_transfer: _Optional[_Union[FileTransfer, _Mapping]] = ..., directory_listing: _Optional[_Union[DirectoryListing, _Mapping]] = ..., get_sd_info: bool = ..., sd_info: _Optional[_Union[SdCardInfo, _Mapping]] = ..., ping: _Optional[_Union[InterdeviceVersion, str]] = ..., pong: _Optional[_Union[InterdeviceVersion, str]] = ..., nack: bool = ..., sd_command: _Optional[_Union[SdCommand, str]] = ...) -> None: ...
|
||||
sensor: SensorData
|
||||
def __init__(self, nmea: _Optional[str] = ..., sensor: _Optional[_Union[SensorData, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class SdCardInfo(_message.Message):
|
||||
__slots__ = ["busy", "card_size", "card_type", "fat_type", "free_bytes", "present", "stats_valid", "unformatted", "used_bytes"]
|
||||
class CardType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class FatType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
BUSY_FIELD_NUMBER: _ClassVar[int]
|
||||
CARD_SIZE_FIELD_NUMBER: _ClassVar[int]
|
||||
CARD_TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
EXFAT: SdCardInfo.FatType
|
||||
FAT16: SdCardInfo.FatType
|
||||
FAT32: SdCardInfo.FatType
|
||||
FAT_TYPE_FIELD_NUMBER: _ClassVar[int]
|
||||
FREE_BYTES_FIELD_NUMBER: _ClassVar[int]
|
||||
MMC: SdCardInfo.CardType
|
||||
NONE: SdCardInfo.CardType
|
||||
PRESENT_FIELD_NUMBER: _ClassVar[int]
|
||||
SD: SdCardInfo.CardType
|
||||
SDHC: SdCardInfo.CardType
|
||||
SDXC: SdCardInfo.CardType
|
||||
STATS_VALID_FIELD_NUMBER: _ClassVar[int]
|
||||
UNFORMATTED_FIELD_NUMBER: _ClassVar[int]
|
||||
UNKNOWN_CARD: SdCardInfo.CardType
|
||||
UNKNOWN_FAT: SdCardInfo.FatType
|
||||
USED_BYTES_FIELD_NUMBER: _ClassVar[int]
|
||||
busy: bool
|
||||
card_size: int
|
||||
card_type: SdCardInfo.CardType
|
||||
fat_type: SdCardInfo.FatType
|
||||
free_bytes: int
|
||||
present: bool
|
||||
stats_valid: bool
|
||||
unformatted: bool
|
||||
used_bytes: int
|
||||
def __init__(self, present: bool = ..., card_type: _Optional[_Union[SdCardInfo.CardType, str]] = ..., fat_type: _Optional[_Union[SdCardInfo.FatType, str]] = ..., card_size: _Optional[int] = ..., used_bytes: _Optional[int] = ..., free_bytes: _Optional[int] = ..., stats_valid: bool = ..., busy: bool = ..., unformatted: bool = ...) -> None: ...
|
||||
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 InterdeviceVersion(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class FileOperation(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class FileStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
|
||||
class SdCommand(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
class MessageType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
@@ -15,7 +15,7 @@ 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\"\x98\n\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\x12G\n\x0bmesh_beacon\x18\x12 \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.MeshBeaconConfig\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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.localonly_pb2', globals())
|
||||
@@ -26,5 +26,5 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
_LOCALCONFIG._serialized_start=136
|
||||
_LOCALCONFIG._serialized_end=642
|
||||
_LOCALMODULECONFIG._serialized_start=645
|
||||
_LOCALMODULECONFIG._serialized_end=1949
|
||||
_LOCALMODULECONFIG._serialized_end=1876
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -29,13 +29,12 @@ class LocalConfig(_message.Message):
|
||||
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: ...
|
||||
|
||||
class LocalModuleConfig(_message.Message):
|
||||
__slots__ = ["ambient_lighting", "audio", "canned_message", "detection_sensor", "external_notification", "mesh_beacon", "mqtt", "neighbor_info", "paxcounter", "range_test", "remote_hardware", "serial", "statusmessage", "store_forward", "tak", "telemetry", "traffic_management", "version"]
|
||||
__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]
|
||||
MESH_BEACON_FIELD_NUMBER: _ClassVar[int]
|
||||
MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
NEIGHBOR_INFO_FIELD_NUMBER: _ClassVar[int]
|
||||
PAXCOUNTER_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -53,7 +52,6 @@ class LocalModuleConfig(_message.Message):
|
||||
canned_message: _module_config_pb2.ModuleConfig.CannedMessageConfig
|
||||
detection_sensor: _module_config_pb2.ModuleConfig.DetectionSensorConfig
|
||||
external_notification: _module_config_pb2.ModuleConfig.ExternalNotificationConfig
|
||||
mesh_beacon: _module_config_pb2.ModuleConfig.MeshBeaconConfig
|
||||
mqtt: _module_config_pb2.ModuleConfig.MQTTConfig
|
||||
neighbor_info: _module_config_pb2.ModuleConfig.NeighborInfoConfig
|
||||
paxcounter: _module_config_pb2.ModuleConfig.PaxcounterConfig
|
||||
@@ -66,4 +64,4 @@ class LocalModuleConfig(_message.Message):
|
||||
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]] = ..., mesh_beacon: _Optional[_Union[_module_config_pb2.ModuleConfig.MeshBeaconConfig, _Mapping]] = ..., version: _Optional[int] = ...) -> None: ...
|
||||
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: ...
|
||||
@@ -1,36 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/lorawan_bridge.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/lorawan_bridge.proto\x12\x13meshtastic.protobuf\"\xa9\x08\n\rLoRaWANBridge\x12;\n\x06uplink\x18\x01 \x01(\x0b\x32).meshtastic.protobuf.LoRaWANBridge.UplinkH\x00\x12?\n\x08\x64ownlink\x18\x02 \x01(\x0b\x32+.meshtastic.protobuf.LoRaWANBridge.DownlinkH\x00\x12@\n\ttx_result\x18\x03 \x01(\x0b\x32+.meshtastic.protobuf.LoRaWANBridge.TxResultH\x00\x12@\n\x05\x63hunk\x18\x04 \x01(\x0b\x32/.meshtastic.protobuf.LoRaWANBridge.PayloadChunkH\x00\x1a\xaf\x01\n\x06Uplink\x12\x0f\n\x07\x66req_hz\x18\x01 \x01(\x07\x12\x0c\n\x04tmst\x18\x02 \x01(\x07\x12\x10\n\x08rssi_x10\x18\x03 \x01(\x11\x12\x0f\n\x07snr_x10\x18\x04 \x01(\x11\x12\x14\n\x0cradio_params\x18\x05 \x01(\r\x12\x13\n\x0b\x66sk_bitrate\x18\t \x01(\r\x12\x0f\n\x07payload\x18\x06 \x01(\x0c\x12\x12\n\npayload_id\x18\x07 \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x08 \x01(\r\x1a\xef\x01\n\x08\x44ownlink\x12\x0f\n\x07\x66req_hz\x18\x01 \x01(\x07\x12\x0c\n\x04tmst\x18\x02 \x01(\x07\x12\x14\n\x0cradio_params\x18\x03 \x01(\r\x12\x11\n\tpower_dbm\x18\x04 \x01(\r\x12\x11\n\timmediate\x18\x05 \x01(\x08\x12\x17\n\x0finvert_polarity\x18\x06 \x01(\x08\x12\x0e\n\x06no_crc\x18\x07 \x01(\x08\x12\x11\n\tmay_defer\x18\x08 \x01(\x08\x12\x12\n\nrequest_id\x18\x0c \x01(\r\x12\x0f\n\x07payload\x18\t \x01(\x0c\x12\x12\n\npayload_id\x18\n \x01(\r\x12\x13\n\x0b\x63hunk_count\x18\x0b \x01(\r\x1aN\n\x0cPayloadChunk\x12\x12\n\npayload_id\x18\x01 \x01(\r\x12\x13\n\x0b\x63hunk_index\x18\x02 \x01(\r\x12\x15\n\rpayload_chunk\x18\x03 \x01(\x0c\x1a\x96\x02\n\x08TxResult\x12\x0c\n\x04tmst\x18\x01 \x01(\x07\x12\x42\n\x06status\x18\x02 \x01(\x0e\x32\x32.meshtastic.protobuf.LoRaWANBridge.TxResult.Status\x12\x12\n\nrequest_id\x18\x03 \x01(\r\"\xa3\x01\n\x06Status\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08TOO_LATE\x10\x01\x12\r\n\tTOO_EARLY\x10\x02\x12\x14\n\x10\x43OLLISION_PACKET\x10\x03\x12\x14\n\x10\x43OLLISION_BEACON\x10\x04\x12\x0b\n\x07TX_FREQ\x10\x05\x12\x0c\n\x08TX_POWER\x10\x06\x12\x10\n\x0cGPS_UNLOCKED\x10\x07\x12\x0c\n\x08\x44\x45\x46\x45RRED\x10\x08\x12\x0b\n\x07\x44ROPPED\x10\tB\t\n\x07variantBi\n\x14org.meshtastic.protoB\x13LoRaWANBridgeProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.lorawan_bridge_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\023LoRaWANBridgeProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_LORAWANBRIDGE._serialized_start=66
|
||||
_LORAWANBRIDGE._serialized_end=1131
|
||||
_LORAWANBRIDGE_UPLINK._serialized_start=342
|
||||
_LORAWANBRIDGE_UPLINK._serialized_end=517
|
||||
_LORAWANBRIDGE_DOWNLINK._serialized_start=520
|
||||
_LORAWANBRIDGE_DOWNLINK._serialized_end=759
|
||||
_LORAWANBRIDGE_PAYLOADCHUNK._serialized_start=761
|
||||
_LORAWANBRIDGE_PAYLOADCHUNK._serialized_end=839
|
||||
_LORAWANBRIDGE_TXRESULT._serialized_start=842
|
||||
_LORAWANBRIDGE_TXRESULT._serialized_end=1120
|
||||
_LORAWANBRIDGE_TXRESULT_STATUS._serialized_start=957
|
||||
_LORAWANBRIDGE_TXRESULT_STATUS._serialized_end=1120
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,96 +0,0 @@
|
||||
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
|
||||
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class LoRaWANBridge(_message.Message):
|
||||
__slots__ = ["chunk", "downlink", "tx_result", "uplink"]
|
||||
class Downlink(_message.Message):
|
||||
__slots__ = ["chunk_count", "freq_hz", "immediate", "invert_polarity", "may_defer", "no_crc", "payload", "payload_id", "power_dbm", "radio_params", "request_id", "tmst"]
|
||||
CHUNK_COUNT_FIELD_NUMBER: _ClassVar[int]
|
||||
FREQ_HZ_FIELD_NUMBER: _ClassVar[int]
|
||||
IMMEDIATE_FIELD_NUMBER: _ClassVar[int]
|
||||
INVERT_POLARITY_FIELD_NUMBER: _ClassVar[int]
|
||||
MAY_DEFER_FIELD_NUMBER: _ClassVar[int]
|
||||
NO_CRC_FIELD_NUMBER: _ClassVar[int]
|
||||
PAYLOAD_FIELD_NUMBER: _ClassVar[int]
|
||||
PAYLOAD_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
POWER_DBM_FIELD_NUMBER: _ClassVar[int]
|
||||
RADIO_PARAMS_FIELD_NUMBER: _ClassVar[int]
|
||||
REQUEST_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
TMST_FIELD_NUMBER: _ClassVar[int]
|
||||
chunk_count: int
|
||||
freq_hz: int
|
||||
immediate: bool
|
||||
invert_polarity: bool
|
||||
may_defer: bool
|
||||
no_crc: bool
|
||||
payload: bytes
|
||||
payload_id: int
|
||||
power_dbm: int
|
||||
radio_params: int
|
||||
request_id: int
|
||||
tmst: int
|
||||
def __init__(self, freq_hz: _Optional[int] = ..., tmst: _Optional[int] = ..., radio_params: _Optional[int] = ..., power_dbm: _Optional[int] = ..., immediate: bool = ..., invert_polarity: bool = ..., no_crc: bool = ..., may_defer: bool = ..., request_id: _Optional[int] = ..., payload: _Optional[bytes] = ..., payload_id: _Optional[int] = ..., chunk_count: _Optional[int] = ...) -> None: ...
|
||||
class PayloadChunk(_message.Message):
|
||||
__slots__ = ["chunk_index", "payload_chunk", "payload_id"]
|
||||
CHUNK_INDEX_FIELD_NUMBER: _ClassVar[int]
|
||||
PAYLOAD_CHUNK_FIELD_NUMBER: _ClassVar[int]
|
||||
PAYLOAD_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
chunk_index: int
|
||||
payload_chunk: bytes
|
||||
payload_id: int
|
||||
def __init__(self, payload_id: _Optional[int] = ..., chunk_index: _Optional[int] = ..., payload_chunk: _Optional[bytes] = ...) -> None: ...
|
||||
class TxResult(_message.Message):
|
||||
__slots__ = ["request_id", "status", "tmst"]
|
||||
class Status(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
COLLISION_BEACON: LoRaWANBridge.TxResult.Status
|
||||
COLLISION_PACKET: LoRaWANBridge.TxResult.Status
|
||||
DEFERRED: LoRaWANBridge.TxResult.Status
|
||||
DROPPED: LoRaWANBridge.TxResult.Status
|
||||
GPS_UNLOCKED: LoRaWANBridge.TxResult.Status
|
||||
NONE: LoRaWANBridge.TxResult.Status
|
||||
REQUEST_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
TMST_FIELD_NUMBER: _ClassVar[int]
|
||||
TOO_EARLY: LoRaWANBridge.TxResult.Status
|
||||
TOO_LATE: LoRaWANBridge.TxResult.Status
|
||||
TX_FREQ: LoRaWANBridge.TxResult.Status
|
||||
TX_POWER: LoRaWANBridge.TxResult.Status
|
||||
request_id: int
|
||||
status: LoRaWANBridge.TxResult.Status
|
||||
tmst: int
|
||||
def __init__(self, tmst: _Optional[int] = ..., status: _Optional[_Union[LoRaWANBridge.TxResult.Status, str]] = ..., request_id: _Optional[int] = ...) -> None: ...
|
||||
class Uplink(_message.Message):
|
||||
__slots__ = ["chunk_count", "freq_hz", "fsk_bitrate", "payload", "payload_id", "radio_params", "rssi_x10", "snr_x10", "tmst"]
|
||||
CHUNK_COUNT_FIELD_NUMBER: _ClassVar[int]
|
||||
FREQ_HZ_FIELD_NUMBER: _ClassVar[int]
|
||||
FSK_BITRATE_FIELD_NUMBER: _ClassVar[int]
|
||||
PAYLOAD_FIELD_NUMBER: _ClassVar[int]
|
||||
PAYLOAD_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
RADIO_PARAMS_FIELD_NUMBER: _ClassVar[int]
|
||||
RSSI_X10_FIELD_NUMBER: _ClassVar[int]
|
||||
SNR_X10_FIELD_NUMBER: _ClassVar[int]
|
||||
TMST_FIELD_NUMBER: _ClassVar[int]
|
||||
chunk_count: int
|
||||
freq_hz: int
|
||||
fsk_bitrate: int
|
||||
payload: bytes
|
||||
payload_id: int
|
||||
radio_params: int
|
||||
rssi_x10: int
|
||||
snr_x10: int
|
||||
tmst: int
|
||||
def __init__(self, freq_hz: _Optional[int] = ..., tmst: _Optional[int] = ..., rssi_x10: _Optional[int] = ..., snr_x10: _Optional[int] = ..., radio_params: _Optional[int] = ..., fsk_bitrate: _Optional[int] = ..., payload: _Optional[bytes] = ..., payload_id: _Optional[int] = ..., chunk_count: _Optional[int] = ...) -> None: ...
|
||||
CHUNK_FIELD_NUMBER: _ClassVar[int]
|
||||
DOWNLINK_FIELD_NUMBER: _ClassVar[int]
|
||||
TX_RESULT_FIELD_NUMBER: _ClassVar[int]
|
||||
UPLINK_FIELD_NUMBER: _ClassVar[int]
|
||||
chunk: LoRaWANBridge.PayloadChunk
|
||||
downlink: LoRaWANBridge.Downlink
|
||||
tx_result: LoRaWANBridge.TxResult
|
||||
uplink: LoRaWANBridge.Uplink
|
||||
def __init__(self, uplink: _Optional[_Union[LoRaWANBridge.Uplink, _Mapping]] = ..., downlink: _Optional[_Union[LoRaWANBridge.Downlink, _Mapping]] = ..., tx_result: _Optional[_Union[LoRaWANBridge.TxResult, _Mapping]] = ..., chunk: _Optional[_Union[LoRaWANBridge.PayloadChunk, _Mapping]] = ...) -> None: ...
|
||||
@@ -1,28 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||
# source: meshtastic/protobuf/mesh_beacon.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 meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_channel__pb2
|
||||
from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%meshtastic/protobuf/mesh_beacon.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\"\xbf\x02\n\nMeshBeacon\x12\x0f\n\x07message\x18\x01 \x01(\t\x12;\n\roffer_channel\x18\x02 \x01(\x0b\x32$.meshtastic.protobuf.ChannelSettings\x12G\n\x0coffer_region\x18\x03 \x01(\x0e\x32\x31.meshtastic.protobuf.Config.LoRaConfig.RegionCode\x12M\n\x0coffer_preset\x18\x04 \x01(\x0e\x32\x32.meshtastic.protobuf.Config.LoRaConfig.ModemPresetH\x00\x88\x01\x01\x12!\n\x14offer_frequency_slot\x18\x05 \x01(\rH\x01\x88\x01\x01\x42\x0f\n\r_offer_presetB\x17\n\x15_offer_frequency_slotBf\n\x14org.meshtastic.protoB\x10MeshBeaconProtosZ\"github.com/meshtastic/go/generated\xaa\x02\x14Meshtastic.Protobufs\xba\x02\x00\x62\x06proto3')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mesh_beacon_pb2', globals())
|
||||
if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\020MeshBeaconProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_MESHBEACON._serialized_start=132
|
||||
_MESHBEACON._serialized_end=451
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,21 +0,0 @@
|
||||
from meshtastic.protobuf import channel_pb2 as _channel_pb2
|
||||
from meshtastic.protobuf import config_pb2 as _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
|
||||
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class MeshBeacon(_message.Message):
|
||||
__slots__ = ["message", "offer_channel", "offer_frequency_slot", "offer_preset", "offer_region"]
|
||||
MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFER_CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFER_FREQUENCY_SLOT_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFER_PRESET_FIELD_NUMBER: _ClassVar[int]
|
||||
OFFER_REGION_FIELD_NUMBER: _ClassVar[int]
|
||||
message: str
|
||||
offer_channel: _channel_pb2.ChannelSettings
|
||||
offer_frequency_slot: int
|
||||
offer_preset: _config_pb2.Config.LoRaConfig.ModemPreset
|
||||
offer_region: _config_pb2.Config.LoRaConfig.RegionCode
|
||||
def __init__(self, message: _Optional[str] = ..., offer_channel: _Optional[_Union[_channel_pb2.ChannelSettings, _Mapping]] = ..., offer_region: _Optional[_Union[_config_pb2.Config.LoRaConfig.RegionCode, str]] = ..., offer_preset: _Optional[_Union[_config_pb2.Config.LoRaConfig.ModemPreset, str]] = ..., offer_frequency_slot: _Optional[int] = ...) -> None: ...
|
||||
+101
-150
@@ -14,14 +14,13 @@ _sym_db = _symbol_database.Default()
|
||||
from meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_channel__pb2
|
||||
from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2
|
||||
from meshtastic.protobuf import device_ui_pb2 as meshtastic_dot_protobuf_dot_device__ui__pb2
|
||||
from meshtastic.protobuf import field_metadata_pb2 as meshtastic_dot_protobuf_dot_field__metadata__pb2
|
||||
from meshtastic.protobuf import module_config_pb2 as meshtastic_dot_protobuf_dot_module__config__pb2
|
||||
from meshtastic.protobuf import portnums_pb2 as meshtastic_dot_protobuf_dot_portnums__pb2
|
||||
from meshtastic.protobuf import telemetry_pb2 as meshtastic_dot_protobuf_dot_telemetry__pb2
|
||||
from meshtastic.protobuf import xmodem_pb2 as meshtastic_dot_protobuf_dot_xmodem__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a(meshtastic/protobuf/field_metadata.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\x9c\x02\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xc7\x04\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\x12\x11\n\tack_proof\x18\x04 \x01(\x0c\"\xe7\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10&\x12\x1c\n\x18PKI_SEND_FAIL_PUBLIC_KEY\x10\'B\t\n\x07variant\"\xee\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x12\x18\n\x10xeddsa_signature\x18\n \x01(\x0c\x42\x0b\n\t_bitfield\">\n\x0fKeyVerification\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\r\n\x05hash1\x18\x02 \x01(\x0c\x12\r\n\x05hash2\x18\x03 \x01(\x0c\"\xd4\x03\n\x14StoreForwardPlusPlus\x12V\n\x11sfpp_message_type\x18\x01 \x01(\x0e\x32;.meshtastic.protobuf.StoreForwardPlusPlus.SFPP_message_type\x12\x14\n\x0cmessage_hash\x18\x02 \x01(\x0c\x12\x13\n\x0b\x63ommit_hash\x18\x03 \x01(\x0c\x12\x11\n\troot_hash\x18\x04 \x01(\x0c\x12\x0f\n\x07message\x18\x05 \x01(\x0c\x12\x17\n\x0f\x65ncapsulated_id\x18\x06 \x01(\r\x12\x17\n\x0f\x65ncapsulated_to\x18\x07 \x01(\r\x12\x19\n\x11\x65ncapsulated_from\x18\x08 \x01(\r\x12\x1b\n\x13\x65ncapsulated_rxtime\x18\t \x01(\r\x12\x13\n\x0b\x63hain_count\x18\nLine truncated
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1emeshtastic/protobuf/mesh.proto\x12\x13meshtastic.protobuf\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a#meshtastic/protobuf/device_ui.proto\x1a\'meshtastic/protobuf/module_config.proto\x1a\"meshtastic/protobuf/portnums.proto\x1a#meshtastic/protobuf/telemetry.proto\x1a meshtastic/protobuf/xmodem.proto\"\x99\x07\n\x08Position\x12\x17\n\nlatitude_i\x18\x01 \x01(\x0fH\x00\x88\x01\x01\x12\x18\n\x0blongitude_i\x18\x02 \x01(\x0fH\x01\x88\x01\x01\x12\x15\n\x08\x61ltitude\x18\x03 \x01(\x05H\x02\x88\x01\x01\x12\x0c\n\x04time\x18\x04 \x01(\x07\x12@\n\x0flocation_source\x18\x05 \x01(\x0e\x32\'.meshtastic.protobuf.Position.LocSource\x12@\n\x0f\x61ltitude_source\x18\x06 \x01(\x0e\x32\'.meshtastic.protobuf.Position.AltSource\x12\x11\n\ttimestamp\x18\x07 \x01(\x07\x12\x1f\n\x17timestamp_millis_adjust\x18\x08 \x01(\x05\x12\x19\n\x0c\x61ltitude_hae\x18\t \x01(\x11H\x03\x88\x01\x01\x12(\n\x1b\x61ltitude_geoidal_separation\x18\n \x01(\x11H\x04\x88\x01\x01\x12\x0c\n\x04PDOP\x18\x0b \x01(\r\x12\x0c\n\x04HDOP\x18\x0c \x01(\r\x12\x0c\n\x04VDOP\x18\r \x01(\r\x12\x14\n\x0cgps_accuracy\x18\x0e \x01(\r\x12\x19\n\x0cground_speed\x18\x0f \x01(\rH\x05\x88\x01\x01\x12\x19\n\x0cground_track\x18\x10 \x01(\rH\x06\x88\x01\x01\x12\x13\n\x0b\x66ix_quality\x18\x11 \x01(\r\x12\x10\n\x08\x66ix_type\x18\x12 \x01(\r\x12\x14\n\x0csats_in_view\x18\x13 \x01(\r\x12\x11\n\tsensor_id\x18\x14 \x01(\r\x12\x13\n\x0bnext_update\x18\x15 \x01(\r\x12\x12\n\nseq_number\x18\x16 \x01(\r\x12\x16\n\x0eprecision_bits\x18\x17 \x01(\r\"N\n\tLocSource\x12\r\n\tLOC_UNSET\x10\x00\x12\x0e\n\nLOC_MANUAL\x10\x01\x12\x10\n\x0cLOC_INTERNAL\x10\x02\x12\x10\n\x0cLOC_EXTERNAL\x10\x03\"b\n\tAltSource\x12\r\n\tALT_UNSET\x10\x00\x12\x0e\n\nALT_MANUAL\x10\x01\x12\x10\n\x0c\x41LT_INTERNAL\x10\x02\x12\x10\n\x0c\x41LT_EXTERNAL\x10\x03\x12\x12\n\x0e\x41LT_BAROMETRIC\x10\x04\x42\r\n\x0b_latitude_iB\x0e\n\x0c_longitude_iB\x0b\n\t_altitudeB\x0f\n\r_altitude_haeB\x1e\n\x1c_altitude_geoidal_separationB\x0f\n\r_ground_speedB\x0f\n\r_ground_track\"\x9c\x02\n\x04User\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tlong_name\x18\x02 \x01(\t\x12\x12\n\nshort_name\x18\x03 \x01(\t\x12\x13\n\x07macaddr\x18\x04 \x01(\x0c\x42\x02\x18\x01\x12\x34\n\x08hw_model\x18\x05 \x01(\x0e\x32\".meshtastic.protobuf.HardwareModel\x12\x13\n\x0bis_licensed\x18\x06 \x01(\x08\x12;\n\x04role\x18\x07 \x01(\x0e\x32-.meshtastic.protobuf.Config.DeviceConfig.Role\x12\x12\n\npublic_key\x18\x08 \x01(\x0c\x12\x1c\n\x0fis_unmessagable\x18\t \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_is_unmessagable\"Z\n\x0eRouteDiscovery\x12\r\n\x05route\x18\x01 \x03(\x07\x12\x13\n\x0bsnr_towards\x18\x02 \x03(\x05\x12\x12\n\nroute_back\x18\x03 \x03(\x07\x12\x10\n\x08snr_back\x18\x04 \x03(\x05\"\xb4\x04\n\x07Routing\x12<\n\rroute_request\x18\x01 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0broute_reply\x18\x02 \x01(\x0b\x32#.meshtastic.protobuf.RouteDiscoveryH\x00\x12:\n\x0c\x65rror_reason\x18\x03 \x01(\x0e\x32\".meshtastic.protobuf.Routing.ErrorH\x00\"\xe7\x02\n\x05\x45rror\x12\x08\n\x04NONE\x10\x00\x12\x0c\n\x08NO_ROUTE\x10\x01\x12\x0b\n\x07GOT_NAK\x10\x02\x12\x0b\n\x07TIMEOUT\x10\x03\x12\x10\n\x0cNO_INTERFACE\x10\x04\x12\x12\n\x0eMAX_RETRANSMIT\x10\x05\x12\x0e\n\nNO_CHANNEL\x10\x06\x12\r\n\tTOO_LARGE\x10\x07\x12\x0f\n\x0bNO_RESPONSE\x10\x08\x12\x14\n\x10\x44UTY_CYCLE_LIMIT\x10\t\x12\x0f\n\x0b\x42\x41\x44_REQUEST\x10 \x12\x12\n\x0eNOT_AUTHORIZED\x10!\x12\x0e\n\nPKI_FAILED\x10\"\x12\x16\n\x12PKI_UNKNOWN_PUBKEY\x10#\x12\x19\n\x15\x41\x44MIN_BAD_SESSION_KEY\x10$\x12!\n\x1d\x41\x44MIN_PUBLIC_KEY_UNAUTHORIZED\x10%\x12\x17\n\x13RATE_LIMIT_EXCEEDED\x10&\x12\x1c\n\x18PKI_SEND_FAIL_PUBLIC_KEY\x10\'B\t\n\x07variant\"\xd4\x01\n\x04\x44\x61ta\x12-\n\x07portnum\x18\x01 \x01(\x0e\x32\x1c.meshtastic.protobuf.PortNum\x12\x0f\n\x07payload\x18\x02 \x01(\x0c\x12\x15\n\rwant_response\x18\x03 \x01(\x08\x12\x0c\n\x04\x64\x65st\x18\x04 \x01(\x07\x12\x0e\n\x06source\x18\x05 \x01(\x07\x12\x12\n\nrequest_id\x18\x06 \x01(\x07\x12\x10\n\x08reply_id\x18\x07 \x01(\x07\x12\r\n\x05\x65moji\x18\x08 \x01(\x07\x12\x15\n\x08\x62itfield\x18\t \x01(\rH\x00\x88\x01\x01\x42\x0b\n\t_bitfield\">\n\x0fKeyVerification\x12\r\n\x05nonce\x18\x01 \x01(\x04\x12\r\n\x05hash1\x18\x02 \x01(\x0c\x12\r\n\x05hash2\x18\x03 \x01(\x0c\"\xd4\x03\n\x14StoreForwardPlusPlus\x12V\n\x11sfpp_message_type\x18\x01 \x01(\x0e\x32;.meshtastic.protobuf.StoreForwardPlusPlus.SFPP_message_type\x12\x14\n\x0cmessage_hash\x18\x02 \x01(\x0c\x12\x13\n\x0b\x63ommit_hash\x18\x03 \x01(\x0c\x12\x11\n\troot_hash\x18\x04 \x01(\x0c\x12\x0f\n\x07message\x18\x05 \x01(\x0c\x12\x17\n\x0f\x65ncapsulated_id\x18\x06 \x01(\r\x12\x17\n\x0f\x65ncapsulated_to\x18\x07 \x01(\r\x12\x19\n\x11\x65ncapsulated_from\x18\x08 \x01(\r\x12\x1b\n\x13\x65ncapsulated_rxtime\x18\t \x01(\r\x12\x13\n\x0b\x63hain_count\x18\n \x01(\r\"\x95\x01\n\x11SFPP_message_type\x12\x12\n\x0e\x43\x41NON_ANNOUNCE\x10\x00\x12\x0f\n\x0b\x43HAIN_QUERY\x10\x01\x12\x10\n\Line truncated
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.mesh_pb2', globals())
|
||||
@@ -29,156 +28,108 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\nMeshProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_HARDWAREMODEL.values_by_name["TBEAM"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["TBEAM"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["T_ECHO"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["T_ECHO"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["LILYGO_TBEAM_S3_CORE"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["LILYGO_TBEAM_S3_CORE"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["WIO_WM1110"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["WIO_WM1110"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["CANARYONE"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["CANARYONE"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["T_ECHO_PLUS"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["T_ECHO_PLUS"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["HELTEC_WIRELESS_TRACKER"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["HELTEC_WIRELESS_TRACKER"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["TRACKER_T1000_E"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["TRACKER_T1000_E"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["THINKNODE_M1"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["THINKNODE_M1"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["SEEED_WIO_TRACKER_L1"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["SEEED_WIO_TRACKER_L1"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["SEEED_WIO_TRACKER_L1_EINK"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["SEEED_WIO_TRACKER_L1_EINK"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["T_DECK_PRO"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["T_DECK_PRO"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["T_LORA_PAGER"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["T_LORA_PAGER"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["WISMESH_TAG"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["WISMESH_TAG"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["HELTEC_WIRELESS_TRACKER_V2"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["HELTEC_WIRELESS_TRACKER_V2"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["TBEAM_1_WATT"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["TBEAM_1_WATT"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["TBEAM_BPF"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["TBEAM_BPF"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_HARDWAREMODEL.values_by_name["MESH_TRACKER_X1"]._options = None
|
||||
_HARDWAREMODEL.values_by_name["MESH_TRACKER_X1"]._serialized_options = b'\312\363\030\002`\001'
|
||||
_USER.fields_by_name['macaddr']._options = None
|
||||
_USER.fields_by_name['macaddr']._serialized_options = b'\030\001'
|
||||
_MESHPACKET.fields_by_name['delayed']._options = None
|
||||
_MESHPACKET.fields_by_name['delayed']._serialized_options = b'\030\001'
|
||||
_HARDWAREMODEL._serialized_start=10490
|
||||
_HARDWAREMODEL._serialized_end=13636
|
||||
_CONSTANTS._serialized_start=13638
|
||||
_CONSTANTS._serialized_end=13682
|
||||
_CRITICALERRORCODE._serialized_start=13685
|
||||
_CRITICALERRORCODE._serialized_end=13993
|
||||
_FIRMWAREEDITION._serialized_start=13996
|
||||
_FIRMWAREEDITION._serialized_end=14157
|
||||
_EXCLUDEDMODULES._serialized_start=14160
|
||||
_EXCLUDEDMODULES._serialized_end=14647
|
||||
_POSITION._serialized_start=352
|
||||
_POSITION._serialized_end=1273
|
||||
_POSITION_LOCSOURCE._serialized_start=968
|
||||
_POSITION_LOCSOURCE._serialized_end=1046
|
||||
_POSITION_ALTSOURCE._serialized_start=1048
|
||||
_POSITION_ALTSOURCE._serialized_end=1146
|
||||
_USER._serialized_start=1276
|
||||
_USER._serialized_end=1560
|
||||
_ROUTEDISCOVERY._serialized_start=1562
|
||||
_ROUTEDISCOVERY._serialized_end=1652
|
||||
_ROUTING._serialized_start=1655
|
||||
_ROUTING._serialized_end=2238
|
||||
_ROUTING_ERROR._serialized_start=1868
|
||||
_ROUTING_ERROR._serialized_end=2227
|
||||
_DATA._serialized_start=2241
|
||||
_DATA._serialized_end=2479
|
||||
_KEYVERIFICATION._serialized_start=2481
|
||||
_KEYVERIFICATION._serialized_end=2543
|
||||
_STOREFORWARDPLUSPLUS._serialized_start=2546
|
||||
_STOREFORWARDPLUSPLUS._serialized_end=3014
|
||||
_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE._serialized_start=2865
|
||||
_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE._serialized_end=3014
|
||||
_REMOTESHELL._serialized_start=3017
|
||||
_REMOTESHELL._serialized_end=3381
|
||||
_REMOTESHELL_OPCODE._serialized_start=3238
|
||||
_REMOTESHELL_OPCODE._serialized_end=3381
|
||||
_BOUNDINGBOX._serialized_start=3383
|
||||
_BOUNDINGBOX._serialized_end=3500
|
||||
_WAYPOINT._serialized_start=3503
|
||||
_WAYPOINT._serialized_end=3874
|
||||
_STATUSMESSAGE._serialized_start=3876
|
||||
_STATUSMESSAGE._serialized_end=3907
|
||||
_MQTTCLIENTPROXYMESSAGE._serialized_start=3909
|
||||
_MQTTCLIENTPROXYMESSAGE._serialized_end=4017
|
||||
_MESHPACKET._serialized_start=4020
|
||||
_MESHPACKET._serialized_end=5414
|
||||
_MESHPACKET_PRIORITY._serialized_start=4754
|
||||
_MESHPACKET_PRIORITY._serialized_end=4880
|
||||
_MESHPACKET_DELAYED._serialized_start=4882
|
||||
_MESHPACKET_DELAYED._serialized_end=4948
|
||||
_MESHPACKET_TRANSPORTMECHANISM._serialized_start=4951
|
||||
_MESHPACKET_TRANSPORTMECHANISM._serialized_end=5185
|
||||
_MESHPACKET_ACKPROOFSTATUS._serialized_start=5187
|
||||
_MESHPACKET_ACKPROOFSTATUS._serialized_end=5291
|
||||
_MESHPACKET_SLOTPARITY._serialized_start=5293
|
||||
_MESHPACKET_SLOTPARITY._serialized_end=5371
|
||||
_NODEINFO._serialized_start=5417
|
||||
_NODEINFO._serialized_end=5847
|
||||
_MYNODEINFO._serialized_start=5850
|
||||
_MYNODEINFO._serialized_end=6052
|
||||
_LOGRECORD._serialized_start=6055
|
||||
_LOGRECORD._serialized_end=6256
|
||||
_LOGRECORD_LEVEL._serialized_start=6168
|
||||
_LOGRECORD_LEVEL._serialized_end=6256
|
||||
_QUEUESTATUS._serialized_start=6258
|
||||
_QUEUESTATUS._serialized_end=6338
|
||||
_FROMRADIO._serialized_start=6341
|
||||
_FROMRADIO._serialized_end=7360
|
||||
_LOCKDOWNSTATUS._serialized_start=7363
|
||||
_LOCKDOWNSTATUS._serialized_end=7647
|
||||
_LOCKDOWNSTATUS_STATE._serialized_start=7537
|
||||
_LOCKDOWNSTATUS_STATE._serialized_end=7647
|
||||
_CLIENTNOTIFICATION._serialized_start=7650
|
||||
_CLIENTNOTIFICATION._serialized_end=8210
|
||||
_KEYVERIFICATIONNUMBERINFORM._serialized_start=8212
|
||||
_KEYVERIFICATIONNUMBERINFORM._serialized_end=8306
|
||||
_KEYVERIFICATIONNUMBERREQUEST._serialized_start=8308
|
||||
_KEYVERIFICATIONNUMBERREQUEST._serialized_end=8378
|
||||
_KEYVERIFICATIONFINAL._serialized_start=8380
|
||||
_KEYVERIFICATIONFINAL._serialized_end=8493
|
||||
_DUPLICATEDPUBLICKEY._serialized_start=8495
|
||||
_DUPLICATEDPUBLICKEY._serialized_end=8516
|
||||
_LOWENTROPYKEY._serialized_start=8518
|
||||
_LOWENTROPYKEY._serialized_end=8533
|
||||
_FILEINFO._serialized_start=8535
|
||||
_FILEINFO._serialized_end=8584
|
||||
_TORADIO._serialized_start=8587
|
||||
_TORADIO._serialized_end=8899
|
||||
_COMPRESSED._serialized_start=8901
|
||||
_COMPRESSED._serialized_end=8974
|
||||
_NEIGHBORINFO._serialized_start=8977
|
||||
_NEIGHBORINFO._serialized_end=9121
|
||||
_NEIGHBOR._serialized_start=9123
|
||||
_NEIGHBOR._serialized_end=9223
|
||||
_DEVICEMETADATA._serialized_start=9226
|
||||
_DEVICEMETADATA._serialized_end=9607
|
||||
_LORAPRESETGROUP._serialized_start=9610
|
||||
_LORAPRESETGROUP._serialized_end=9795
|
||||
_LORAREGIONPRESETS._serialized_start=9797
|
||||
_LORAREGIONPRESETS._serialized_end=9904
|
||||
_LORAREGIONPRESETMAP._serialized_start=9907
|
||||
_LORAREGIONPRESETMAP._serialized_end=10045
|
||||
_HEARTBEAT._serialized_start=10047
|
||||
_HEARTBEAT._serialized_end=10073
|
||||
_NODEREMOTEHARDWAREPIN._serialized_start=10075
|
||||
_NODEREMOTEHARDWAREPIN._serialized_end=10169
|
||||
_CHUNKEDPAYLOAD._serialized_start=10171
|
||||
_CHUNKEDPAYLOAD._serialized_end=10272
|
||||
_RESEND_CHUNKS._serialized_start=10274
|
||||
_RESEND_CHUNKS._serialized_end=10305
|
||||
_CHUNKEDPAYLOADRESPONSE._serialized_start=10308
|
||||
_CHUNKEDPAYLOADRESPONSE._serialized_end=10487
|
||||
_HARDWAREMODEL._serialized_start=9094
|
||||
_HARDWAREMODEL._serialized_end=11732
|
||||
_CONSTANTS._serialized_start=11734
|
||||
_CONSTANTS._serialized_end=11778
|
||||
_CRITICALERRORCODE._serialized_start=11781
|
||||
_CRITICALERRORCODE._serialized_end=12089
|
||||
_FIRMWAREEDITION._serialized_start=12091
|
||||
_FIRMWAREEDITION._serialized_end=12218
|
||||
_EXCLUDEDMODULES._serialized_start=12221
|
||||
_EXCLUDEDMODULES._serialized_end=12605
|
||||
_POSITION._serialized_start=310
|
||||
_POSITION._serialized_end=1231
|
||||
_POSITION_LOCSOURCE._serialized_start=926
|
||||
_POSITION_LOCSOURCE._serialized_end=1004
|
||||
_POSITION_ALTSOURCE._serialized_start=1006
|
||||
_POSITION_ALTSOURCE._serialized_end=1104
|
||||
_USER._serialized_start=1234
|
||||
_USER._serialized_end=1518
|
||||
_ROUTEDISCOVERY._serialized_start=1520
|
||||
_ROUTEDISCOVERY._serialized_end=1610
|
||||
_ROUTING._serialized_start=1613
|
||||
_ROUTING._serialized_end=2177
|
||||
_ROUTING_ERROR._serialized_start=1807
|
||||
_ROUTING_ERROR._serialized_end=2166
|
||||
_DATA._serialized_start=2180
|
||||
_DATA._serialized_end=2392
|
||||
_KEYVERIFICATION._serialized_start=2394
|
||||
_KEYVERIFICATION._serialized_end=2456
|
||||
_STOREFORWARDPLUSPLUS._serialized_start=2459
|
||||
_STOREFORWARDPLUSPLUS._serialized_end=2927
|
||||
_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE._serialized_start=2778
|
||||
_STOREFORWARDPLUSPLUS_SFPP_MESSAGE_TYPE._serialized_end=2927
|
||||
_REMOTESHELL._serialized_start=2930
|
||||
_REMOTESHELL._serialized_end=3294
|
||||
_REMOTESHELL_OPCODE._serialized_start=3151
|
||||
_REMOTESHELL_OPCODE._serialized_end=3294
|
||||
_WAYPOINT._serialized_start=3297
|
||||
_WAYPOINT._serialized_end=3485
|
||||
_STATUSMESSAGE._serialized_start=3487
|
||||
_STATUSMESSAGE._serialized_end=3518
|
||||
_MQTTCLIENTPROXYMESSAGE._serialized_start=3520
|
||||
_MQTTCLIENTPROXYMESSAGE._serialized_end=3628
|
||||
_MESHPACKET._serialized_start=3631
|
||||
_MESHPACKET._serialized_end=4616
|
||||
_MESHPACKET_PRIORITY._serialized_start=4193
|
||||
_MESHPACKET_PRIORITY._serialized_end=4319
|
||||
_MESHPACKET_DELAYED._serialized_start=4321
|
||||
_MESHPACKET_DELAYED._serialized_end=4387
|
||||
_MESHPACKET_TRANSPORTMECHANISM._serialized_start=4390
|
||||
_MESHPACKET_TRANSPORTMECHANISM._serialized_end=4597
|
||||
_NODEINFO._serialized_start=4619
|
||||
_NODEINFO._serialized_end=4991
|
||||
_MYNODEINFO._serialized_start=4994
|
||||
_MYNODEINFO._serialized_end=5196
|
||||
_LOGRECORD._serialized_start=5199
|
||||
_LOGRECORD._serialized_end=5400
|
||||
_LOGRECORD_LEVEL._serialized_start=5312
|
||||
_LOGRECORD_LEVEL._serialized_end=5400
|
||||
_QUEUESTATUS._serialized_start=5402
|
||||
_QUEUESTATUS._serialized_end=5482
|
||||
_FROMRADIO._serialized_start=5485
|
||||
_FROMRADIO._serialized_end=6436
|
||||
_LOCKDOWNSTATUS._serialized_start=6439
|
||||
_LOCKDOWNSTATUS._serialized_end=6709
|
||||
_LOCKDOWNSTATUS_STATE._serialized_start=6613
|
||||
_LOCKDOWNSTATUS_STATE._serialized_end=6709
|
||||
_CLIENTNOTIFICATION._serialized_start=6712
|
||||
_CLIENTNOTIFICATION._serialized_end=7272
|
||||
_KEYVERIFICATIONNUMBERINFORM._serialized_start=7274
|
||||
_KEYVERIFICATIONNUMBERINFORM._serialized_end=7368
|
||||
_KEYVERIFICATIONNUMBERREQUEST._serialized_start=7370
|
||||
_KEYVERIFICATIONNUMBERREQUEST._serialized_end=7440
|
||||
_KEYVERIFICATIONFINAL._serialized_start=7442
|
||||
_KEYVERIFICATIONFINAL._serialized_end=7555
|
||||
_DUPLICATEDPUBLICKEY._serialized_start=7557
|
||||
_DUPLICATEDPUBLICKEY._serialized_end=7578
|
||||
_LOWENTROPYKEY._serialized_start=7580
|
||||
_LOWENTROPYKEY._serialized_end=7595
|
||||
_FILEINFO._serialized_start=7597
|
||||
_FILEINFO._serialized_end=7646
|
||||
_TORADIO._serialized_start=7649
|
||||
_TORADIO._serialized_end=7961
|
||||
_COMPRESSED._serialized_start=7963
|
||||
_COMPRESSED._serialized_end=8036
|
||||
_NEIGHBORINFO._serialized_start=8039
|
||||
_NEIGHBORINFO._serialized_end=8183
|
||||
_NEIGHBOR._serialized_start=8185
|
||||
_NEIGHBOR._serialized_end=8285
|
||||
_DEVICEMETADATA._serialized_start=8288
|
||||
_DEVICEMETADATA._serialized_end=8649
|
||||
_HEARTBEAT._serialized_start=8651
|
||||
_HEARTBEAT._serialized_end=8677
|
||||
_NODEREMOTEHARDWAREPIN._serialized_start=8679
|
||||
_NODEREMOTEHARDWAREPIN._serialized_end=8773
|
||||
_CHUNKEDPAYLOAD._serialized_start=8775
|
||||
_CHUNKEDPAYLOAD._serialized_end=8876
|
||||
_RESEND_CHUNKS._serialized_start=8878
|
||||
_RESEND_CHUNKS._serialized_end=8909
|
||||
_CHUNKEDPAYLOADRESPONSE._serialized_start=8912
|
||||
_CHUNKEDPAYLOADRESPONSE._serialized_end=9091
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,7 +1,6 @@
|
||||
from meshtastic.protobuf import channel_pb2 as _channel_pb2
|
||||
from meshtastic.protobuf import config_pb2 as _config_pb2
|
||||
from meshtastic.protobuf import device_ui_pb2 as _device_ui_pb2
|
||||
from meshtastic.protobuf import field_metadata_pb2 as _field_metadata_pb2
|
||||
from meshtastic.protobuf import module_config_pb2 as _module_config_pb2
|
||||
from meshtastic.protobuf import portnums_pb2 as _portnums_pb2
|
||||
from meshtastic.protobuf import telemetry_pb2 as _telemetry_pb2
|
||||
@@ -15,7 +14,6 @@ from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Map
|
||||
AMBIENTLIGHTING_CONFIG: ExcludedModules
|
||||
ANDROID_SIM: HardwareModel
|
||||
AUDIO_CONFIG: ExcludedModules
|
||||
AXIOMETA_GENESIS_MINI: HardwareModel
|
||||
BETAFPV_2400_TX: HardwareModel
|
||||
BETAFPV_900_NANO_TX: HardwareModel
|
||||
BLUETOOTH_CONFIG: ExcludedModules
|
||||
@@ -23,24 +21,20 @@ BROWNOUT: CriticalErrorCode
|
||||
BURNING_MAN: FirmwareEdition
|
||||
CANARYONE: HardwareModel
|
||||
CANNEDMSG_CONFIG: ExcludedModules
|
||||
CCC: FirmwareEdition
|
||||
CDEBYTE_EORA_S3: HardwareModel
|
||||
CHATTER_2: HardwareModel
|
||||
CROWPANEL: HardwareModel
|
||||
CROWPANEL_P4: HardwareModel
|
||||
DATA_PAYLOAD_LEN: Constants
|
||||
DEFCON: FirmwareEdition
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
DETECTIONSENSOR_CONFIG: ExcludedModules
|
||||
DIY_EDITION: FirmwareEdition
|
||||
DIY_V1: HardwareModel
|
||||
DRAGON_CON: FirmwareEdition
|
||||
DR_DEV: HardwareModel
|
||||
EBYTE_ESP32_S3: HardwareModel
|
||||
ESP32_S3_PICO: HardwareModel
|
||||
EXCLUDED_NONE: ExcludedModules
|
||||
EXTNOTIF_CONFIG: ExcludedModules
|
||||
FAB: FirmwareEdition
|
||||
FLASH_CORRUPTION_RECOVERABLE: CriticalErrorCode
|
||||
FLASH_CORRUPTION_UNRECOVERABLE: CriticalErrorCode
|
||||
GENIEBLOCKS: HardwareModel
|
||||
@@ -52,12 +46,7 @@ HELTEC_MESH_NODE_T096: HardwareModel
|
||||
HELTEC_MESH_NODE_T1: HardwareModel
|
||||
HELTEC_MESH_NODE_T114: HardwareModel
|
||||
HELTEC_MESH_POCKET: HardwareModel
|
||||
HELTEC_MESH_POCKET_V2: HardwareModel
|
||||
HELTEC_MESH_SOLAR: HardwareModel
|
||||
HELTEC_MESH_TOWER_V2: HardwareModel
|
||||
HELTEC_RC32: HardwareModel
|
||||
HELTEC_RC52: HardwareModel
|
||||
HELTEC_RCC6: HardwareModel
|
||||
HELTEC_SENSOR_HUB: HardwareModel
|
||||
HELTEC_V1: HardwareModel
|
||||
HELTEC_V2_0: HardwareModel
|
||||
@@ -87,18 +76,10 @@ M5STACK_CORE2: HardwareModel
|
||||
M5STACK_COREBASIC: HardwareModel
|
||||
M5STACK_CORES3: HardwareModel
|
||||
M5STACK_RESERVED: HardwareModel
|
||||
MAKERFABS_NOMAD_TERMINAL: HardwareModel
|
||||
MAKERFABS_RESERVED: HardwareModel
|
||||
MAKERFABS_TRACKER: HardwareModel
|
||||
ME25LS01_4Y10TD: HardwareModel
|
||||
MESHBEACON_CONFIG: ExcludedModules
|
||||
MESHLINK: HardwareModel
|
||||
MESHNOLOGY_W10: HardwareModel
|
||||
MESHNOLOGY_W12: HardwareModel
|
||||
MESHPAGER_X2: HardwareModel
|
||||
MESHSTICK_1262: HardwareModel
|
||||
MESH_TAB: HardwareModel
|
||||
MESH_TRACKER_X1: HardwareModel
|
||||
MINI_EPAPER_S3: HardwareModel
|
||||
MQTT_CONFIG: ExcludedModules
|
||||
MS24SF1: HardwareModel
|
||||
@@ -109,7 +90,6 @@ NANO_G1_EXPLORER: HardwareModel
|
||||
NANO_G2_ULTRA: HardwareModel
|
||||
NEIGHBORINFO_CONFIG: ExcludedModules
|
||||
NETWORK_CONFIG: ExcludedModules
|
||||
NODARA: HardwareModel
|
||||
NOMADSTAR_METEOR_PRO: HardwareModel
|
||||
NONE: CriticalErrorCode
|
||||
NO_AXP192: CriticalErrorCode
|
||||
@@ -144,21 +124,19 @@ RPI_PICO2: HardwareModel
|
||||
SEEED_SOLAR_NODE: HardwareModel
|
||||
SEEED_WIO_TRACKER_L1: HardwareModel
|
||||
SEEED_WIO_TRACKER_L1_EINK: HardwareModel
|
||||
SEEED_WIO_TRACKER_L1_PRO_1W: HardwareModel
|
||||
SEEED_WIO_TRACKER_L2: HardwareModel
|
||||
SEEED_XIAO_S3: HardwareModel
|
||||
SENSECAP_INDICATOR: HardwareModel
|
||||
SENSELORA_RP2040: HardwareModel
|
||||
SENSELORA_S3: HardwareModel
|
||||
SERIAL_CONFIG: ExcludedModules
|
||||
SLEEP_ENTER_WAIT: CriticalErrorCode
|
||||
SMART_CITIZEN: FirmwareEdition
|
||||
STATION_G1: HardwareModel
|
||||
STATION_G2: HardwareModel
|
||||
STATION_G3: HardwareModel
|
||||
STATUSMESSAGE_CONFIG: ExcludedModules
|
||||
STOREFORWARD_CONFIG: ExcludedModules
|
||||
SX1262_FAILURE: CriticalErrorCode
|
||||
T5_S3_EPAPER_PRO: HardwareModel
|
||||
TAK_CONFIG: ExcludedModules
|
||||
TBEAM: HardwareModel
|
||||
TBEAM_1_WATT: HardwareModel
|
||||
TBEAM_BPF: HardwareModel
|
||||
@@ -175,7 +153,6 @@ THINKNODE_M6: HardwareModel
|
||||
THINKNODE_M7: HardwareModel
|
||||
THINKNODE_M8: HardwareModel
|
||||
THINKNODE_M9: HardwareModel
|
||||
THINKNODE_MX: HardwareModel
|
||||
TLORA_C6: HardwareModel
|
||||
TLORA_T3_S3: HardwareModel
|
||||
TLORA_V1: HardwareModel
|
||||
@@ -184,11 +161,10 @@ TLORA_V2: HardwareModel
|
||||
TLORA_V2_1_1P6: HardwareModel
|
||||
TLORA_V2_1_1P8: HardwareModel
|
||||
TRACKER_T1000_E: HardwareModel
|
||||
TRAFFICMANAGEMENT_CONFIG: ExcludedModules
|
||||
TRACKER_T1000_E_PRO: HardwareModel
|
||||
TRANSMIT_FAILED: CriticalErrorCode
|
||||
TWC_MESH_V4: HardwareModel
|
||||
TX_WATCHDOG: CriticalErrorCode
|
||||
T_CONNECT_PRO: HardwareModel
|
||||
T_DECK: HardwareModel
|
||||
T_DECK_PRO: HardwareModel
|
||||
T_ECHO: HardwareModel
|
||||
@@ -214,18 +190,6 @@ WISMESH_TAP_V2: HardwareModel
|
||||
XIAO_NRF52_KIT: HardwareModel
|
||||
ZERO: Constants
|
||||
|
||||
class BoundingBox(_message.Message):
|
||||
__slots__ = ["latitude_north_i", "latitude_south_i", "longitude_east_i", "longitude_west_i"]
|
||||
LATITUDE_NORTH_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LATITUDE_SOUTH_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_EAST_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_WEST_I_FIELD_NUMBER: _ClassVar[int]
|
||||
latitude_north_i: int
|
||||
latitude_south_i: int
|
||||
longitude_east_i: int
|
||||
longitude_west_i: int
|
||||
def __init__(self, longitude_west_i: _Optional[int] = ..., latitude_south_i: _Optional[int] = ..., longitude_east_i: _Optional[int] = ..., latitude_north_i: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class ChunkedPayload(_message.Message):
|
||||
__slots__ = ["chunk_count", "chunk_index", "payload_chunk", "payload_id"]
|
||||
CHUNK_COUNT_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -281,7 +245,7 @@ class Compressed(_message.Message):
|
||||
def __init__(self, portnum: _Optional[_Union[_portnums_pb2.PortNum, str]] = ..., data: _Optional[bytes] = ...) -> None: ...
|
||||
|
||||
class Data(_message.Message):
|
||||
__slots__ = ["bitfield", "dest", "emoji", "payload", "portnum", "reply_id", "request_id", "source", "want_response", "xeddsa_signature"]
|
||||
__slots__ = ["bitfield", "dest", "emoji", "payload", "portnum", "reply_id", "request_id", "source", "want_response"]
|
||||
BITFIELD_FIELD_NUMBER: _ClassVar[int]
|
||||
DEST_FIELD_NUMBER: _ClassVar[int]
|
||||
EMOJI_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -291,7 +255,6 @@ class Data(_message.Message):
|
||||
REQUEST_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
SOURCE_FIELD_NUMBER: _ClassVar[int]
|
||||
WANT_RESPONSE_FIELD_NUMBER: _ClassVar[int]
|
||||
XEDDSA_SIGNATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
bitfield: int
|
||||
dest: int
|
||||
emoji: int
|
||||
@@ -301,11 +264,10 @@ class Data(_message.Message):
|
||||
request_id: int
|
||||
source: int
|
||||
want_response: bool
|
||||
xeddsa_signature: bytes
|
||||
def __init__(self, portnum: _Optional[_Union[_portnums_pb2.PortNum, str]] = ..., payload: _Optional[bytes] = ..., want_response: bool = ..., dest: _Optional[int] = ..., source: _Optional[int] = ..., request_id: _Optional[int] = ..., reply_id: _Optional[int] = ..., emoji: _Optional[int] = ..., bitfield: _Optional[int] = ..., xeddsa_signature: _Optional[bytes] = ...) -> None: ...
|
||||
def __init__(self, portnum: _Optional[_Union[_portnums_pb2.PortNum, str]] = ..., payload: _Optional[bytes] = ..., want_response: bool = ..., dest: _Optional[int] = ..., source: _Optional[int] = ..., request_id: _Optional[int] = ..., reply_id: _Optional[int] = ..., emoji: _Optional[int] = ..., bitfield: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class DeviceMetadata(_message.Message):
|
||||
__slots__ = ["canShutdown", "device_state_version", "excluded_modules", "firmware_version", "hasBluetooth", "hasEthernet", "hasPKC", "hasRemoteHardware", "hasWifi", "has_xeddsa", "hw_model", "position_flags", "role"]
|
||||
__slots__ = ["canShutdown", "device_state_version", "excluded_modules", "firmware_version", "hasBluetooth", "hasEthernet", "hasPKC", "hasRemoteHardware", "hasWifi", "hw_model", "position_flags", "role"]
|
||||
CANSHUTDOWN_FIELD_NUMBER: _ClassVar[int]
|
||||
DEVICE_STATE_VERSION_FIELD_NUMBER: _ClassVar[int]
|
||||
EXCLUDED_MODULES_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -315,7 +277,6 @@ class DeviceMetadata(_message.Message):
|
||||
HASPKC_FIELD_NUMBER: _ClassVar[int]
|
||||
HASREMOTEHARDWARE_FIELD_NUMBER: _ClassVar[int]
|
||||
HASWIFI_FIELD_NUMBER: _ClassVar[int]
|
||||
HAS_XEDDSA_FIELD_NUMBER: _ClassVar[int]
|
||||
HW_MODEL_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_FLAGS_FIELD_NUMBER: _ClassVar[int]
|
||||
ROLE_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -328,11 +289,10 @@ class DeviceMetadata(_message.Message):
|
||||
hasPKC: bool
|
||||
hasRemoteHardware: bool
|
||||
hasWifi: bool
|
||||
has_xeddsa: bool
|
||||
hw_model: HardwareModel
|
||||
position_flags: int
|
||||
role: _config_pb2.Config.DeviceConfig.Role
|
||||
def __init__(self, firmware_version: _Optional[str] = ..., device_state_version: _Optional[int] = ..., canShutdown: bool = ..., hasWifi: bool = ..., hasBluetooth: bool = ..., hasEthernet: bool = ..., role: _Optional[_Union[_config_pb2.Config.DeviceConfig.Role, str]] = ..., position_flags: _Optional[int] = ..., hw_model: _Optional[_Union[HardwareModel, str]] = ..., hasRemoteHardware: bool = ..., hasPKC: bool = ..., excluded_modules: _Optional[int] = ..., has_xeddsa: bool = ...) -> None: ...
|
||||
def __init__(self, firmware_version: _Optional[str] = ..., device_state_version: _Optional[int] = ..., canShutdown: bool = ..., hasWifi: bool = ..., hasBluetooth: bool = ..., hasEthernet: bool = ..., role: _Optional[_Union[_config_pb2.Config.DeviceConfig.Role, str]] = ..., position_flags: _Optional[int] = ..., hw_model: _Optional[_Union[HardwareModel, str]] = ..., hasRemoteHardware: bool = ..., hasPKC: bool = ..., excluded_modules: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class DuplicatedPublicKey(_message.Message):
|
||||
__slots__ = []
|
||||
@@ -347,7 +307,7 @@ class FileInfo(_message.Message):
|
||||
def __init__(self, file_name: _Optional[str] = ..., size_bytes: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class FromRadio(_message.Message):
|
||||
__slots__ = ["channel", "clientNotification", "config", "config_complete_id", "deviceuiConfig", "fileInfo", "id", "lockdown_status", "log_record", "metadata", "moduleConfig", "mqttClientProxyMessage", "my_info", "node_info", "packet", "queueStatus", "rebooted", "region_presets", "xmodemPacket"]
|
||||
__slots__ = ["channel", "clientNotification", "config", "config_complete_id", "deviceuiConfig", "fileInfo", "id", "lockdown_status", "log_record", "metadata", "moduleConfig", "mqttClientProxyMessage", "my_info", "node_info", "packet", "queueStatus", "rebooted", "xmodemPacket"]
|
||||
CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
CLIENTNOTIFICATION_FIELD_NUMBER: _ClassVar[int]
|
||||
CONFIG_COMPLETE_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -365,7 +325,6 @@ class FromRadio(_message.Message):
|
||||
PACKET_FIELD_NUMBER: _ClassVar[int]
|
||||
QUEUESTATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
REBOOTED_FIELD_NUMBER: _ClassVar[int]
|
||||
REGION_PRESETS_FIELD_NUMBER: _ClassVar[int]
|
||||
XMODEMPACKET_FIELD_NUMBER: _ClassVar[int]
|
||||
channel: _channel_pb2.Channel
|
||||
clientNotification: ClientNotification
|
||||
@@ -384,9 +343,8 @@ class FromRadio(_message.Message):
|
||||
packet: MeshPacket
|
||||
queueStatus: QueueStatus
|
||||
rebooted: bool
|
||||
region_presets: LoRaRegionPresetMap
|
||||
xmodemPacket: _xmodem_pb2.XModem
|
||||
def __init__(self, id: _Optional[int] = ..., packet: _Optional[_Union[MeshPacket, _Mapping]] = ..., my_info: _Optional[_Union[MyNodeInfo, _Mapping]] = ..., node_info: _Optional[_Union[NodeInfo, _Mapping]] = ..., config: _Optional[_Union[_config_pb2.Config, _Mapping]] = ..., log_record: _Optional[_Union[LogRecord, _Mapping]] = ..., config_complete_id: _Optional[int] = ..., rebooted: bool = ..., moduleConfig: _Optional[_Union[_module_config_pb2.ModuleConfig, _Mapping]] = ..., channel: _Optional[_Union[_channel_pb2.Channel, _Mapping]] = ..., queueStatus: _Optional[_Union[QueueStatus, _Mapping]] = ..., xmodemPacket: _Optional[_Union[_xmodem_pb2.XModem, _Mapping]] = ..., metadata: _Optional[_Union[DeviceMetadata, _Mapping]] = ..., mqttClientProxyMessage: _Optional[_Union[MqttClientProxyMessage, _Mapping]] = ..., fileInfo: _Optional[_Union[FileInfo, _Mapping]] = ..., clientNotification: _Optional[_Union[ClientNotification, _Mapping]] = ..., deviceuiConfig: _Optional[_Union[_device_ui_pb2.DeviceUIConfig, _Mapping]] = ..., lockdown_status: _Optional[_Union[LockdownStatus, _Mapping]] = ..., region_presets: _Optional[_Union[LoRaRegionPresetMap, _Mapping]] = ...) -> None: ...
|
||||
def __init__(self, id: _Optional[int] = ..., packet: _Optional[_Union[MeshPacket, _Mapping]] = ..., my_info: _Optional[_Union[MyNodeInfo, _Mapping]] = ..., node_info: _Optional[_Union[NodeInfo, _Mapping]] = ..., config: _Optional[_Union[_config_pb2.Config, _Mapping]] = ..., log_record: _Optional[_Union[LogRecord, _Mapping]] = ..., config_complete_id: _Optional[int] = ..., rebooted: bool = ..., moduleConfig: _Optional[_Union[_module_config_pb2.ModuleConfig, _Mapping]] = ..., channel: _Optional[_Union[_channel_pb2.Channel, _Mapping]] = ..., queueStatus: _Optional[_Union[QueueStatus, _Mapping]] = ..., xmodemPacket: _Optional[_Union[_xmodem_pb2.XModem, _Mapping]] = ..., metadata: _Optional[_Union[DeviceMetadata, _Mapping]] = ..., mqttClientProxyMessage: _Optional[_Union[MqttClientProxyMessage, _Mapping]] = ..., fileInfo: _Optional[_Union[FileInfo, _Mapping]] = ..., clientNotification: _Optional[_Union[ClientNotification, _Mapping]] = ..., deviceuiConfig: _Optional[_Union[_device_ui_pb2.DeviceUIConfig, _Mapping]] = ..., lockdown_status: _Optional[_Union[LockdownStatus, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class Heartbeat(_message.Message):
|
||||
__slots__ = ["nonce"]
|
||||
@@ -434,39 +392,12 @@ class KeyVerificationNumberRequest(_message.Message):
|
||||
remote_longname: str
|
||||
def __init__(self, nonce: _Optional[int] = ..., remote_longname: _Optional[str] = ...) -> None: ...
|
||||
|
||||
class LoRaPresetGroup(_message.Message):
|
||||
__slots__ = ["default_preset", "licensed_only", "presets"]
|
||||
DEFAULT_PRESET_FIELD_NUMBER: _ClassVar[int]
|
||||
LICENSED_ONLY_FIELD_NUMBER: _ClassVar[int]
|
||||
PRESETS_FIELD_NUMBER: _ClassVar[int]
|
||||
default_preset: _config_pb2.Config.LoRaConfig.ModemPreset
|
||||
licensed_only: bool
|
||||
presets: _containers.RepeatedScalarFieldContainer[_config_pb2.Config.LoRaConfig.ModemPreset]
|
||||
def __init__(self, presets: _Optional[_Iterable[_Union[_config_pb2.Config.LoRaConfig.ModemPreset, str]]] = ..., default_preset: _Optional[_Union[_config_pb2.Config.LoRaConfig.ModemPreset, str]] = ..., licensed_only: bool = ...) -> None: ...
|
||||
|
||||
class LoRaRegionPresetMap(_message.Message):
|
||||
__slots__ = ["groups", "region_groups"]
|
||||
GROUPS_FIELD_NUMBER: _ClassVar[int]
|
||||
REGION_GROUPS_FIELD_NUMBER: _ClassVar[int]
|
||||
groups: _containers.RepeatedCompositeFieldContainer[LoRaPresetGroup]
|
||||
region_groups: _containers.RepeatedCompositeFieldContainer[LoRaRegionPresets]
|
||||
def __init__(self, groups: _Optional[_Iterable[_Union[LoRaPresetGroup, _Mapping]]] = ..., region_groups: _Optional[_Iterable[_Union[LoRaRegionPresets, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
class LoRaRegionPresets(_message.Message):
|
||||
__slots__ = ["group_index", "region"]
|
||||
GROUP_INDEX_FIELD_NUMBER: _ClassVar[int]
|
||||
REGION_FIELD_NUMBER: _ClassVar[int]
|
||||
group_index: int
|
||||
region: _config_pb2.Config.LoRaConfig.RegionCode
|
||||
def __init__(self, region: _Optional[_Union[_config_pb2.Config.LoRaConfig.RegionCode, str]] = ..., group_index: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class LockdownStatus(_message.Message):
|
||||
__slots__ = ["backoff_seconds", "boots_remaining", "lock_reason", "state", "valid_until_epoch"]
|
||||
class State(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
BACKOFF_SECONDS_FIELD_NUMBER: _ClassVar[int]
|
||||
BOOTS_REMAINING_FIELD_NUMBER: _ClassVar[int]
|
||||
DISABLED: LockdownStatus.State
|
||||
LOCKED: LockdownStatus.State
|
||||
LOCK_REASON_FIELD_NUMBER: _ClassVar[int]
|
||||
NEEDS_PROVISION: LockdownStatus.State
|
||||
@@ -508,23 +439,14 @@ class LowEntropyKey(_message.Message):
|
||||
def __init__(self) -> None: ...
|
||||
|
||||
class MeshPacket(_message.Message):
|
||||
__slots__ = ["ack_proof_status", "channel", "decoded", "delayed", "encrypted", "hop_limit", "hop_start", "id", "next_hop", "pki_encrypted", "priority", "public_key", "relay_node", "rx_rssi", "rx_snr", "rx_time", "slot_parity", "to", "transport_mechanism", "tx_after", "via_mqtt", "want_ack", "xeddsa_signed"]
|
||||
class AckProofStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
__slots__ = ["channel", "decoded", "delayed", "encrypted", "hop_limit", "hop_start", "id", "next_hop", "pki_encrypted", "priority", "public_key", "relay_node", "rx_rssi", "rx_snr", "rx_time", "to", "transport_mechanism", "tx_after", "via_mqtt", "want_ack"]
|
||||
class Delayed(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class Priority(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class SlotParity(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class TransportMechanism(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
ACK: MeshPacket.Priority
|
||||
ACK_PROOF_ABSENT: MeshPacket.AckProofStatus
|
||||
ACK_PROOF_INVALID: MeshPacket.AckProofStatus
|
||||
ACK_PROOF_NO_KEY: MeshPacket.AckProofStatus
|
||||
ACK_PROOF_STATUS_FIELD_NUMBER: _ClassVar[int]
|
||||
ACK_PROOF_VALID: MeshPacket.AckProofStatus
|
||||
ALERT: MeshPacket.Priority
|
||||
BACKGROUND: MeshPacket.Priority
|
||||
CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -552,10 +474,6 @@ class MeshPacket(_message.Message):
|
||||
RX_RSSI_FIELD_NUMBER: _ClassVar[int]
|
||||
RX_SNR_FIELD_NUMBER: _ClassVar[int]
|
||||
RX_TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
SLOT_PARITY_EVEN: MeshPacket.SlotParity
|
||||
SLOT_PARITY_FIELD_NUMBER: _ClassVar[int]
|
||||
SLOT_PARITY_ODD: MeshPacket.SlotParity
|
||||
SLOT_PARITY_UNSET: MeshPacket.SlotParity
|
||||
TO_FIELD_NUMBER: _ClassVar[int]
|
||||
TRANSPORT_API: MeshPacket.TransportMechanism
|
||||
TRANSPORT_INTERNAL: MeshPacket.TransportMechanism
|
||||
@@ -566,13 +484,10 @@ class MeshPacket(_message.Message):
|
||||
TRANSPORT_MECHANISM_FIELD_NUMBER: _ClassVar[int]
|
||||
TRANSPORT_MQTT: MeshPacket.TransportMechanism
|
||||
TRANSPORT_MULTICAST_UDP: MeshPacket.TransportMechanism
|
||||
TRANSPORT_UNICAST_UDP: MeshPacket.TransportMechanism
|
||||
TX_AFTER_FIELD_NUMBER: _ClassVar[int]
|
||||
UNSET: MeshPacket.Priority
|
||||
VIA_MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
WANT_ACK_FIELD_NUMBER: _ClassVar[int]
|
||||
XEDDSA_SIGNED_FIELD_NUMBER: _ClassVar[int]
|
||||
ack_proof_status: MeshPacket.AckProofStatus
|
||||
channel: int
|
||||
decoded: Data
|
||||
delayed: MeshPacket.Delayed
|
||||
@@ -588,14 +503,12 @@ class MeshPacket(_message.Message):
|
||||
rx_rssi: int
|
||||
rx_snr: float
|
||||
rx_time: int
|
||||
slot_parity: MeshPacket.SlotParity
|
||||
to: int
|
||||
transport_mechanism: MeshPacket.TransportMechanism
|
||||
tx_after: int
|
||||
via_mqtt: bool
|
||||
want_ack: bool
|
||||
xeddsa_signed: bool
|
||||
def __init__(self, to: _Optional[int] = ..., channel: _Optional[int] = ..., decoded: _Optional[_Union[Data, _Mapping]] = ..., encrypted: _Optional[bytes] = ..., id: _Optional[int] = ..., rx_time: _Optional[int] = ..., rx_snr: _Optional[float] = ..., hop_limit: _Optional[int] = ..., want_ack: bool = ..., priority: _Optional[_Union[MeshPacket.Priority, str]] = ..., rx_rssi: _Optional[int] = ..., delayed: _Optional[_Union[MeshPacket.Delayed, str]] = ..., via_mqtt: bool = ..., hop_start: _Optional[int] = ..., public_key: _Optional[bytes] = ..., pki_encrypted: bool = ..., next_hop: _Optional[int] = ..., relay_node: _Optional[int] = ..., tx_after: _Optional[int] = ..., transport_mechanism: _Optional[_Union[MeshPacket.TransportMechanism, str]] = ..., xeddsa_signed: bool = ..., ack_proof_status: _Optional[_Union[MeshPacket.AckProofStatus, str]] = ..., slot_parity: _Optional[_Union[MeshPacket.SlotParity, str]] = ..., **kwargs) -> None: ...
|
||||
def __init__(self, to: _Optional[int] = ..., channel: _Optional[int] = ..., decoded: _Optional[_Union[Data, _Mapping]] = ..., encrypted: _Optional[bytes] = ..., id: _Optional[int] = ..., rx_time: _Optional[int] = ..., rx_snr: _Optional[float] = ..., hop_limit: _Optional[int] = ..., want_ack: bool = ..., priority: _Optional[_Union[MeshPacket.Priority, str]] = ..., rx_rssi: _Optional[int] = ..., delayed: _Optional[_Union[MeshPacket.Delayed, str]] = ..., via_mqtt: bool = ..., hop_start: _Optional[int] = ..., public_key: _Optional[bytes] = ..., pki_encrypted: bool = ..., next_hop: _Optional[int] = ..., relay_node: _Optional[int] = ..., tx_after: _Optional[int] = ..., transport_mechanism: _Optional[_Union[MeshPacket.TransportMechanism, str]] = ..., **kwargs) -> None: ...
|
||||
|
||||
class MqttClientProxyMessage(_message.Message):
|
||||
__slots__ = ["data", "retained", "text", "topic"]
|
||||
@@ -652,11 +565,9 @@ class NeighborInfo(_message.Message):
|
||||
def __init__(self, node_id: _Optional[int] = ..., last_sent_by_id: _Optional[int] = ..., node_broadcast_interval_secs: _Optional[int] = ..., neighbors: _Optional[_Iterable[_Union[Neighbor, _Mapping]]] = ...) -> None: ...
|
||||
|
||||
class NodeInfo(_message.Message):
|
||||
__slots__ = ["channel", "device_metrics", "has_xeddsa_signed", "heard_on_current_lora", "hops_away", "is_favorite", "is_ignored", "is_key_manually_verified", "is_muted", "last_heard", "num", "position", "snr", "user", "via_mqtt"]
|
||||
__slots__ = ["channel", "device_metrics", "hops_away", "is_favorite", "is_ignored", "is_key_manually_verified", "is_muted", "last_heard", "num", "position", "snr", "user", "via_mqtt"]
|
||||
CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
DEVICE_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
HAS_XEDDSA_SIGNED_FIELD_NUMBER: _ClassVar[int]
|
||||
HEARD_ON_CURRENT_LORA_FIELD_NUMBER: _ClassVar[int]
|
||||
HOPS_AWAY_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_FAVORITE_FIELD_NUMBER: _ClassVar[int]
|
||||
IS_IGNORED_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -670,8 +581,6 @@ class NodeInfo(_message.Message):
|
||||
VIA_MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
channel: int
|
||||
device_metrics: _telemetry_pb2.DeviceMetrics
|
||||
has_xeddsa_signed: bool
|
||||
heard_on_current_lora: bool
|
||||
hops_away: int
|
||||
is_favorite: bool
|
||||
is_ignored: bool
|
||||
@@ -683,7 +592,7 @@ class NodeInfo(_message.Message):
|
||||
snr: float
|
||||
user: User
|
||||
via_mqtt: bool
|
||||
def __init__(self, num: _Optional[int] = ..., user: _Optional[_Union[User, _Mapping]] = ..., position: _Optional[_Union[Position, _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 = ..., is_key_manually_verified: bool = ..., is_muted: bool = ..., has_xeddsa_signed: bool = ..., heard_on_current_lora: bool = ...) -> None: ...
|
||||
def __init__(self, num: _Optional[int] = ..., user: _Optional[_Union[User, _Mapping]] = ..., position: _Optional[_Union[Position, _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 = ..., is_key_manually_verified: bool = ..., is_muted: bool = ...) -> None: ...
|
||||
|
||||
class NodeRemoteHardwarePin(_message.Message):
|
||||
__slots__ = ["node_num", "pin"]
|
||||
@@ -819,10 +728,9 @@ class RouteDiscovery(_message.Message):
|
||||
def __init__(self, route: _Optional[_Iterable[int]] = ..., snr_towards: _Optional[_Iterable[int]] = ..., route_back: _Optional[_Iterable[int]] = ..., snr_back: _Optional[_Iterable[int]] = ...) -> None: ...
|
||||
|
||||
class Routing(_message.Message):
|
||||
__slots__ = ["ack_proof", "error_reason", "route_reply", "route_request"]
|
||||
__slots__ = ["error_reason", "route_reply", "route_request"]
|
||||
class Error(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
ACK_PROOF_FIELD_NUMBER: _ClassVar[int]
|
||||
ADMIN_BAD_SESSION_KEY: Routing.Error
|
||||
ADMIN_PUBLIC_KEY_UNAUTHORIZED: Routing.Error
|
||||
BAD_REQUEST: Routing.Error
|
||||
@@ -844,11 +752,10 @@ class Routing(_message.Message):
|
||||
ROUTE_REQUEST_FIELD_NUMBER: _ClassVar[int]
|
||||
TIMEOUT: Routing.Error
|
||||
TOO_LARGE: Routing.Error
|
||||
ack_proof: bytes
|
||||
error_reason: Routing.Error
|
||||
route_reply: RouteDiscovery
|
||||
route_request: RouteDiscovery
|
||||
def __init__(self, route_request: _Optional[_Union[RouteDiscovery, _Mapping]] = ..., route_reply: _Optional[_Union[RouteDiscovery, _Mapping]] = ..., error_reason: _Optional[_Union[Routing.Error, str]] = ..., ack_proof: _Optional[bytes] = ...) -> None: ...
|
||||
def __init__(self, route_request: _Optional[_Union[RouteDiscovery, _Mapping]] = ..., route_reply: _Optional[_Union[RouteDiscovery, _Mapping]] = ..., error_reason: _Optional[_Union[Routing.Error, str]] = ...) -> None: ...
|
||||
|
||||
class StatusMessage(_message.Message):
|
||||
__slots__ = ["status"]
|
||||
@@ -927,34 +834,24 @@ class User(_message.Message):
|
||||
def __init__(self, id: _Optional[str] = ..., long_name: _Optional[str] = ..., short_name: _Optional[str] = ..., macaddr: _Optional[bytes] = ..., hw_model: _Optional[_Union[HardwareModel, str]] = ..., is_licensed: bool = ..., role: _Optional[_Union[_config_pb2.Config.DeviceConfig.Role, str]] = ..., public_key: _Optional[bytes] = ..., is_unmessagable: bool = ...) -> None: ...
|
||||
|
||||
class Waypoint(_message.Message):
|
||||
__slots__ = ["bounding_box", "description", "expire", "geofence_radius", "icon", "id", "latitude_i", "locked_to", "longitude_i", "name", "notify_favorites_only", "notify_on_enter", "notify_on_exit"]
|
||||
BOUNDING_BOX_FIELD_NUMBER: _ClassVar[int]
|
||||
__slots__ = ["description", "expire", "icon", "id", "latitude_i", "locked_to", "longitude_i", "name"]
|
||||
DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
|
||||
EXPIRE_FIELD_NUMBER: _ClassVar[int]
|
||||
GEOFENCE_RADIUS_FIELD_NUMBER: _ClassVar[int]
|
||||
ICON_FIELD_NUMBER: _ClassVar[int]
|
||||
ID_FIELD_NUMBER: _ClassVar[int]
|
||||
LATITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
LOCKED_TO_FIELD_NUMBER: _ClassVar[int]
|
||||
LONGITUDE_I_FIELD_NUMBER: _ClassVar[int]
|
||||
NAME_FIELD_NUMBER: _ClassVar[int]
|
||||
NOTIFY_FAVORITES_ONLY_FIELD_NUMBER: _ClassVar[int]
|
||||
NOTIFY_ON_ENTER_FIELD_NUMBER: _ClassVar[int]
|
||||
NOTIFY_ON_EXIT_FIELD_NUMBER: _ClassVar[int]
|
||||
bounding_box: BoundingBox
|
||||
description: str
|
||||
expire: int
|
||||
geofence_radius: int
|
||||
icon: int
|
||||
id: int
|
||||
latitude_i: int
|
||||
locked_to: int
|
||||
longitude_i: int
|
||||
name: str
|
||||
notify_favorites_only: bool
|
||||
notify_on_enter: bool
|
||||
notify_on_exit: bool
|
||||
def __init__(self, id: _Optional[int] = ..., latitude_i: _Optional[int] = ..., longitude_i: _Optional[int] = ..., expire: _Optional[int] = ..., locked_to: _Optional[int] = ..., name: _Optional[str] = ..., description: _Optional[str] = ..., icon: _Optional[int] = ..., geofence_radius: _Optional[int] = ..., bounding_box: _Optional[_Union[BoundingBox, _Mapping]] = ..., notify_on_enter: bool = ..., notify_on_exit: bool = ..., notify_favorites_only: bool = ...) -> None: ...
|
||||
def __init__(self, id: _Optional[int] = ..., latitude_i: _Optional[int] = ..., longitude_i: _Optional[int] = ..., expire: _Optional[int] = ..., locked_to: _Optional[int] = ..., name: _Optional[str] = ..., description: _Optional[str] = ..., icon: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class resend_chunks(_message.Message):
|
||||
__slots__ = ["chunks"]
|
||||
|
||||
@@ -12,12 +12,9 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
from meshtastic.protobuf import atak_pb2 as meshtastic_dot_protobuf_dot_atak__pb2
|
||||
from meshtastic.protobuf import channel_pb2 as meshtastic_dot_protobuf_dot_channel__pb2
|
||||
from meshtastic.protobuf import config_pb2 as meshtastic_dot_protobuf_dot_config__pb2
|
||||
from meshtastic.protobuf import field_metadata_pb2 as meshtastic_dot_protobuf_dot_field__metadata__pb2
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\x1a\x1emeshtastic/protobuf/atak.proto\x1a!meshtastic/protobuf/channel.proto\x1a meshtastic/protobuf/config.proto\x1a(meshtastic/protobuf/field_metadata.proto\"\xfd~\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x12\\\n\rstatusmessage\x18\x0e \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfigB\x0c\xca\xf3\x18\x08R\x06\x32.7.20H\x00\x12\x64\n\x12traffic_management\x18\x0f \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfigB\x0b\xca\xf3\x18\x07R\x05\x32.8.0H\x00\x12G\n\x03tak\x18\x10 \x01(\x0b\x32+.meshtastic.protobuf.ModuleConfig.TAKConfigB\x0b\xca\xf3\x18\x07R\x05\x32.8.0H\x00\x12V\n\x0bmesh_beacon\x18\x11 \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.MeshBeaconConfigB\x0b\xca\xf3\x18\x07R\x05\x32.8.0H\x00\x1a\xd9\x07\n\nMQTTConfig\x12\x38\n\x07\x65nabled\x18\x01 \x01(\x08\x42\'\xca\xf3\x18#:\x0cMQTT EnabledB\x13\x45nable MQTT gateway\x12\x33\n\x07\x61\x64\x64ress\x18\x02 \x01(\tB\"\xca\xf3\x18\x1e:\x07\x41\x64\x64ressB\x13MQTT server address\x12/\n\x08username\x18\x03 \x01(\tB\x1d\xca\xf3\x18\x19:\x08UsernameB\rMQTT username\x12/\n\x08password\x18\x04 \x01(\tB\x1d\xca\xf3\x18\x19:\x08PasswordB\rMQTT password\x12T\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x42\x38\xca\xf3\x18\x34:\x12\x45ncryption EnabledB\x1eSend encrypted packets to MQTT\x12#\n\x0cjson_enabled\x18\x06 \x01(\x08\x42\r\x18\x01\xca\xf3\x18\x07Z\x05\x32.8.0\x12L\n\x0btls_enabled\x18\x07 \x01(\x08\x42\x37\xca\xf3\x18\x33:\x0bTLS EnabledB$Connect to the MQTT server over TLS.\x12/\n\x04root\x18\x08 \x01(\tB!\xca\xf3\x18\x1d:\nRoot TopicB\x0fMQTT root topic\x12{\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x42Z\xca\xf3\x18V:\x11MQTT Client ProxyBAUtilizes the network connection on your phone to connect to MQTT.\x12\xb0\x02\n\x15map_reporting_enabled\x18\n \x01(\x08\x42\x90\x02\xca\xf3\x18\x8b\x02:\rMap ReportingB\xf9\x01Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name.\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1a\xea\x02\n\x11MapReportSettings\x12{\n\x15publish_interval_secs\x18\x01 \x01(\rB\\\xca\xf3\x18X\x19\x00\x00\x00\x00\x00 \xac@*\x01s:\x14Map Publish IntervalB4How often a map report is published. Minimum 1 hour.\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\xbb\x01\n\x16should_report_location\x18\x03 \x01(\x08\x42\x9a\x01\xca\xf3\x18\x95\x01:\x0cShare on MapB~Consent to publish this node\'s details and approximate location unencrypted to the MQTT map. No map report is sent without it.R\x05\x32.6.8\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1a\x84\x04\n\x12NeighborInfoConfig\x12\xb2\x01\n\x07\x65nabled\x18\x01 \x01(\x08\x42\xa0\x01\xca\xf3\x18\x9b\x01:\x15Neighbor Info EnabledB\x81\x01\x45nable neighbor info broadcasting. Periodically sends information about directly-heard neighbors to help visualize mesh topology.\x12r\n\x0fupdate_interval\x18\x02 \x01(\rBY\xca\xf3\x18U\x19\x00\x00\x00\x00\x00 \xcc@*\x01s:\x0fUpdate IntervalB6How often to broadcast neighbor info. Minimum 4 hours.\x12\xc4\x01\n\x12transmit_over_lora\x18\x03 \x01(\x08\x42\xa7\x01\xca\xf3\x18\xa2\x01:\x12Transmit over LoRaB\x8b\x01Whether to traLine truncated
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'meshtastic/protobuf/module_config.proto\x12\x13meshtastic.protobuf\x1a\x1emeshtastic/protobuf/atak.proto\"\x86/\n\x0cModuleConfig\x12<\n\x04mqtt\x18\x01 \x01(\x0b\x32,.meshtastic.protobuf.ModuleConfig.MQTTConfigH\x00\x12@\n\x06serial\x18\x02 \x01(\x0b\x32..meshtastic.protobuf.ModuleConfig.SerialConfigH\x00\x12]\n\x15\x65xternal_notification\x18\x03 \x01(\x0b\x32<.meshtastic.protobuf.ModuleConfig.ExternalNotificationConfigH\x00\x12M\n\rstore_forward\x18\x04 \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.StoreForwardConfigH\x00\x12G\n\nrange_test\x18\x05 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.RangeTestConfigH\x00\x12\x46\n\ttelemetry\x18\x06 \x01(\x0b\x32\x31.meshtastic.protobuf.ModuleConfig.TelemetryConfigH\x00\x12O\n\x0e\x63\x61nned_message\x18\x07 \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.CannedMessageConfigH\x00\x12>\n\x05\x61udio\x18\x08 \x01(\x0b\x32-.meshtastic.protobuf.ModuleConfig.AudioConfigH\x00\x12Q\n\x0fremote_hardware\x18\t \x01(\x0b\x32\x36.meshtastic.protobuf.ModuleConfig.RemoteHardwareConfigH\x00\x12M\n\rneighbor_info\x18\n \x01(\x0b\x32\x34.meshtastic.protobuf.ModuleConfig.NeighborInfoConfigH\x00\x12S\n\x10\x61mbient_lighting\x18\x0b \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.AmbientLightingConfigH\x00\x12S\n\x10\x64\x65tection_sensor\x18\x0c \x01(\x0b\x32\x37.meshtastic.protobuf.ModuleConfig.DetectionSensorConfigH\x00\x12H\n\npaxcounter\x18\r \x01(\x0b\x32\x32.meshtastic.protobuf.ModuleConfig.PaxcounterConfigH\x00\x12N\n\rstatusmessage\x18\x0e \x01(\x0b\x32\x35.meshtastic.protobuf.ModuleConfig.StatusMessageConfigH\x00\x12W\n\x12traffic_management\x18\x0f \x01(\x0b\x32\x39.meshtastic.protobuf.ModuleConfig.TrafficManagementConfigH\x00\x12:\n\x03tak\x18\x10 \x01(\x0b\x32+.meshtastic.protobuf.ModuleConfig.TAKConfigH\x00\x1a\xbd\x02\n\nMQTTConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\x12\x10\n\x08username\x18\x03 \x01(\t\x12\x10\n\x08password\x18\x04 \x01(\t\x12\x1a\n\x12\x65ncryption_enabled\x18\x05 \x01(\x08\x12\x18\n\x0cjson_enabled\x18\x06 \x01(\x08\x42\x02\x18\x01\x12\x13\n\x0btls_enabled\x18\x07 \x01(\x08\x12\x0c\n\x04root\x18\x08 \x01(\t\x12\x1f\n\x17proxy_to_client_enabled\x18\t \x01(\x08\x12\x1d\n\x15map_reporting_enabled\x18\n \x01(\x08\x12P\n\x13map_report_settings\x18\x0b \x01(\x0b\x32\x33.meshtastic.protobuf.ModuleConfig.MapReportSettings\x1an\n\x11MapReportSettings\x12\x1d\n\x15publish_interval_secs\x18\x01 \x01(\r\x12\x1a\n\x12position_precision\x18\x02 \x01(\r\x12\x1e\n\x16should_report_location\x18\x03 \x01(\x08\x1a\x8b\x01\n\x14RemoteHardwareConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1a\x61llow_undefined_pin_access\x18\x02 \x01(\x08\x12>\n\x0e\x61vailable_pins\x18\x03 \x03(\x0b\x32&.meshtastic.protobuf.RemoteHardwarePin\x1aZ\n\x12NeighborInfoConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x17\n\x0fupdate_interval\x18\x02 \x01(\r\x12\x1a\n\x12transmit_over_lora\x18\x03 \x01(\x08\x1a\xa0\x03\n\x15\x44\x65tectionSensorConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16minimum_broadcast_secs\x18\x02 \x01(\r\x12\x1c\n\x14state_broadcast_secs\x18\x03 \x01(\r\x12\x11\n\tsend_bell\x18\x04 \x01(\x08\x12\x0c\n\x04name\x18\x05 \x01(\t\x12\x13\n\x0bmonitor_pin\x18\x06 \x01(\r\x12\x63\n\x16\x64\x65tection_trigger_type\x18\x07 \x01(\x0e\x32\x43.meshtastic.protobuf.ModuleConfig.DetectionSensorConfig.TriggerType\x12\x12\n\nuse_pullup\x18\x08 \x01(\x08\"\x88\x01\n\x0bTriggerType\x12\r\n\tLOGIC_LOW\x10\x00\x12\x0e\n\nLOGIC_HIGH\x10\x01\x12\x10\n\x0c\x46\x41LLING_EDGE\x10\x02\x12\x0f\n\x0bRISING_EDGE\x10\x03\x12\x1a\n\x16\x45ITHER_EDGE_ACTIVE_LOW\x10\x04\x12\x1b\n\x17\x45ITHER_EDGE_ACTIVE_HIGH\x10\x05\x1a\xed\x02\n\x0b\x41udioConfig\x12\x16\n\x0e\x63odec2_enabled\x18\x01 \x01(\x08\x12\x0f\n\x07ptt_pin\x18\x02 \x01(\r\x12I\n\x07\x62itrate\x18\x03 \x01(\x0e\x32\x38.meshtastic.protobuf.ModuleConfig.AudioConfig.Audio_Baud\x12\x0e\n\x06i2s_ws\x18\x04 \x01(\r\x12\x0e\n\x06i2s_sd\x18\x05 \x01(\r\x12\x0f\n\x07i2s_din\x18\x06 \x01(\r\x12\x0f\n\x07i2s_sck\x18\x07 \x01(\r\"\xa7\x01\n\nAudio_Baud\x12\x12\n\x0e\x43ODEC2_DEFAULT\x10\x00\x12\x0f\n\x0b\x43ODEC2_3200\x10\x01\x12\x0f\n\x0b\x43ODEC2_2400\x10\x02\x12\x0f\n\x0b\x43ODEC2_1600\x10\x03\x12\x0f\n\x0b\x43ODEC2_1400\x10\x04\x12\x0f\n\x0b\x43ODEC2_1300\x10\x05\x12\x0f\n\x0b\x43ODEC2_1200\x10\x06\x12\x0e\n\nCODEC2_700\x10\x07\x12\x0f\n\x0b\x43ODEC2_700B\x10\x08\x1av\n\x10PaxcounterConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\"\n\x1apaxcounter_update_interval\x18\x02 \x01(\r\x12\x16\n\x0ewifi_threshold\x18\x03 \x01(\x05\x12\x15\n\rble_threshold\x18\x04 \x01(\x05\x1a\xd3\x03\n\x17TrafficManagementConfig\x12\x0f\n\x07\x65nabled\x18\x01 \x01(\x08\x12\x1e\n\x16position_dedup_enabled\x18\x02 \x01(\x08\x12\x1f\n\x17position_precision_bits\x18\x03 \x01(\r\x12\"\n\x1aposition_min_interval_secs\x18\x04 \x01(\r\x12 \n\x18nodeinfo_direct_response\x18\x05 \x01(\x08\x12)\n!nodeinfo_directLine truncated
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.module_config_pb2', globals())
|
||||
@@ -25,368 +22,60 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\022ModuleConfigProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030#:\014MQTT EnabledB\023Enable MQTT gateway'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['address']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['address']._serialized_options = b'\312\363\030\036:\007AddressB\023MQTT server address'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['username']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['username']._serialized_options = b'\312\363\030\031:\010UsernameB\rMQTT username'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['password']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['password']._serialized_options = b'\312\363\030\031:\010PasswordB\rMQTT password'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['encryption_enabled']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['encryption_enabled']._serialized_options = b'\312\363\0304:\022Encryption EnabledB\036Send encrypted packets to MQTT'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['json_enabled']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['json_enabled']._serialized_options = b'\030\001\312\363\030\007Z\0052.8.0'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['tls_enabled']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['tls_enabled']._serialized_options = b'\312\363\0303:\013TLS EnabledB$Connect to the MQTT server over TLS.'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['root']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['root']._serialized_options = b'\312\363\030\035:\nRoot TopicB\017MQTT root topic'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['proxy_to_client_enabled']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['proxy_to_client_enabled']._serialized_options = b'\312\363\030V:\021MQTT Client ProxyBAUtilizes the network connection on your phone to connect to MQTT.'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['map_reporting_enabled']._options = None
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['map_reporting_enabled']._serialized_options = b'\312\363\030\213\002:\rMap ReportingB\371\001Your node will periodically send an unencrypted map report packet to the configured MQTT server, this includes id, short and long name, approximate location, hardware model, role, firmware version, LoRa region, modem preset and primary channel name.'
|
||||
_MODULECONFIG_MAPREPORTSETTINGS.fields_by_name['publish_interval_secs']._options = None
|
||||
_MODULECONFIG_MAPREPORTSETTINGS.fields_by_name['publish_interval_secs']._serialized_options = b'\312\363\030X\031\000\000\000\000\000 \254@*\001s:\024Map Publish IntervalB4How often a map report is published. Minimum 1 hour.'
|
||||
_MODULECONFIG_MAPREPORTSETTINGS.fields_by_name['should_report_location']._options = None
|
||||
_MODULECONFIG_MAPREPORTSETTINGS.fields_by_name['should_report_location']._serialized_options = b'\312\363\030\225\001:\014Share on MapB~Consent to publish this node\'s details and approximate location unencrypted to the MQTT map. No map report is sent without it.R\0052.6.8'
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030\233\001:\025Neighbor Info EnabledB\201\001Enable neighbor info broadcasting. Periodically sends information about directly-heard neighbors to help visualize mesh topology.'
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG.fields_by_name['update_interval']._options = None
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG.fields_by_name['update_interval']._serialized_options = b'\312\363\030U\031\000\000\000\000\000 \314@*\001s:\017Update IntervalB6How often to broadcast neighbor info. Minimum 4 hours.'
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG.fields_by_name['transmit_over_lora']._options = None
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG.fields_by_name['transmit_over_lora']._serialized_options = b'\312\363\030\242\001:\022Transmit over LoRaB\213\001Whether to transmit neighbor info over LoRa in addition to MQTT and the connected app. Not available on channels with default key and name.'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["LOGIC_LOW"]._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["LOGIC_LOW"]._serialized_options = b'\312\363\030\005:\003Low'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["LOGIC_HIGH"]._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["LOGIC_HIGH"]._serialized_options = b'\312\363\030\006:\004High'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["FALLING_EDGE"]._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["FALLING_EDGE"]._serialized_options = b'\312\363\030\016:\014Falling Edge'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["RISING_EDGE"]._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["RISING_EDGE"]._serialized_options = b'\312\363\030\r:\013Rising Edge'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["EITHER_EDGE_ACTIVE_LOW"]._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["EITHER_EDGE_ACTIVE_LOW"]._serialized_options = b'\312\363\030\021:\017Either Edge Low'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["EITHER_EDGE_ACTIVE_HIGH"]._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE.values_by_name["EITHER_EDGE_ACTIVE_HIGH"]._serialized_options = b'\312\363\030\022:\020Either Edge High'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030\354\001:\030Detection Sensor EnabledB\317\001Enables the detection sensor module, it needs to be enabled on both the node with the sensor, and any nodes that you want to receive detection sensor text messages or view the detection sensor log and chart.'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['minimum_broadcast_secs']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['minimum_broadcast_secs']._serialized_options = b'\312\363\030Z*\001s:)Minimum time between detection broadcastsB*Minimum time between detection broadcasts.'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['state_broadcast_secs']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['state_broadcast_secs']._serialized_options = b'\312\363\030\231\001*\001s:\030State Broadcast IntervalBzHow often to send the detection sensor state to the mesh, whether or not anything was detected. 0 sends only on detection.'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['send_bell']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['send_bell']._serialized_options = b'\312\363\030e:\tSend BellBXSend ASCII bell with alert message. Useful for triggering external notification on bell.'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['name']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['name']._serialized_options = b'\312\363\030%:\004NameB\035Sensor name for mesh messages'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['monitor_pin']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['monitor_pin']._serialized_options = b'\312\363\030Q:\023GPIO Pin to monitorB:GPIO pin watched for state changes. 0 disables the module.'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['detection_trigger_type']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['detection_trigger_type']._serialized_options = b'\312\363\030%:\014Trigger TypeB\025Type of trigger event'
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['use_pullup']._options = None
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG.fields_by_name['use_pullup']._serialized_options = b'\312\363\030P:\024Use Internal Pull-upB8Enable the internal pull-up resistor on the monitor pin.'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_DEFAULT"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_DEFAULT"]._serialized_options = b'\312\363\030\t:\007Default'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_3200"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_3200"]._serialized_options = b'\312\363\030\n:\0103200 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_2400"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_2400"]._serialized_options = b'\312\363\030\n:\0102400 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1600"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1600"]._serialized_options = b'\312\363\030\n:\0101600 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1400"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1400"]._serialized_options = b'\312\363\030\n:\0101400 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1300"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1300"]._serialized_options = b'\312\363\030\n:\0101300 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1200"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_1200"]._serialized_options = b'\312\363\030\n:\0101200 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_700"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_700"]._serialized_options = b'\010\001'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_700B"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_700B"]._serialized_options = b'\010\001'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_700C"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_700C"]._serialized_options = b'\312\363\030\020:\016700 bps (700C)'
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_450"]._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD.values_by_name["CODEC2_450"]._serialized_options = b'\312\363\030\t:\007450 bps'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['codec2_enabled']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['codec2_enabled']._serialized_options = b'\312\363\030^:\016Codec2 EnabledBLEnable Codec2 audio encoding/decoding for voice communication over the mesh.'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['ptt_pin']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['ptt_pin']._serialized_options = b'\312\363\0308:\007PTT PinB-Push-to-talk GPIO pin number. 0 uses GPIO 39.'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['bitrate']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['bitrate']._serialized_options = b'\312\363\030\202\001:\007BitrateBwThe Codec2 bitrate to use. The sample rate is always 8 kHz. Lower bitrates use less bandwidth but reduce audio quality.'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_ws']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_ws']._serialized_options = b'\312\363\030\025:\023I2S Word Select Pin'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sd']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sd']._serialized_options = b'\312\363\030\021:\017I2S Data In Pin'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_din']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_din']._serialized_options = b'\312\363\030\022:\020I2S Data Out Pin'
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sck']._options = None
|
||||
_MODULECONFIG_AUDIOCONFIG.fields_by_name['i2s_sck']._serialized_options = b'\312\363\030\017:\rI2S Clock Pin'
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030\250\001:\023PAX Counter EnabledB\220\001When enabled, the PAX Counter module counts nearby WiFi and Bluetooth devices. Both WiFi and Bluetooth must be disabled for PAX counter to work.'
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['paxcounter_update_interval']._options = None
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['paxcounter_update_interval']._serialized_options = b'\312\363\030F*\001s:\017Update IntervalB0How often to send the device counts to the mesh.'
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['wifi_threshold']._options = None
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['wifi_threshold']._serialized_options = b'\312\363\030@*\003dBm:\016WiFi ThresholdB)RSSI threshold for counting WiFi devices.'
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['ble_threshold']._options = None
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG.fields_by_name['ble_threshold']._serialized_options = b'\312\363\030>*\003dBm:\rBLE ThresholdB(RSSI threshold for counting BLE devices.'
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['position_min_interval_secs']._options = None
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['position_min_interval_secs']._serialized_options = b'\312\363\030c*\001s:\031Minimum Position IntervalBCPositions from the same node arriving sooner than this are dropped.'
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['nodeinfo_direct_response_max_hops']._options = None
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['nodeinfo_direct_response_max_hops']._serialized_options = b'\312\363\030\261\001!\000\000\000\000\000\000\010@:\030Direct NodeInfo Max HopsB\213\001Answer NodeInfo requests from cache for requestors within this many hops. Capped at 3 on routers; other roles answer direct neighbors only.'
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['rate_limit_window_secs']._options = None
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['rate_limit_window_secs']._serialized_options = b'\312\363\030A*\001s:\021Rate Limit WindowB)The time window packets are counted over.'
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['rate_limit_max_packets']._options = None
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['rate_limit_max_packets']._serialized_options = b'\312\363\030Q!\000\000\000\000\000\000N@:\026Rate Limit Max PacketsB.The most packets one node may send per window.'
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['unknown_packet_threshold']._options = None
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG.fields_by_name['unknown_packet_threshold']._serialized_options = b'\312\363\030o!\000\000\000\000\000\000N@:\030Unknown Packet ThresholdBJUndecryptable packets one node may send in 5 minutes before it is dropped.'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_DEFAULT"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_DEFAULT"]._serialized_options = b'\312\363\030\t:\007Default'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_110"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_110"]._serialized_options = b'\312\363\030\n:\010110 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_300"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_300"]._serialized_options = b'\312\363\030\n:\010300 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_600"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_600"]._serialized_options = b'\312\363\030\n:\010600 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_1200"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_1200"]._serialized_options = b'\312\363\030\013:\t1200 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_2400"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_2400"]._serialized_options = b'\312\363\030\013:\t2400 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_4800"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_4800"]._serialized_options = b'\312\363\030\013:\t4800 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_9600"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_9600"]._serialized_options = b'\312\363\030\013:\t9600 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_19200"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_19200"]._serialized_options = b'\312\363\030\014:\n19200 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_38400"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_38400"]._serialized_options = b'\312\363\030\014:\n38400 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_57600"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_57600"]._serialized_options = b'\312\363\030\014:\n57600 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_115200"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_115200"]._serialized_options = b'\312\363\030\r:\013115200 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_230400"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_230400"]._serialized_options = b'\312\363\030\r:\013230400 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_460800"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_460800"]._serialized_options = b'\312\363\030\r:\013460800 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_576000"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_576000"]._serialized_options = b'\312\363\030\r:\013576000 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_921600"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD.values_by_name["BAUD_921600"]._serialized_options = b'\312\363\030\r:\013921600 Baud'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["DEFAULT"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["DEFAULT"]._serialized_options = b'\312\363\030\t:\007Default'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["SIMPLE"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["SIMPLE"]._serialized_options = b'\312\363\030\010:\006Simple'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["PROTO"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["PROTO"]._serialized_options = b'\312\363\030\013:\tProtobufs'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["TEXTMSG"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["TEXTMSG"]._serialized_options = b'\312\363\030\016:\014Text Message'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["NMEA"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["NMEA"]._serialized_options = b'\312\363\030\020:\016NMEA Positions'
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["CALTOPO"]._options = None
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE.values_by_name["CALTOPO"]._serialized_options = b'\312\363\030\t:\007CalTopo'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030&:\016Serial EnabledB\024Enable serial module'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['echo']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['echo']._serialized_options = b'\312\363\030N:\004EchoBFIf set, any packets you send will be echoed back over the serial port.'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['rxd']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['rxd']._serialized_options = b'\312\363\030,:\033Receive data (rxd) GPIO pinB\rRX pin number'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['txd']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['txd']._serialized_options = b'\312\363\030-:\034Transmit data (txd) GPIO pinB\rTX pin number'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['baud']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['baud']._serialized_options = b'\312\363\030\030:\004BaudB\020Serial baud rate'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['timeout']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['timeout']._serialized_options = b'\312\363\030i*\002ms:\007TimeoutBZHow long to wait before treating received serial data as a complete packet. 0 uses 250 ms.'
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['mode']._options = None
|
||||
_MODULECONFIG_SERIALCONFIG.fields_by_name['mode']._serialized_options = b'\312\363\030$:\004ModeB\034Serial module operation mode'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030>:\035External Notification EnabledB\035Enable external notifications'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_ms']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_ms']._serialized_options = b'\312\363\030I*\002ms:\024GPIO Output DurationB-In GPIO mode, how long to keep the output on.'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output']._serialized_options = b'\312\363\030_:\017Output pin GPIOBLGPIO pin driven on notification. Defaults to the board\'s EXT_NOTIFY_OUT pin.'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_vibra']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_vibra']._serialized_options = b'\312\363\0303:\025Output pin vibra GPIOB\032Vibration motor output pin'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_buzzer']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['output_buzzer']._serialized_options = b'\312\363\030+:\026Output pin buzzer GPIOB\021Buzzer output pin'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['active']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['active']._serialized_options = b'\312\363\030]:\006ActiveBSIf enabled, the \'output\' Pin will be pulled active high, disabled means active low.'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_message']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_message']._serialized_options = b'\312\363\030;:\036Alert when receiving a messageB\031Alert on incoming message'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_message_vibra']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_message_vibra']._serialized_options = b'\312\363\030D:\021Vibra Motor AlertB/Alert GPIO vibra motor when receiving a message'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_message_buzzer']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_message_buzzer']._serialized_options = b'\312\363\030F:*Alert GPIO buzzer when receiving a messageB\030Buzz on incoming message'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_bell']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_bell']._serialized_options = b'\312\363\0306:\033Alert when receiving a bellB\027Alert on bell character'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_bell_vibra']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_bell_vibra']._serialized_options = b'\312\363\030I:,Alert GPIO vibra motor when receiving a bellB\031Vibrate on bell character'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_bell_buzzer']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['alert_bell_buzzer']._serialized_options = b'\312\363\030A:\'Alert GPIO buzzer when receiving a bellB\026Buzz on bell character'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['use_pwm']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['use_pwm']._serialized_options = b'\312\363\030\327\001:\016Use PWM BuzzerB\304\001Use a PWM output (like the RAK Buzzer) for tunes instead of an on/off output. This will ignore the output, output duration and active settings and use the device config buzzer GPIO option instead.'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['nag_timeout']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['nag_timeout']._serialized_options = b'\312\363\0302*\001s:\013Nag TimeoutB How long the notification lasts.'
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['use_i2s_as_buzzer']._options = None
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG.fields_by_name['use_i2s_as_buzzer']._serialized_options = b'\312\363\030\247\001:\021Use I2S As BuzzerB\221\001Enables devices with native I2S audio output to use the RTTTL over speaker like a buzzer. T-Watch S3 and T-Deck for example have this capability.'
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030B:\031Store and Forward EnabledB%Enables the store and forward module.'
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['heartbeat']._options = None
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['heartbeat']._serialized_options = b'\312\363\030F:\016Send HeartbeatB4Send a heartbeat to advertise the server\'s presence.'
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['records']._options = None
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['records']._serialized_options = b'\312\363\030^:\021Number of recordsBIMaximum number of messages to store. 0 uses three quarters of free PSRAM.'
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['history_return_max']._options = None
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['history_return_max']._serialized_options = b'\312\363\030X:\022History Return MaxBBMaximum number of stored messages returned per request. 0 uses 25.'
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['history_return_window']._options = None
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['history_return_window']._serialized_options = b'\312\363\030\\:\025History Return WindowBCHow far back, in minutes, stored messages are returned. 0 uses 240.'
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['is_server']._options = None
|
||||
_MODULECONFIG_STOREFORWARDCONFIG.fields_by_name['is_server']._serialized_options = b'\312\363\030`:\006ServerBVEnable this device as a Store and Forward server. Requires an ESP32 device with PSRAM.'
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['enabled']._serialized_options = b'\312\363\030.:\022Range Test EnabledB\030Enable range test module'
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['sender']._options = None
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['sender']._serialized_options = b'\312\363\030q*\001s:\017Sender IntervalB[This device will send out range test messages on the selected interval. 0 disables sending.'
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['save']._options = None
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['save']._serialized_options = b'\312\363\030u:\004SaveBmSaves a CSV with the range test message details, currently only available on ESP32 devices with a web server.'
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['clear_on_reboot']._options = None
|
||||
_MODULECONFIG_RANGETESTCONFIG.fields_by_name['clear_on_reboot']._serialized_options = b'\312\363\030\010R\0062.7.11'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['device_update_interval']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['device_update_interval']._serialized_options = b'\312\363\030N*\001s:\027Device Metrics IntervalB0How often device metrics are sent over the mesh.'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_update_interval']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_update_interval']._serialized_options = b'\312\363\030X*\001s:\034Environment Metrics IntervalB5How often environment metrics are sent over the mesh.'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_measurement_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_measurement_enabled']._serialized_options = b'\312\363\030?:\033Environment Metrics EnabledB Collect environment measurements'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_screen_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_screen_enabled']._serialized_options = b'\312\363\030C:\025Show on device screenB*Display environment measurements on device'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_display_fahrenheit']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['environment_display_fahrenheit']._serialized_options = b'\312\363\0307:\022Display FahrenheitB!Display environment in Fahrenheit'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['air_quality_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['air_quality_enabled']._serialized_options = b'\312\363\030::\033Air Quality Metrics EnabledB\033Collect air quality metrics'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['air_quality_interval']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['air_quality_interval']._serialized_options = b'\312\363\030X*\001s:\034Air Quality Metrics IntervalB5How often air quality metrics are sent over the mesh.'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['power_measurement_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['power_measurement_enabled']._serialized_options = b'\312\363\0302:\031Power Measurement EnabledB\025Collect power metrics'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['power_update_interval']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['power_update_interval']._serialized_options = b'\312\363\030L*\001s:\026Power Metrics IntervalB/How often power metrics are sent over the mesh.'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['power_screen_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['power_screen_enabled']._serialized_options = b'\312\363\030/:\014Power ScreenB\037Display power metrics on device'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['device_telemetry_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['device_telemetry_enabled']._serialized_options = b'\312\363\030\226\001:\030Broadcast Device MetricsBrEnable broadcasting device metrics to the mesh network. When disabled, metrics are only sent to connected clients.R\0062.7.13'
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['air_quality_screen_enabled']._options = None
|
||||
_MODULECONFIG_TELEMETRYCONFIG.fields_by_name['air_quality_screen_enabled']._serialized_options = b'\312\363\030\010R\0062.7.18'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["NONE"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["NONE"]._serialized_options = b'\312\363\030\006:\004None'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["UP"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["UP"]._serialized_options = b'\312\363\030\004:\002Up'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["DOWN"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["DOWN"]._serialized_options = b'\312\363\030\006:\004Down'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["LEFT"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["LEFT"]._serialized_options = b'\312\363\030\006:\004Left'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["RIGHT"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["RIGHT"]._serialized_options = b'\312\363\030\007:\005Right'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["SELECT"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["SELECT"]._serialized_options = b'\312\363\030\010:\006Select'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["BACK"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["BACK"]._serialized_options = b'\312\363\030\006:\004Back'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["CANCEL"]._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR.values_by_name["CANCEL"]._serialized_options = b'\312\363\030\010:\006Cancel'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['rotary1_enabled']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['rotary1_enabled']._serialized_options = b'\312\363\030\':\016Rotary EncoderB\025Enable rotary encoder'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_pin_a']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_pin_a']._serialized_options = b'\312\363\030,:\005Pin AB#GPIO pin for rotary encoder A port.'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_pin_b']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_pin_b']._serialized_options = b'\312\363\030,:\005Pin BB#GPIO pin for rotary encoder B port.'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_pin_press']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_pin_press']._serialized_options = b'\312\363\0303:\tPress PinB&GPIO pin for the encoder press button.'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_event_cw']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_event_cw']._serialized_options = b'\312\363\030<:\026Clockwise Rotary EventB\"Input event for clockwise rotation'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_event_ccw']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_event_ccw']._serialized_options = b'\312\363\030K:\035Counterclockwise Rotary EventB*Input event for counter-clockwise rotation'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_event_press']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['inputbroker_event_press']._serialized_options = b'\312\363\0304:\023Encoder Press EventB\035Input event for encoder press'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['updown1_enabled']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['updown1_enabled']._serialized_options = b'\312\363\0303:\024Up/Down/Select InputB\033Enable up/down/select input'
|
||||
_MODULECONFIG_MQTTCONFIG.fields_by_name['json_enabled']._serialized_options = b'\030\001'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['enabled']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['enabled']._serialized_options = b'\030\001\312\363\030\007Z\0052.7.0'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['enabled']._serialized_options = b'\030\001'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._serialized_options = b'\030\001\312\363\030\007Z\0052.7.0'
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['send_bell']._options = None
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['send_bell']._serialized_options = b'\312\363\030.:\tSend BellB!Send bell character with messages'
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['led_state']._options = None
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['led_state']._serialized_options = b'\312\363\030*:\tLED StateB\035The state of the LED (on/off)'
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['current']._options = None
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['current']._serialized_options = b'\312\363\030_\031\000\000\000\000\000\000\000\000!\000\000\000\000\000\000?@:\007CurrentB!Drive current for the LED output.J\037led|brightness|ambient|lighting'
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['red']._options = None
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['red']._serialized_options = b'\312\363\030j\031\000\000\000\000\000\000\000\000!\000\000\000\000\000\340o@:\003RedB*The red level of the ambient lighting LED.J%color|colour|rgb|led|ambient|lighting'
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['green']._options = None
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['green']._serialized_options = b'\312\363\030n\031\000\000\000\000\000\000\000\000!\000\000\000\000\000\340o@:\005GreenB,The green level of the ambient lighting LED.J%color|colour|rgb|led|ambient|lighting'
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['blue']._options = None
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG.fields_by_name['blue']._serialized_options = b'\312\363\030l\031\000\000\000\000\000\000\000\000!\000\000\000\000\000\340o@:\004BlueB+The blue level of the ambient lighting LED.J%color|colour|rgb|led|ambient|lighting'
|
||||
_MODULECONFIG_MESHBEACONCONFIG.fields_by_name['broadcast_message']._options = None
|
||||
_MODULECONFIG_MESHBEACONCONFIG.fields_by_name['broadcast_message']._serialized_options = b'\312\363\0309:\007MessageB.Message for beacon broadcasts, up to 60 bytes.'
|
||||
_MODULECONFIG_MESHBEACONCONFIG.fields_by_name['broadcast_interval_secs']._options = None
|
||||
_MODULECONFIG_MESHBEACONCONFIG.fields_by_name['broadcast_interval_secs']._serialized_options = b'\312\363\030H\031\000\000\000\000\000 \254@*\001s:\010IntervalB0How often a beacon is broadcast. Minimum 1 hour.'
|
||||
_MODULECONFIG_TAKCONFIG.fields_by_name['team']._options = None
|
||||
_MODULECONFIG_TAKCONFIG.fields_by_name['team']._serialized_options = b'\312\363\030\026:\004TeamB\016TAK team color'
|
||||
_MODULECONFIG_TAKCONFIG.fields_by_name['role']._options = None
|
||||
_MODULECONFIG_TAKCONFIG.fields_by_name['role']._serialized_options = b'\312\363\030\027:\004RoleB\017TAK member role'
|
||||
_MODULECONFIG.fields_by_name['statusmessage']._options = None
|
||||
_MODULECONFIG.fields_by_name['statusmessage']._serialized_options = b'\312\363\030\010R\0062.7.20'
|
||||
_MODULECONFIG.fields_by_name['traffic_management']._options = None
|
||||
_MODULECONFIG.fields_by_name['traffic_management']._serialized_options = b'\312\363\030\007R\0052.8.0'
|
||||
_MODULECONFIG.fields_by_name['tak']._options = None
|
||||
_MODULECONFIG.fields_by_name['tak']._serialized_options = b'\312\363\030\007R\0052.8.0'
|
||||
_MODULECONFIG.fields_by_name['mesh_beacon']._options = None
|
||||
_MODULECONFIG.fields_by_name['mesh_beacon']._serialized_options = b'\312\363\030\007R\0052.8.0'
|
||||
_REMOTEHARDWAREPINTYPE._serialized_start=16574
|
||||
_REMOTEHARDWAREPINTYPE._serialized_end=16647
|
||||
_MODULECONFIG._serialized_start=208
|
||||
_MODULECONFIG._serialized_end=16461
|
||||
_MODULECONFIG_MQTTCONFIG._serialized_start=1580
|
||||
_MODULECONFIG_MQTTCONFIG._serialized_end=2565
|
||||
_MODULECONFIG_MAPREPORTSETTINGS._serialized_start=2568
|
||||
_MODULECONFIG_MAPREPORTSETTINGS._serialized_end=2930
|
||||
_MODULECONFIG_REMOTEHARDWARECONFIG._serialized_start=2933
|
||||
_MODULECONFIG_REMOTEHARDWARECONFIG._serialized_end=3072
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG._serialized_start=3075
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG._serialized_end=3591
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG._serialized_start=3594
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG._serialized_end=4989
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE._serialized_start=4744
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE._serialized_end=4989
|
||||
_MODULECONFIG_AUDIOCONFIG._serialized_start=4992
|
||||
_MODULECONFIG_AUDIOCONFIG._serialized_end=5942
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD._serialized_start=5586
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD._serialized_end=5942
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG._serialized_start=5945
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG._serialized_end=6454
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG._serialized_start=6457
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG._serialized_end=7474
|
||||
_MODULECONFIG_SERIALCONFIG._serialized_start=7477
|
||||
_MODULECONFIG_SERIALCONFIG._serialized_end=8977
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_start=8166
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_end=8712
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_start=8715
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_end=8977
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_start=8980
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_end=10675
|
||||
_MODULECONFIG_STOREFORWARDCONFIG._serialized_start=10678
|
||||
_MODULECONFIG_STOREFORWARDCONFIG._serialized_end=11371
|
||||
_MODULECONFIG_RANGETESTCONFIG._serialized_start=11374
|
||||
_MODULECONFIG_RANGETESTCONFIG._serialized_end=11773
|
||||
_MODULECONFIG_TELEMETRYCONFIG._serialized_start=11776
|
||||
_MODULECONFIG_TELEMETRYCONFIG._serialized_end=13207
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG._serialized_start=13210
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG._serialized_end=14484
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_start=14286
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_end=14484
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG._serialized_start=14487
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG._serialized_end=15080
|
||||
_MODULECONFIG_STATUSMESSAGECONFIG._serialized_start=15082
|
||||
_MODULECONFIG_STATUSMESSAGECONFIG._serialized_end=15124
|
||||
_MODULECONFIG_MESHBEACONCONFIG._serialized_start=15127
|
||||
_MODULECONFIG_MESHBEACONCONFIG._serialized_end=16283
|
||||
_MODULECONFIG_MESHBEACONCONFIG_BROADCASTTARGET._serialized_start=15747
|
||||
_MODULECONFIG_MESHBEACONCONFIG_BROADCASTTARGET._serialized_end=16009
|
||||
_MODULECONFIG_MESHBEACONCONFIG_FLAGS._serialized_start=16011
|
||||
_MODULECONFIG_MESHBEACONCONFIG_FLAGS._serialized_end=16109
|
||||
_MODULECONFIG_TAKCONFIG._serialized_start=16286
|
||||
_MODULECONFIG_TAKCONFIG._serialized_end=16442
|
||||
_REMOTEHARDWAREPIN._serialized_start=16463
|
||||
_REMOTEHARDWAREPIN._serialized_end=16572
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG.fields_by_name['allow_input_source']._serialized_options = b'\030\001'
|
||||
_REMOTEHARDWAREPINTYPE._serialized_start=6232
|
||||
_REMOTEHARDWAREPINTYPE._serialized_end=6305
|
||||
_MODULECONFIG._serialized_start=97
|
||||
_MODULECONFIG._serialized_end=6119
|
||||
_MODULECONFIG_MQTTCONFIG._serialized_start=1341
|
||||
_MODULECONFIG_MQTTCONFIG._serialized_end=1658
|
||||
_MODULECONFIG_MAPREPORTSETTINGS._serialized_start=1660
|
||||
_MODULECONFIG_MAPREPORTSETTINGS._serialized_end=1770
|
||||
_MODULECONFIG_REMOTEHARDWARECONFIG._serialized_start=1773
|
||||
_MODULECONFIG_REMOTEHARDWARECONFIG._serialized_end=1912
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG._serialized_start=1914
|
||||
_MODULECONFIG_NEIGHBORINFOCONFIG._serialized_end=2004
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG._serialized_start=2007
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG._serialized_end=2423
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE._serialized_start=2287
|
||||
_MODULECONFIG_DETECTIONSENSORCONFIG_TRIGGERTYPE._serialized_end=2423
|
||||
_MODULECONFIG_AUDIOCONFIG._serialized_start=2426
|
||||
_MODULECONFIG_AUDIOCONFIG._serialized_end=2791
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD._serialized_start=2624
|
||||
_MODULECONFIG_AUDIOCONFIG_AUDIO_BAUD._serialized_end=2791
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG._serialized_start=2793
|
||||
_MODULECONFIG_PAXCOUNTERCONFIG._serialized_end=2911
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG._serialized_start=2914
|
||||
_MODULECONFIG_TRAFFICMANAGEMENTCONFIG._serialized_end=3381
|
||||
_MODULECONFIG_SERIALCONFIG._serialized_start=3384
|
||||
_MODULECONFIG_SERIALCONFIG._serialized_end=4077
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_start=3661
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_BAUD._serialized_end=3927
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_start=3930
|
||||
_MODULECONFIG_SERIALCONFIG_SERIAL_MODE._serialized_end=4077
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_start=4080
|
||||
_MODULECONFIG_EXTERNALNOTIFICATIONCONFIG._serialized_end=4441
|
||||
_MODULECONFIG_STOREFORWARDCONFIG._serialized_start=4444
|
||||
_MODULECONFIG_STOREFORWARDCONFIG._serialized_end=4595
|
||||
_MODULECONFIG_RANGETESTCONFIG._serialized_start=4597
|
||||
_MODULECONFIG_RANGETESTCONFIG._serialized_end=4686
|
||||
_MODULECONFIG_TELEMETRYCONFIG._serialized_start=4689
|
||||
_MODULECONFIG_TELEMETRYCONFIG._serialized_end=5216
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG._serialized_start=5219
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG._serialized_end=5852
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_start=5753
|
||||
_MODULECONFIG_CANNEDMESSAGECONFIG_INPUTEVENTCHAR._serialized_end=5852
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG._serialized_start=5854
|
||||
_MODULECONFIG_AMBIENTLIGHTINGCONFIG._serialized_end=5955
|
||||
_MODULECONFIG_STATUSMESSAGECONFIG._serialized_start=5957
|
||||
_MODULECONFIG_STATUSMESSAGECONFIG._serialized_end=5999
|
||||
_MODULECONFIG_TAKCONFIG._serialized_start=6001
|
||||
_MODULECONFIG_TAKCONFIG._serialized_end=6100
|
||||
_REMOTEHARDWAREPIN._serialized_start=6121
|
||||
_REMOTEHARDWAREPIN._serialized_end=6230
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -1,7 +1,4 @@
|
||||
from meshtastic.protobuf import atak_pb2 as _atak_pb2
|
||||
from meshtastic.protobuf import channel_pb2 as _channel_pb2
|
||||
from meshtastic.protobuf import config_pb2 as _config_pb2
|
||||
from meshtastic.protobuf import field_metadata_pb2 as _field_metadata_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
|
||||
@@ -14,7 +11,7 @@ DIGITAL_WRITE: RemoteHardwarePinType
|
||||
UNKNOWN: RemoteHardwarePinType
|
||||
|
||||
class ModuleConfig(_message.Message):
|
||||
__slots__ = ["ambient_lighting", "audio", "canned_message", "detection_sensor", "external_notification", "mesh_beacon", "mqtt", "neighbor_info", "paxcounter", "range_test", "remote_hardware", "serial", "statusmessage", "store_forward", "tak", "telemetry", "traffic_management"]
|
||||
__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"]
|
||||
class AmbientLightingConfig(_message.Message):
|
||||
__slots__ = ["blue", "current", "green", "led_state", "red"]
|
||||
BLUE_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -39,10 +36,8 @@ class ModuleConfig(_message.Message):
|
||||
CODEC2_1600: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_2400: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_3200: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_450: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_700: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_700B: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_700C: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_DEFAULT: ModuleConfig.AudioConfig.Audio_Baud
|
||||
CODEC2_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
I2S_DIN_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -187,42 +182,6 @@ class ModuleConfig(_message.Message):
|
||||
publish_interval_secs: int
|
||||
should_report_location: bool
|
||||
def __init__(self, publish_interval_secs: _Optional[int] = ..., position_precision: _Optional[int] = ..., should_report_location: bool = ...) -> None: ...
|
||||
class MeshBeaconConfig(_message.Message):
|
||||
__slots__ = ["broadcast_interval_secs", "broadcast_message", "broadcast_offer_channel", "broadcast_offer_frequency_slot", "broadcast_offer_preset", "broadcast_offer_region", "broadcast_targets", "flags"]
|
||||
class Flags(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class BroadcastTarget(_message.Message):
|
||||
__slots__ = ["channel_index", "frequency_slot", "preset", "region"]
|
||||
CHANNEL_INDEX_FIELD_NUMBER: _ClassVar[int]
|
||||
FREQUENCY_SLOT_FIELD_NUMBER: _ClassVar[int]
|
||||
PRESET_FIELD_NUMBER: _ClassVar[int]
|
||||
REGION_FIELD_NUMBER: _ClassVar[int]
|
||||
channel_index: int
|
||||
frequency_slot: int
|
||||
preset: _config_pb2.Config.LoRaConfig.ModemPreset
|
||||
region: _config_pb2.Config.LoRaConfig.RegionCode
|
||||
def __init__(self, preset: _Optional[_Union[_config_pb2.Config.LoRaConfig.ModemPreset, str]] = ..., region: _Optional[_Union[_config_pb2.Config.LoRaConfig.RegionCode, str]] = ..., channel_index: _Optional[int] = ..., frequency_slot: _Optional[int] = ...) -> None: ...
|
||||
BROADCAST_INTERVAL_SECS_FIELD_NUMBER: _ClassVar[int]
|
||||
BROADCAST_MESSAGE_FIELD_NUMBER: _ClassVar[int]
|
||||
BROADCAST_OFFER_CHANNEL_FIELD_NUMBER: _ClassVar[int]
|
||||
BROADCAST_OFFER_FREQUENCY_SLOT_FIELD_NUMBER: _ClassVar[int]
|
||||
BROADCAST_OFFER_PRESET_FIELD_NUMBER: _ClassVar[int]
|
||||
BROADCAST_OFFER_REGION_FIELD_NUMBER: _ClassVar[int]
|
||||
BROADCAST_TARGETS_FIELD_NUMBER: _ClassVar[int]
|
||||
FLAGS_FIELD_NUMBER: _ClassVar[int]
|
||||
FLAG_BROADCAST_ENABLED: ModuleConfig.MeshBeaconConfig.Flags
|
||||
FLAG_LEGACY_SPLIT: ModuleConfig.MeshBeaconConfig.Flags
|
||||
FLAG_LISTEN_ENABLED: ModuleConfig.MeshBeaconConfig.Flags
|
||||
FLAG_NONE: ModuleConfig.MeshBeaconConfig.Flags
|
||||
broadcast_interval_secs: int
|
||||
broadcast_message: str
|
||||
broadcast_offer_channel: _channel_pb2.ChannelSettings
|
||||
broadcast_offer_frequency_slot: int
|
||||
broadcast_offer_preset: _config_pb2.Config.LoRaConfig.ModemPreset
|
||||
broadcast_offer_region: _config_pb2.Config.LoRaConfig.RegionCode
|
||||
broadcast_targets: _containers.RepeatedCompositeFieldContainer[ModuleConfig.MeshBeaconConfig.BroadcastTarget]
|
||||
flags: int
|
||||
def __init__(self, flags: _Optional[int] = ..., broadcast_offer_frequency_slot: _Optional[int] = ..., broadcast_message: _Optional[str] = ..., broadcast_offer_channel: _Optional[_Union[_channel_pb2.ChannelSettings, _Mapping]] = ..., broadcast_offer_region: _Optional[_Union[_config_pb2.Config.LoRaConfig.RegionCode, str]] = ..., broadcast_offer_preset: _Optional[_Union[_config_pb2.Config.LoRaConfig.ModemPreset, str]] = ..., broadcast_interval_secs: _Optional[int] = ..., broadcast_targets: _Optional[_Iterable[_Union[ModuleConfig.MeshBeaconConfig.BroadcastTarget, _Mapping]]] = ...) -> None: ...
|
||||
class NeighborInfoConfig(_message.Message):
|
||||
__slots__ = ["enabled", "transmit_over_lora", "update_interval"]
|
||||
ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -292,7 +251,6 @@ class ModuleConfig(_message.Message):
|
||||
ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
LOG: ModuleConfig.SerialConfig.Serial_Mode
|
||||
LOGTEXT: ModuleConfig.SerialConfig.Serial_Mode
|
||||
MODBUS: ModuleConfig.SerialConfig.Serial_Mode
|
||||
MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
MS_CONFIG: ModuleConfig.SerialConfig.Serial_Mode
|
||||
NMEA: ModuleConfig.SerialConfig.Serial_Mode
|
||||
@@ -375,24 +333,41 @@ class ModuleConfig(_message.Message):
|
||||
power_update_interval: int
|
||||
def __init__(self, device_update_interval: _Optional[int] = ..., environment_update_interval: _Optional[int] = ..., environment_measurement_enabled: bool = ..., environment_screen_enabled: bool = ..., environment_display_fahrenheit: bool = ..., air_quality_enabled: bool = ..., air_quality_interval: _Optional[int] = ..., power_measurement_enabled: bool = ..., power_update_interval: _Optional[int] = ..., power_screen_enabled: bool = ..., health_measurement_enabled: bool = ..., health_update_interval: _Optional[int] = ..., health_screen_enabled: bool = ..., device_telemetry_enabled: bool = ..., air_quality_screen_enabled: bool = ...) -> None: ...
|
||||
class TrafficManagementConfig(_message.Message):
|
||||
__slots__ = ["nodeinfo_direct_response_max_hops", "position_min_interval_secs", "rate_limit_max_packets", "rate_limit_window_secs", "unknown_packet_threshold"]
|
||||
__slots__ = ["drop_unknown_enabled", "enabled", "exhaust_hop_position", "exhaust_hop_telemetry", "nodeinfo_direct_response", "nodeinfo_direct_response_max_hops", "position_dedup_enabled", "position_min_interval_secs", "position_precision_bits", "rate_limit_enabled", "rate_limit_max_packets", "rate_limit_window_secs", "router_preserve_hops", "unknown_packet_threshold"]
|
||||
DROP_UNKNOWN_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
EXHAUST_HOP_POSITION_FIELD_NUMBER: _ClassVar[int]
|
||||
EXHAUST_HOP_TELEMETRY_FIELD_NUMBER: _ClassVar[int]
|
||||
NODEINFO_DIRECT_RESPONSE_FIELD_NUMBER: _ClassVar[int]
|
||||
NODEINFO_DIRECT_RESPONSE_MAX_HOPS_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_DEDUP_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_MIN_INTERVAL_SECS_FIELD_NUMBER: _ClassVar[int]
|
||||
POSITION_PRECISION_BITS_FIELD_NUMBER: _ClassVar[int]
|
||||
RATE_LIMIT_ENABLED_FIELD_NUMBER: _ClassVar[int]
|
||||
RATE_LIMIT_MAX_PACKETS_FIELD_NUMBER: _ClassVar[int]
|
||||
RATE_LIMIT_WINDOW_SECS_FIELD_NUMBER: _ClassVar[int]
|
||||
ROUTER_PRESERVE_HOPS_FIELD_NUMBER: _ClassVar[int]
|
||||
UNKNOWN_PACKET_THRESHOLD_FIELD_NUMBER: _ClassVar[int]
|
||||
drop_unknown_enabled: bool
|
||||
enabled: bool
|
||||
exhaust_hop_position: bool
|
||||
exhaust_hop_telemetry: bool
|
||||
nodeinfo_direct_response: bool
|
||||
nodeinfo_direct_response_max_hops: int
|
||||
position_dedup_enabled: bool
|
||||
position_min_interval_secs: int
|
||||
position_precision_bits: int
|
||||
rate_limit_enabled: bool
|
||||
rate_limit_max_packets: int
|
||||
rate_limit_window_secs: int
|
||||
router_preserve_hops: bool
|
||||
unknown_packet_threshold: int
|
||||
def __init__(self, position_min_interval_secs: _Optional[int] = ..., nodeinfo_direct_response_max_hops: _Optional[int] = ..., rate_limit_window_secs: _Optional[int] = ..., rate_limit_max_packets: _Optional[int] = ..., unknown_packet_threshold: _Optional[int] = ...) -> None: ...
|
||||
def __init__(self, enabled: bool = ..., position_dedup_enabled: bool = ..., position_precision_bits: _Optional[int] = ..., position_min_interval_secs: _Optional[int] = ..., nodeinfo_direct_response: bool = ..., nodeinfo_direct_response_max_hops: _Optional[int] = ..., rate_limit_enabled: bool = ..., rate_limit_window_secs: _Optional[int] = ..., rate_limit_max_packets: _Optional[int] = ..., drop_unknown_enabled: bool = ..., unknown_packet_threshold: _Optional[int] = ..., exhaust_hop_telemetry: bool = ..., exhaust_hop_position: bool = ..., router_preserve_hops: bool = ...) -> None: ...
|
||||
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]
|
||||
MESH_BEACON_FIELD_NUMBER: _ClassVar[int]
|
||||
MQTT_FIELD_NUMBER: _ClassVar[int]
|
||||
NEIGHBOR_INFO_FIELD_NUMBER: _ClassVar[int]
|
||||
PAXCOUNTER_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -409,7 +384,6 @@ class ModuleConfig(_message.Message):
|
||||
canned_message: ModuleConfig.CannedMessageConfig
|
||||
detection_sensor: ModuleConfig.DetectionSensorConfig
|
||||
external_notification: ModuleConfig.ExternalNotificationConfig
|
||||
mesh_beacon: ModuleConfig.MeshBeaconConfig
|
||||
mqtt: ModuleConfig.MQTTConfig
|
||||
neighbor_info: ModuleConfig.NeighborInfoConfig
|
||||
paxcounter: ModuleConfig.PaxcounterConfig
|
||||
@@ -421,7 +395,7 @@ class ModuleConfig(_message.Message):
|
||||
tak: ModuleConfig.TAKConfig
|
||||
telemetry: ModuleConfig.TelemetryConfig
|
||||
traffic_management: ModuleConfig.TrafficManagementConfig
|
||||
def __init__(self, mqtt: _Optional[_Union[ModuleConfig.MQTTConfig, _Mapping]] = ..., serial: _Optional[_Union[ModuleConfig.SerialConfig, _Mapping]] = ..., external_notification: _Optional[_Union[ModuleConfig.ExternalNotificationConfig, _Mapping]] = ..., store_forward: _Optional[_Union[ModuleConfig.StoreForwardConfig, _Mapping]] = ..., range_test: _Optional[_Union[ModuleConfig.RangeTestConfig, _Mapping]] = ..., telemetry: _Optional[_Union[ModuleConfig.TelemetryConfig, _Mapping]] = ..., canned_message: _Optional[_Union[ModuleConfig.CannedMessageConfig, _Mapping]] = ..., audio: _Optional[_Union[ModuleConfig.AudioConfig, _Mapping]] = ..., remote_hardware: _Optional[_Union[ModuleConfig.RemoteHardwareConfig, _Mapping]] = ..., neighbor_info: _Optional[_Union[ModuleConfig.NeighborInfoConfig, _Mapping]] = ..., ambient_lighting: _Optional[_Union[ModuleConfig.AmbientLightingConfig, _Mapping]] = ..., detection_sensor: _Optional[_Union[ModuleConfig.DetectionSensorConfig, _Mapping]] = ..., paxcounter: _Optional[_Union[ModuleConfig.PaxcounterConfig, _Mapping]] = ..., statusmessage: _Optional[_Union[ModuleConfig.StatusMessageConfig, _Mapping]] = ..., traffic_management: _Optional[_Union[ModuleConfig.TrafficManagementConfig, _Mapping]] = ..., tak: _Optional[_Union[ModuleConfig.TAKConfig, _Mapping]] = ..., mesh_beacon: _Optional[_Union[ModuleConfig.MeshBeaconConfig, _Mapping]] = ...) -> None: ...
|
||||
def __init__(self, mqtt: _Optional[_Union[ModuleConfig.MQTTConfig, _Mapping]] = ..., serial: _Optional[_Union[ModuleConfig.SerialConfig, _Mapping]] = ..., external_notification: _Optional[_Union[ModuleConfig.ExternalNotificationConfig, _Mapping]] = ..., store_forward: _Optional[_Union[ModuleConfig.StoreForwardConfig, _Mapping]] = ..., range_test: _Optional[_Union[ModuleConfig.RangeTestConfig, _Mapping]] = ..., telemetry: _Optional[_Union[ModuleConfig.TelemetryConfig, _Mapping]] = ..., canned_message: _Optional[_Union[ModuleConfig.CannedMessageConfig, _Mapping]] = ..., audio: _Optional[_Union[ModuleConfig.AudioConfig, _Mapping]] = ..., remote_hardware: _Optional[_Union[ModuleConfig.RemoteHardwareConfig, _Mapping]] = ..., neighbor_info: _Optional[_Union[ModuleConfig.NeighborInfoConfig, _Mapping]] = ..., ambient_lighting: _Optional[_Union[ModuleConfig.AmbientLightingConfig, _Mapping]] = ..., detection_sensor: _Optional[_Union[ModuleConfig.DetectionSensorConfig, _Mapping]] = ..., paxcounter: _Optional[_Union[ModuleConfig.PaxcounterConfig, _Mapping]] = ..., statusmessage: _Optional[_Union[ModuleConfig.StatusMessageConfig, _Mapping]] = ..., traffic_management: _Optional[_Union[ModuleConfig.TrafficManagementConfig, _Mapping]] = ..., tak: _Optional[_Union[ModuleConfig.TAKConfig, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class RemoteHardwarePin(_message.Message):
|
||||
__slots__ = ["gpio_pin", "name", "type"]
|
||||
|
||||
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\"meshtastic/protobuf/portnums.proto\x12\x13meshtastic.protobuf*\xb4\x06\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\x13\n\x0fMESH_BEACON_APP\x10%\x12\x0e\n\nPAGING_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\x10\n\x0cLORA_OTA_APP\x10O\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')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.portnums_pb2', globals())
|
||||
@@ -22,5 +22,5 @@ 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'
|
||||
_PORTNUM._serialized_start=60
|
||||
_PORTNUM._serialized_end=880
|
||||
_PORTNUM._serialized_end=825
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -15,14 +15,11 @@ GROUPALARM_APP: PortNum
|
||||
IP_TUNNEL_APP: PortNum
|
||||
KEY_VERIFICATION_APP: PortNum
|
||||
LORAWAN_BRIDGE: PortNum
|
||||
LORA_OTA_APP: PortNum
|
||||
MAP_REPORT_APP: PortNum
|
||||
MAX: PortNum
|
||||
MESH_BEACON_APP: PortNum
|
||||
NEIGHBORINFO_APP: PortNum
|
||||
NODEINFO_APP: PortNum
|
||||
NODE_STATUS_APP: PortNum
|
||||
PAGING_APP: PortNum
|
||||
PAXCOUNTER_APP: PortNum
|
||||
POSITION_APP: PortNum
|
||||
POWERSTRESS_APP: PortNum
|
||||
|
||||
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&meshtastic/protobuf/storeforward.proto\x12\x13meshtastic.protobuf\"\xd5\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\x12\x13\n\x0boriginal_id\x18\x06 \x01(\r\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')
|
||||
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')
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.storeforward_pb2', globals())
|
||||
@@ -22,13 +22,13 @@ 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'
|
||||
_STOREANDFORWARD._serialized_start=64
|
||||
_STOREANDFORWARD._serialized_end=1045
|
||||
_STOREANDFORWARD_STATISTICS._serialized_start=387
|
||||
_STOREANDFORWARD_STATISTICS._serialized_end=592
|
||||
_STOREANDFORWARD_HISTORY._serialized_start=594
|
||||
_STOREANDFORWARD_HISTORY._serialized_end=667
|
||||
_STOREANDFORWARD_HEARTBEAT._serialized_start=669
|
||||
_STOREANDFORWARD_HEARTBEAT._serialized_end=715
|
||||
_STOREANDFORWARD_REQUESTRESPONSE._serialized_start=718
|
||||
_STOREANDFORWARD_REQUESTRESPONSE._serialized_end=1034
|
||||
_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)
|
||||
@@ -6,7 +6,7 @@ from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Opti
|
||||
DESCRIPTOR: _descriptor.FileDescriptor
|
||||
|
||||
class StoreAndForward(_message.Message):
|
||||
__slots__ = ["heartbeat", "history", "original_id", "rr", "stats", "text"]
|
||||
__slots__ = ["heartbeat", "history", "rr", "stats", "text"]
|
||||
class RequestResponse(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
|
||||
__slots__ = []
|
||||
class Heartbeat(_message.Message):
|
||||
@@ -54,7 +54,6 @@ class StoreAndForward(_message.Message):
|
||||
CLIENT_STATS: StoreAndForward.RequestResponse
|
||||
HEARTBEAT_FIELD_NUMBER: _ClassVar[int]
|
||||
HISTORY_FIELD_NUMBER: _ClassVar[int]
|
||||
ORIGINAL_ID_FIELD_NUMBER: _ClassVar[int]
|
||||
ROUTER_BUSY: StoreAndForward.RequestResponse
|
||||
ROUTER_ERROR: StoreAndForward.RequestResponse
|
||||
ROUTER_HEARTBEAT: StoreAndForward.RequestResponse
|
||||
@@ -70,8 +69,7 @@ class StoreAndForward(_message.Message):
|
||||
UNSET: StoreAndForward.RequestResponse
|
||||
heartbeat: StoreAndForward.Heartbeat
|
||||
history: StoreAndForward.History
|
||||
original_id: int
|
||||
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] = ..., original_id: _Optional[int] = ...) -> None: ...
|
||||
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: ...
|
||||
@@ -13,7 +13,7 @@ _sym_db = _symbol_database.Default()
|
||||
|
||||
|
||||
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa9\x11\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12 \n\x14one_wire_temperature\x18\x17 \x03(\x02\x42\x02\x18\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch0\x18\x18 \x01(\x02H\x16\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch1\x18\x19 \x01(\x02H\x17\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch2\x18\x1a \x01(\x02H\x18\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch3\x18\x1b \x01(\x02H\x19\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch4\x18\x1c \x01(\x02H\x1a\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch5\x18\x1d \x01(\x02H\x1b\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch6\x18\x1e \x01(\x02H\x1c\x88\x01\x01\x12\x1c\n\x0f\x61\x64\x63_voltage_ch7\x18\x1f \x01(\x02H\x1d\x88\x01\x01\x12%\n\x18one_wire_temperature_ch0\x18 \x01(\x02H\x1e\x88\x01\x01\x12%\n\x18one_wire_temperature_ch1\x18! \x01(\x02H\x1f\x88\x01\x01\x12%\n\x18one_wire_temperature_ch2\x18\" \x01(\x02H \x88\x01\x01\x12%\n\x18one_wire_temperature_ch3\x18# \x01(\x02H!\x88\x01\x01\x12%\n\x18one_wire_temperature_ch4\x18$ \x01(\x02H\"\x88\x01\x01\x12%\n\x18one_wire_temperature_ch5\x18% \x01(\x02H#\x88\x01\x01\x12%\n\x18one_wire_temperature_ch6\x18& \x01(\x02H$\x88\x01\x01\x12%\n\x18one_wire_temperature_ch7\x18\' \x01(\x02H%\x88\x01\x01\x12&\n\x19lightning_strike_count_1h\x18( \x01(\rH&\x88\x01\x01\x12\"\n\x15lightning_distance_km\x18) \x01(\x02H\'\x88\x01\x01\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperatureB\x12\n\x10_adc_voltage_ch0B\x12\n\x10_adc_voltage_ch1B\x12\n\x10_adc_voltage_ch2B\x12\n\x10_adc_voltage_ch3B\x12\n\x10_adc_voltage_ch4B\x12\n\x10_adc_voltage_ch5B\x12\n\x10_adc_voltage_ch6B\x12\n\x10_adc_voltage_ch7B\x1b\n\x19_one_wire_temperature_ch0B\x1b\n\x19_one_wire_temperature_ch1B\x1b\n\x19_one_wire_temperature_ch2B\x1b\n\x19_one_wire_temperature_ch3B\x1b\n\x19_one_wire_temperature_ch4B\x1b\n\x19_one_wire_temperature_ch5B\x1b\n\x19_one_wire_temperature_ch6B\x1b\n\x19_one_wire_temperature_ch7B\x1c\n\x1a_lightning_strike_count_1hB\x18\n\x16_lightning_distance_kmJ\x04\x08*\x10\x39R\x07soil_phR\x02phR\x17\x65lectrical_conductivityR\x08salinityR\x08nitrogenR\nphosphorusR\tpotassiumR\x10\x64issolved_oxygenR\x03orpR\x16\x63hemical_oxygen_demandR\tturbidityR\x07nitrateR\x08\x61mmoniumR\x19\x62iochemical_oxygen_demandR\x10solar_irradiance\"\x98\x05\n\x10SoilWaterMetrics\x12\x14\n\x07soil_ph\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x0f\n\x02ph\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12$\n\x17\x65lectrical_conductivity\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x15\n\x08salinity\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x15\n\x08nitrogen\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x17\n\nphosphorus\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x16\n\tpotassium\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x1d\n\x10\x64issolved_oxygen\x18\x08 \x01(\x02H\x07\xLine truncated
|
||||
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n#meshtastic/protobuf/telemetry.proto\x12\x13meshtastic.protobuf\"\xf3\x01\n\rDeviceMetrics\x12\x1a\n\rbattery_level\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x14\n\x07voltage\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x63hannel_utilization\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x61ir_util_tx\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x1b\n\x0euptime_seconds\x18\x05 \x01(\rH\x04\x88\x01\x01\x42\x10\n\x0e_battery_levelB\n\n\x08_voltageB\x16\n\x14_channel_utilizationB\x0e\n\x0c_air_util_txB\x11\n\x0f_uptime_seconds\"\xa0\x07\n\x12\x45nvironmentMetrics\x12\x18\n\x0btemperature\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x1e\n\x11relative_humidity\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12 \n\x13\x62\x61rometric_pressure\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x1b\n\x0egas_resistance\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x14\n\x07voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x14\n\x07\x63urrent\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x10\n\x03iaq\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x15\n\x08\x64istance\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x10\n\x03lux\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x16\n\twhite_lux\x18\n \x01(\x02H\t\x88\x01\x01\x12\x13\n\x06ir_lux\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x13\n\x06uv_lux\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x1b\n\x0ewind_direction\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x17\n\nwind_speed\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x13\n\x06weight\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x16\n\twind_gust\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x16\n\twind_lull\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x16\n\tradiation\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x18\n\x0brainfall_1h\x18\x13 \x01(\x02H\x12\x88\x01\x01\x12\x19\n\x0crainfall_24h\x18\x14 \x01(\x02H\x13\x88\x01\x01\x12\x1a\n\rsoil_moisture\x18\x15 \x01(\rH\x14\x88\x01\x01\x12\x1d\n\x10soil_temperature\x18\x16 \x01(\x02H\x15\x88\x01\x01\x12\x1c\n\x14one_wire_temperature\x18\x17 \x03(\x02\x42\x0e\n\x0c_temperatureB\x14\n\x12_relative_humidityB\x16\n\x14_barometric_pressureB\x11\n\x0f_gas_resistanceB\n\n\x08_voltageB\n\n\x08_currentB\x06\n\x04_iaqB\x0b\n\t_distanceB\x06\n\x04_luxB\x0c\n\n_white_luxB\t\n\x07_ir_luxB\t\n\x07_uv_luxB\x11\n\x0f_wind_directionB\r\n\x0b_wind_speedB\t\n\x07_weightB\x0c\n\n_wind_gustB\x0c\n\n_wind_lullB\x0c\n\n_radiationB\x0e\n\x0c_rainfall_1hB\x0f\n\r_rainfall_24hB\x10\n\x0e_soil_moistureB\x13\n\x11_soil_temperature\"\xae\x05\n\x0cPowerMetrics\x12\x18\n\x0b\x63h1_voltage\x18\x01 \x01(\x02H\x00\x88\x01\x01\x12\x18\n\x0b\x63h1_current\x18\x02 \x01(\x02H\x01\x88\x01\x01\x12\x18\n\x0b\x63h2_voltage\x18\x03 \x01(\x02H\x02\x88\x01\x01\x12\x18\n\x0b\x63h2_current\x18\x04 \x01(\x02H\x03\x88\x01\x01\x12\x18\n\x0b\x63h3_voltage\x18\x05 \x01(\x02H\x04\x88\x01\x01\x12\x18\n\x0b\x63h3_current\x18\x06 \x01(\x02H\x05\x88\x01\x01\x12\x18\n\x0b\x63h4_voltage\x18\x07 \x01(\x02H\x06\x88\x01\x01\x12\x18\n\x0b\x63h4_current\x18\x08 \x01(\x02H\x07\x88\x01\x01\x12\x18\n\x0b\x63h5_voltage\x18\t \x01(\x02H\x08\x88\x01\x01\x12\x18\n\x0b\x63h5_current\x18\n \x01(\x02H\t\x88\x01\x01\x12\x18\n\x0b\x63h6_voltage\x18\x0b \x01(\x02H\n\x88\x01\x01\x12\x18\n\x0b\x63h6_current\x18\x0c \x01(\x02H\x0b\x88\x01\x01\x12\x18\n\x0b\x63h7_voltage\x18\r \x01(\x02H\x0c\x88\x01\x01\x12\x18\n\x0b\x63h7_current\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x18\n\x0b\x63h8_voltage\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x18\n\x0b\x63h8_current\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x42\x0e\n\x0c_ch1_voltageB\x0e\n\x0c_ch1_currentB\x0e\n\x0c_ch2_voltageB\x0e\n\x0c_ch2_currentB\x0e\n\x0c_ch3_voltageB\x0e\n\x0c_ch3_currentB\x0e\n\x0c_ch4_voltageB\x0e\n\x0c_ch4_currentB\x0e\n\x0c_ch5_voltageB\x0e\n\x0c_ch5_currentB\x0e\n\x0c_ch6_voltageB\x0e\n\x0c_ch6_currentB\x0e\n\x0c_ch7_voltageB\x0e\n\x0c_ch7_currentB\x0e\n\x0c_ch8_voltageB\x0e\n\x0c_ch8_current\"\xb1\t\n\x11\x41irQualityMetrics\x12\x1a\n\rpm10_standard\x18\x01 \x01(\rH\x00\x88\x01\x01\x12\x1a\n\rpm25_standard\x18\x02 \x01(\rH\x01\x88\x01\x01\x12\x1b\n\x0epm100_standard\x18\x03 \x01(\rH\x02\x88\x01\x01\x12\x1f\n\x12pm10_environmental\x18\x04 \x01(\rH\x03\x88\x01\x01\x12\x1f\n\x12pm25_environmental\x18\x05 \x01(\rH\x04\x88\x01\x01\x12 \n\x13pm100_environmental\x18\x06 \x01(\rH\x05\x88\x01\x01\x12\x1b\n\x0eparticles_03um\x18\x07 \x01(\rH\x06\x88\x01\x01\x12\x1b\n\x0eparticles_05um\x18\x08 \x01(\rH\x07\x88\x01\x01\x12\x1b\n\x0eparticles_10um\x18\t \x01(\rH\x08\x88\x01\x01\x12\x1b\n\x0eparticles_25um\x18\n \x01(\rH\t\x88\x01\x01\x12\x1b\n\x0eparticles_50um\x18\x0b \x01(\rH\n\x88\x01\x01\x12\x1c\n\x0fparticles_100um\x18\x0c \x01(\rH\x0b\x88\x01\x01\x12\x10\n\x03\x63o2\x18\r \x01(\rH\x0c\x88\x01\x01\x12\x1c\n\x0f\x63o2_temperature\x18\x0e \x01(\x02H\r\x88\x01\x01\x12\x19\n\x0c\x63o2_humidity\x18\x0f \x01(\x02H\x0e\x88\x01\x01\x12\x1e\n\x11\x66orm_formaldehyde\x18\x10 \x01(\x02H\x0f\x88\x01\x01\x12\x1a\n\rform_humidity\x18\x11 \x01(\x02H\x10\x88\x01\x01\x12\x1d\n\x10\x66orm_temperature\x18\x12 \x01(\x02H\x11\x88\x01\x01\x12\x1a\n\rpm40_standard\x18\x13 \x01(\rH\x12\x88\x01Line truncated
|
||||
|
||||
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
|
||||
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'meshtastic.protobuf.telemetry_pb2', globals())
|
||||
@@ -21,64 +21,28 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
||||
|
||||
DESCRIPTOR._options = None
|
||||
DESCRIPTOR._serialized_options = b'\n\024org.meshtastic.protoB\017TelemetryProtosZ\"github.com/meshtastic/go/generated\252\002\024Meshtastic.Protobufs\272\002\000'
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHTC3"]._options = None
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHTC3"]._serialized_options = b'\010\001'
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHT31"]._options = None
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHT31"]._serialized_options = b'\010\001'
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHT4X"]._options = None
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHT4X"]._serialized_options = b'\010\001'
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHT21"]._options = None
|
||||
_TELEMETRYSENSORTYPE.values_by_name["SHT21"]._serialized_options = b'\010\001'
|
||||
_ENVIRONMENTMETRICS.fields_by_name['one_wire_temperature']._options = None
|
||||
_ENVIRONMENTMETRICS.fields_by_name['one_wire_temperature']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch4_voltage']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch4_voltage']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch4_current']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch4_current']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch5_voltage']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch5_voltage']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch5_current']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch5_current']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch6_voltage']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch6_voltage']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch6_current']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch6_current']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch7_voltage']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch7_voltage']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch7_current']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch7_current']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch8_voltage']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch8_voltage']._serialized_options = b'\030\001'
|
||||
_POWERMETRICS.fields_by_name['ch8_current']._options = None
|
||||
_POWERMETRICS.fields_by_name['ch8_current']._serialized_options = b'\030\001'
|
||||
_TELEMETRYSENSORTYPE._serialized_start=7413
|
||||
_TELEMETRYSENSORTYPE._serialized_end=8207
|
||||
_TELEMETRYSENSORTYPE._serialized_start=5017
|
||||
_TELEMETRYSENSORTYPE._serialized_end=5749
|
||||
_DEVICEMETRICS._serialized_start=61
|
||||
_DEVICEMETRICS._serialized_end=304
|
||||
_ENVIRONMENTMETRICS._serialized_start=307
|
||||
_ENVIRONMENTMETRICS._serialized_end=2524
|
||||
_SOILWATERMETRICS._serialized_start=2527
|
||||
_SOILWATERMETRICS._serialized_end=3191
|
||||
_POWERMETRICS._serialized_start=3194
|
||||
_POWERMETRICS._serialized_end=3920
|
||||
_AIRQUALITYMETRICS._serialized_start=3923
|
||||
_AIRQUALITYMETRICS._serialized_end=5174
|
||||
_LOCALSTATS._serialized_start=5177
|
||||
_LOCALSTATS._serialized_end=5560
|
||||
_TRAFFICMANAGEMENTSTATS._serialized_start=5563
|
||||
_TRAFFICMANAGEMENTSTATS._serialized_end=5791
|
||||
_HEALTHMETRICS._serialized_start=5793
|
||||
_HEALTHMETRICS._serialized_end=5916
|
||||
_HOSTMETRICS._serialized_start=5919
|
||||
_HOSTMETRICS._serialized_end=6192
|
||||
_TELEMETRY._serialized_start=6195
|
||||
_TELEMETRY._serialized_end=6822
|
||||
_NAU7802CONFIG._serialized_start=6824
|
||||
_NAU7802CONFIG._serialized_end=6886
|
||||
_AS3935STATE._serialized_start=6888
|
||||
_AS3935STATE._serialized_end=6924
|
||||
_SEN5XSTATE._serialized_start=6927
|
||||
_SEN5XSTATE._serialized_end=7167
|
||||
_SEN6XSTATE._serialized_start=7170
|
||||
_SEN6XSTATE._serialized_end=7410
|
||||
_ENVIRONMENTMETRICS._serialized_end=1235
|
||||
_POWERMETRICS._serialized_start=1238
|
||||
_POWERMETRICS._serialized_end=1924
|
||||
_AIRQUALITYMETRICS._serialized_start=1927
|
||||
_AIRQUALITYMETRICS._serialized_end=3128
|
||||
_LOCALSTATS._serialized_start=3131
|
||||
_LOCALSTATS._serialized_end=3514
|
||||
_TRAFFICMANAGEMENTSTATS._serialized_start=3517
|
||||
_TRAFFICMANAGEMENTSTATS._serialized_end=3745
|
||||
_HEALTHMETRICS._serialized_start=3747
|
||||
_HEALTHMETRICS._serialized_end=3870
|
||||
_HOSTMETRICS._serialized_start=3873
|
||||
_HOSTMETRICS._serialized_end=4146
|
||||
_TELEMETRY._serialized_start=4149
|
||||
_TELEMETRY._serialized_end=4707
|
||||
_NAU7802CONFIG._serialized_start=4709
|
||||
_NAU7802CONFIG._serialized_end=4771
|
||||
_SEN5XSTATE._serialized_start=4774
|
||||
_SEN5XSTATE._serialized_end=5014
|
||||
# @@protoc_insertion_point(module_scope)
|
||||
@@ -7,7 +7,6 @@ from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Map
|
||||
ADS1X15: TelemetrySensorType
|
||||
ADS1X15_ALT: TelemetrySensorType
|
||||
AHT10: TelemetrySensorType
|
||||
AS3935: TelemetrySensorType
|
||||
BH1750: TelemetrySensorType
|
||||
BME280: TelemetrySensorType
|
||||
BME680: TelemetrySensorType
|
||||
@@ -21,7 +20,6 @@ DFROBOT_RAIN: TelemetrySensorType
|
||||
DPS310: TelemetrySensorType
|
||||
DS248X: TelemetrySensorType
|
||||
HDC1080: TelemetrySensorType
|
||||
HM330X: TelemetrySensorType
|
||||
ICM20948: TelemetrySensorType
|
||||
ICM42607P: TelemetrySensorType
|
||||
INA219: TelemetrySensorType
|
||||
@@ -50,7 +48,6 @@ RCWL9620: TelemetrySensorType
|
||||
SCD30: TelemetrySensorType
|
||||
SCD4X: TelemetrySensorType
|
||||
SEN5X: TelemetrySensorType
|
||||
SEN6X: TelemetrySensorType
|
||||
SENSOR_UNSET: TelemetrySensorType
|
||||
SFA30: TelemetrySensorType
|
||||
SHT21: TelemetrySensorType
|
||||
@@ -58,20 +55,13 @@ SHT31: TelemetrySensorType
|
||||
SHT4X: TelemetrySensorType
|
||||
SHTC3: TelemetrySensorType
|
||||
SHTXX: TelemetrySensorType
|
||||
SPA06: TelemetrySensorType
|
||||
STC31: TelemetrySensorType
|
||||
TSL2561: TelemetrySensorType
|
||||
TSL25911FN: TelemetrySensorType
|
||||
VEML7700: TelemetrySensorType
|
||||
|
||||
class AS3935State(_message.Message):
|
||||
__slots__ = ["tuning_cap_pf"]
|
||||
TUNING_CAP_PF_FIELD_NUMBER: _ClassVar[int]
|
||||
tuning_cap_pf: int
|
||||
def __init__(self, tuning_cap_pf: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class AirQualityMetrics(_message.Message):
|
||||
__slots__ = ["co2", "co2_humidity", "co2_temperature", "form_formaldehyde", "form_humidity", "form_temperature", "particles_03um", "particles_05um", "particles_100um", "particles_10um", "particles_25um", "particles_40um", "particles_50um", "particles_tps", "pm100_environmental", "pm100_standard", "pm10_environmental", "pm10_standard", "pm25_environmental", "pm25_standard", "pm40_standard", "pm_humidity", "pm_nox_idx", "pm_status_flags", "pm_temperature", "pm_voc_idx"]
|
||||
__slots__ = ["co2", "co2_humidity", "co2_temperature", "form_formaldehyde", "form_humidity", "form_temperature", "particles_03um", "particles_05um", "particles_100um", "particles_10um", "particles_25um", "particles_40um", "particles_50um", "particles_tps", "pm100_environmental", "pm100_standard", "pm10_environmental", "pm10_standard", "pm25_environmental", "pm25_standard", "pm40_standard", "pm_humidity", "pm_nox_idx", "pm_temperature", "pm_voc_idx"]
|
||||
CO2_FIELD_NUMBER: _ClassVar[int]
|
||||
CO2_HUMIDITY_FIELD_NUMBER: _ClassVar[int]
|
||||
CO2_TEMPERATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -95,7 +85,6 @@ class AirQualityMetrics(_message.Message):
|
||||
PM40_STANDARD_FIELD_NUMBER: _ClassVar[int]
|
||||
PM_HUMIDITY_FIELD_NUMBER: _ClassVar[int]
|
||||
PM_NOX_IDX_FIELD_NUMBER: _ClassVar[int]
|
||||
PM_STATUS_FLAGS_FIELD_NUMBER: _ClassVar[int]
|
||||
PM_TEMPERATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
PM_VOC_IDX_FIELD_NUMBER: _ClassVar[int]
|
||||
co2: int
|
||||
@@ -121,10 +110,9 @@ class AirQualityMetrics(_message.Message):
|
||||
pm40_standard: int
|
||||
pm_humidity: float
|
||||
pm_nox_idx: float
|
||||
pm_status_flags: int
|
||||
pm_temperature: float
|
||||
pm_voc_idx: float
|
||||
def __init__(self, pm10_standard: _Optional[int] = ..., pm25_standard: _Optional[int] = ..., pm100_standard: _Optional[int] = ..., pm10_environmental: _Optional[int] = ..., pm25_environmental: _Optional[int] = ..., pm100_environmental: _Optional[int] = ..., particles_03um: _Optional[int] = ..., particles_05um: _Optional[int] = ..., particles_10um: _Optional[int] = ..., particles_25um: _Optional[int] = ..., particles_50um: _Optional[int] = ..., particles_100um: _Optional[int] = ..., co2: _Optional[int] = ..., co2_temperature: _Optional[float] = ..., co2_humidity: _Optional[float] = ..., form_formaldehyde: _Optional[float] = ..., form_humidity: _Optional[float] = ..., form_temperature: _Optional[float] = ..., pm40_standard: _Optional[int] = ..., particles_40um: _Optional[int] = ..., pm_temperature: _Optional[float] = ..., pm_humidity: _Optional[float] = ..., pm_voc_idx: _Optional[float] = ..., pm_nox_idx: _Optional[float] = ..., particles_tps: _Optional[float] = ..., pm_status_flags: _Optional[int] = ...) -> None: ...
|
||||
def __init__(self, pm10_standard: _Optional[int] = ..., pm25_standard: _Optional[int] = ..., pm100_standard: _Optional[int] = ..., pm10_environmental: _Optional[int] = ..., pm25_environmental: _Optional[int] = ..., pm100_environmental: _Optional[int] = ..., particles_03um: _Optional[int] = ..., particles_05um: _Optional[int] = ..., particles_10um: _Optional[int] = ..., particles_25um: _Optional[int] = ..., particles_50um: _Optional[int] = ..., particles_100um: _Optional[int] = ..., co2: _Optional[int] = ..., co2_temperature: _Optional[float] = ..., co2_humidity: _Optional[float] = ..., form_formaldehyde: _Optional[float] = ..., form_humidity: _Optional[float] = ..., form_temperature: _Optional[float] = ..., pm40_standard: _Optional[int] = ..., particles_40um: _Optional[int] = ..., pm_temperature: _Optional[float] = ..., pm_humidity: _Optional[float] = ..., pm_voc_idx: _Optional[float] = ..., pm_nox_idx: _Optional[float] = ..., particles_tps: _Optional[float] = ...) -> None: ...
|
||||
|
||||
class DeviceMetrics(_message.Message):
|
||||
__slots__ = ["air_util_tx", "battery_level", "channel_utilization", "uptime_seconds", "voltage"]
|
||||
@@ -141,32 +129,14 @@ class DeviceMetrics(_message.Message):
|
||||
def __init__(self, battery_level: _Optional[int] = ..., voltage: _Optional[float] = ..., channel_utilization: _Optional[float] = ..., air_util_tx: _Optional[float] = ..., uptime_seconds: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class EnvironmentMetrics(_message.Message):
|
||||
__slots__ = ["adc_voltage_ch0", "adc_voltage_ch1", "adc_voltage_ch2", "adc_voltage_ch3", "adc_voltage_ch4", "adc_voltage_ch5", "adc_voltage_ch6", "adc_voltage_ch7", "barometric_pressure", "current", "distance", "gas_resistance", "iaq", "ir_lux", "lightning_distance_km", "lightning_strike_count_1h", "lux", "one_wire_temperature", "one_wire_temperature_ch0", "one_wire_temperature_ch1", "one_wire_temperature_ch2", "one_wire_temperature_ch3", "one_wire_temperature_ch4", "one_wire_temperature_ch5", "one_wire_temperature_ch6", "one_wire_temperature_ch7", "radiation", "rainfall_1h", "rainfall_24h", "relative_humidity", "soil_moisture", "soil_temperature", "temperature", "uv_lux", "voltage", "weight", "white_lux", "wind_direction", "wind_gust", "wind_lull", "wind_speed"]
|
||||
ADC_VOLTAGE_CH0_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH1_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH2_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH3_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH4_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH5_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH6_FIELD_NUMBER: _ClassVar[int]
|
||||
ADC_VOLTAGE_CH7_FIELD_NUMBER: _ClassVar[int]
|
||||
__slots__ = ["barometric_pressure", "current", "distance", "gas_resistance", "iaq", "ir_lux", "lux", "one_wire_temperature", "radiation", "rainfall_1h", "rainfall_24h", "relative_humidity", "soil_moisture", "soil_temperature", "temperature", "uv_lux", "voltage", "weight", "white_lux", "wind_direction", "wind_gust", "wind_lull", "wind_speed"]
|
||||
BAROMETRIC_PRESSURE_FIELD_NUMBER: _ClassVar[int]
|
||||
CURRENT_FIELD_NUMBER: _ClassVar[int]
|
||||
DISTANCE_FIELD_NUMBER: _ClassVar[int]
|
||||
GAS_RESISTANCE_FIELD_NUMBER: _ClassVar[int]
|
||||
IAQ_FIELD_NUMBER: _ClassVar[int]
|
||||
IR_LUX_FIELD_NUMBER: _ClassVar[int]
|
||||
LIGHTNING_DISTANCE_KM_FIELD_NUMBER: _ClassVar[int]
|
||||
LIGHTNING_STRIKE_COUNT_1H_FIELD_NUMBER: _ClassVar[int]
|
||||
LUX_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH0_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH1_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH2_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH3_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH4_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH5_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH6_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_CH7_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_WIRE_TEMPERATURE_FIELD_NUMBER: _ClassVar[int]
|
||||
RADIATION_FIELD_NUMBER: _ClassVar[int]
|
||||
RAINFALL_1H_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -183,32 +153,14 @@ class EnvironmentMetrics(_message.Message):
|
||||
WIND_GUST_FIELD_NUMBER: _ClassVar[int]
|
||||
WIND_LULL_FIELD_NUMBER: _ClassVar[int]
|
||||
WIND_SPEED_FIELD_NUMBER: _ClassVar[int]
|
||||
adc_voltage_ch0: float
|
||||
adc_voltage_ch1: float
|
||||
adc_voltage_ch2: float
|
||||
adc_voltage_ch3: float
|
||||
adc_voltage_ch4: float
|
||||
adc_voltage_ch5: float
|
||||
adc_voltage_ch6: float
|
||||
adc_voltage_ch7: float
|
||||
barometric_pressure: float
|
||||
current: float
|
||||
distance: float
|
||||
gas_resistance: float
|
||||
iaq: int
|
||||
ir_lux: float
|
||||
lightning_distance_km: float
|
||||
lightning_strike_count_1h: int
|
||||
lux: float
|
||||
one_wire_temperature: _containers.RepeatedScalarFieldContainer[float]
|
||||
one_wire_temperature_ch0: float
|
||||
one_wire_temperature_ch1: float
|
||||
one_wire_temperature_ch2: float
|
||||
one_wire_temperature_ch3: float
|
||||
one_wire_temperature_ch4: float
|
||||
one_wire_temperature_ch5: float
|
||||
one_wire_temperature_ch6: float
|
||||
one_wire_temperature_ch7: float
|
||||
radiation: float
|
||||
rainfall_1h: float
|
||||
rainfall_24h: float
|
||||
@@ -224,7 +176,7 @@ class EnvironmentMetrics(_message.Message):
|
||||
wind_gust: float
|
||||
wind_lull: float
|
||||
wind_speed: float
|
||||
def __init__(self, temperature: _Optional[float] = ..., relative_humidity: _Optional[float] = ..., barometric_pressure: _Optional[float] = ..., gas_resistance: _Optional[float] = ..., voltage: _Optional[float] = ..., current: _Optional[float] = ..., iaq: _Optional[int] = ..., distance: _Optional[float] = ..., lux: _Optional[float] = ..., white_lux: _Optional[float] = ..., ir_lux: _Optional[float] = ..., uv_lux: _Optional[float] = ..., wind_direction: _Optional[int] = ..., wind_speed: _Optional[float] = ..., weight: _Optional[float] = ..., wind_gust: _Optional[float] = ..., wind_lull: _Optional[float] = ..., radiation: _Optional[float] = ..., rainfall_1h: _Optional[float] = ..., rainfall_24h: _Optional[float] = ..., soil_moisture: _Optional[int] = ..., soil_temperature: _Optional[float] = ..., one_wire_temperature: _Optional[_Iterable[float]] = ..., adc_voltage_ch0: _Optional[float] = ..., adc_voltage_ch1: _Optional[float] = ..., adc_voltage_ch2: _Optional[float] = ..., adc_voltage_ch3: _Optional[float] = ..., adc_voltage_ch4: _Optional[float] = ..., adc_voltage_ch5: _Optional[float] = ..., adc_voltage_ch6: _Optional[float] = ..., adc_voltage_ch7: _Optional[float] = ..., one_wire_temperature_ch0: _Optional[float] = ..., one_wire_temperature_ch1: _Optional[float] = ..., one_wire_temperature_ch2: _Optional[float] = ..., one_wire_temperature_ch3: _Optional[float] = ..., one_wire_temperature_ch4: _Optional[float] = ..., one_wire_temperature_ch5: _Optional[float] = ..., one_wire_temperature_ch6: _Optional[float] = ..., one_wire_temperature_ch7: _Optional[float] = ..., lightning_strike_count_1h: _Optional[int] = ..., lightning_distance_km: _Optional[float] = ...) -> None: ...
|
||||
def __init__(self, temperature: _Optional[float] = ..., relative_humidity: _Optional[float] = ..., barometric_pressure: _Optional[float] = ..., gas_resistance: _Optional[float] = ..., voltage: _Optional[float] = ..., current: _Optional[float] = ..., iaq: _Optional[int] = ..., distance: _Optional[float] = ..., lux: _Optional[float] = ..., white_lux: _Optional[float] = ..., ir_lux: _Optional[float] = ..., uv_lux: _Optional[float] = ..., wind_direction: _Optional[int] = ..., wind_speed: _Optional[float] = ..., weight: _Optional[float] = ..., wind_gust: _Optional[float] = ..., wind_lull: _Optional[float] = ..., radiation: _Optional[float] = ..., rainfall_1h: _Optional[float] = ..., rainfall_24h: _Optional[float] = ..., soil_moisture: _Optional[int] = ..., soil_temperature: _Optional[float] = ..., one_wire_temperature: _Optional[_Iterable[float]] = ...) -> None: ...
|
||||
|
||||
class HealthMetrics(_message.Message):
|
||||
__slots__ = ["heart_bpm", "spO2", "temperature"]
|
||||
@@ -352,58 +304,8 @@ class SEN5XState(_message.Message):
|
||||
voc_state_valid: bool
|
||||
def __init__(self, last_cleaning_time: _Optional[int] = ..., last_cleaning_valid: bool = ..., one_shot_mode: bool = ..., voc_state_time: _Optional[int] = ..., voc_state_valid: bool = ..., voc_state_array: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class SEN6XState(_message.Message):
|
||||
__slots__ = ["last_cleaning_time", "last_cleaning_valid", "one_shot_mode", "voc_state_array", "voc_state_time", "voc_state_valid"]
|
||||
LAST_CLEANING_TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
LAST_CLEANING_VALID_FIELD_NUMBER: _ClassVar[int]
|
||||
ONE_SHOT_MODE_FIELD_NUMBER: _ClassVar[int]
|
||||
VOC_STATE_ARRAY_FIELD_NUMBER: _ClassVar[int]
|
||||
VOC_STATE_TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
VOC_STATE_VALID_FIELD_NUMBER: _ClassVar[int]
|
||||
last_cleaning_time: int
|
||||
last_cleaning_valid: bool
|
||||
one_shot_mode: bool
|
||||
voc_state_array: int
|
||||
voc_state_time: int
|
||||
voc_state_valid: bool
|
||||
def __init__(self, last_cleaning_time: _Optional[int] = ..., last_cleaning_valid: bool = ..., one_shot_mode: bool = ..., voc_state_time: _Optional[int] = ..., voc_state_valid: bool = ..., voc_state_array: _Optional[int] = ...) -> None: ...
|
||||
|
||||
class SoilWaterMetrics(_message.Message):
|
||||
__slots__ = ["ammonium", "biochemical_oxygen_demand", "chemical_oxygen_demand", "dissolved_oxygen", "electrical_conductivity", "nitrate", "nitrogen", "orp", "ph", "phosphorus", "potassium", "salinity", "soil_ph", "solar_irradiance", "turbidity"]
|
||||
AMMONIUM_FIELD_NUMBER: _ClassVar[int]
|
||||
BIOCHEMICAL_OXYGEN_DEMAND_FIELD_NUMBER: _ClassVar[int]
|
||||
CHEMICAL_OXYGEN_DEMAND_FIELD_NUMBER: _ClassVar[int]
|
||||
DISSOLVED_OXYGEN_FIELD_NUMBER: _ClassVar[int]
|
||||
ELECTRICAL_CONDUCTIVITY_FIELD_NUMBER: _ClassVar[int]
|
||||
NITRATE_FIELD_NUMBER: _ClassVar[int]
|
||||
NITROGEN_FIELD_NUMBER: _ClassVar[int]
|
||||
ORP_FIELD_NUMBER: _ClassVar[int]
|
||||
PHOSPHORUS_FIELD_NUMBER: _ClassVar[int]
|
||||
PH_FIELD_NUMBER: _ClassVar[int]
|
||||
POTASSIUM_FIELD_NUMBER: _ClassVar[int]
|
||||
SALINITY_FIELD_NUMBER: _ClassVar[int]
|
||||
SOIL_PH_FIELD_NUMBER: _ClassVar[int]
|
||||
SOLAR_IRRADIANCE_FIELD_NUMBER: _ClassVar[int]
|
||||
TURBIDITY_FIELD_NUMBER: _ClassVar[int]
|
||||
ammonium: float
|
||||
biochemical_oxygen_demand: float
|
||||
chemical_oxygen_demand: float
|
||||
dissolved_oxygen: float
|
||||
electrical_conductivity: float
|
||||
nitrate: float
|
||||
nitrogen: float
|
||||
orp: float
|
||||
ph: float
|
||||
phosphorus: float
|
||||
potassium: float
|
||||
salinity: float
|
||||
soil_ph: float
|
||||
solar_irradiance: float
|
||||
turbidity: float
|
||||
def __init__(self, soil_ph: _Optional[float] = ..., ph: _Optional[float] = ..., electrical_conductivity: _Optional[float] = ..., salinity: _Optional[float] = ..., nitrogen: _Optional[float] = ..., phosphorus: _Optional[float] = ..., potassium: _Optional[float] = ..., dissolved_oxygen: _Optional[float] = ..., orp: _Optional[float] = ..., chemical_oxygen_demand: _Optional[float] = ..., turbidity: _Optional[float] = ..., nitrate: _Optional[float] = ..., ammonium: _Optional[float] = ..., biochemical_oxygen_demand: _Optional[float] = ..., solar_irradiance: _Optional[float] = ...) -> None: ...
|
||||
|
||||
class Telemetry(_message.Message):
|
||||
__slots__ = ["air_quality_metrics", "device_metrics", "environment_metrics", "health_metrics", "host_metrics", "local_stats", "power_metrics", "soil_water_metrics", "time", "traffic_management_stats"]
|
||||
__slots__ = ["air_quality_metrics", "device_metrics", "environment_metrics", "health_metrics", "host_metrics", "local_stats", "power_metrics", "time", "traffic_management_stats"]
|
||||
AIR_QUALITY_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
DEVICE_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
ENVIRONMENT_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
@@ -411,7 +313,6 @@ class Telemetry(_message.Message):
|
||||
HOST_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
LOCAL_STATS_FIELD_NUMBER: _ClassVar[int]
|
||||
POWER_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
SOIL_WATER_METRICS_FIELD_NUMBER: _ClassVar[int]
|
||||
TIME_FIELD_NUMBER: _ClassVar[int]
|
||||
TRAFFIC_MANAGEMENT_STATS_FIELD_NUMBER: _ClassVar[int]
|
||||
air_quality_metrics: AirQualityMetrics
|
||||
@@ -421,10 +322,9 @@ class Telemetry(_message.Message):
|
||||
host_metrics: HostMetrics
|
||||
local_stats: LocalStats
|
||||
power_metrics: PowerMetrics
|
||||
soil_water_metrics: SoilWaterMetrics
|
||||
time: int
|
||||
traffic_management_stats: TrafficManagementStats
|
||||
def __init__(self, time: _Optional[int] = ..., device_metrics: _Optional[_Union[DeviceMetrics, _Mapping]] = ..., environment_metrics: _Optional[_Union[EnvironmentMetrics, _Mapping]] = ..., air_quality_metrics: _Optional[_Union[AirQualityMetrics, _Mapping]] = ..., power_metrics: _Optional[_Union[PowerMetrics, _Mapping]] = ..., local_stats: _Optional[_Union[LocalStats, _Mapping]] = ..., health_metrics: _Optional[_Union[HealthMetrics, _Mapping]] = ..., host_metrics: _Optional[_Union[HostMetrics, _Mapping]] = ..., traffic_management_stats: _Optional[_Union[TrafficManagementStats, _Mapping]] = ..., soil_water_metrics: _Optional[_Union[SoilWaterMetrics, _Mapping]] = ...) -> None: ...
|
||||
def __init__(self, time: _Optional[int] = ..., device_metrics: _Optional[_Union[DeviceMetrics, _Mapping]] = ..., environment_metrics: _Optional[_Union[EnvironmentMetrics, _Mapping]] = ..., air_quality_metrics: _Optional[_Union[AirQualityMetrics, _Mapping]] = ..., power_metrics: _Optional[_Union[PowerMetrics, _Mapping]] = ..., local_stats: _Optional[_Union[LocalStats, _Mapping]] = ..., health_metrics: _Optional[_Union[HealthMetrics, _Mapping]] = ..., host_metrics: _Optional[_Union[HostMetrics, _Mapping]] = ..., traffic_management_stats: _Optional[_Union[TrafficManagementStats, _Mapping]] = ...) -> None: ...
|
||||
|
||||
class TrafficManagementStats(_message.Message):
|
||||
__slots__ = ["hop_exhausted_packets", "nodeinfo_cache_hits", "packets_inspected", "position_dedup_drops", "rate_limit_drops", "router_hops_preserved", "unknown_packet_drops"]
|
||||
|
||||
@@ -4,7 +4,7 @@ import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
__version__ = "3.0.9"
|
||||
__release_date__ = "2026-11-12"
|
||||
__release_date__ = "2026-5-12"
|
||||
|
||||
|
||||
def get_git_revision():
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"base": {
|
||||
"chat": "Chat",
|
||||
"nodes": "Nodes",
|
||||
"everything": "Live Traffic",
|
||||
"everything": "See Everything",
|
||||
"graphs": "Mesh Graphs",
|
||||
"net": "Weekly Net",
|
||||
"map": "Live Map",
|
||||
@@ -176,7 +176,7 @@
|
||||
},
|
||||
"firehose":
|
||||
{
|
||||
"live_feed": "📡 Live Traffic",
|
||||
"live_feed": "📡 Live Feed",
|
||||
"pause": "Pause",
|
||||
"resume": "Resume",
|
||||
"time": "Time",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"base": {
|
||||
"chat": "Conversaciones",
|
||||
"nodes": "Nodos",
|
||||
"everything": "Tráfico en vivo",
|
||||
"everything": "Mostrar todo",
|
||||
"graphs": "Gráficos de la Malla",
|
||||
"net": "Red Semanal",
|
||||
"map": "Mapa en Vivo",
|
||||
@@ -175,7 +175,7 @@
|
||||
},
|
||||
|
||||
"firehose": {
|
||||
"live_feed": "📡 Tráfico en vivo",
|
||||
"live_feed": "📡 Flujo en vivo",
|
||||
"pause": "Pausar",
|
||||
"resume": "Reanudar",
|
||||
"time": "Hora",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"base": {
|
||||
"chat": "Чат",
|
||||
"nodes": "Ноды",
|
||||
"everything": "Трафик в реальном времени",
|
||||
"everything": "Показать все",
|
||||
"graphs": "Mesh графики",
|
||||
"net": "Недельная сеть",
|
||||
"map": "Живая карта",
|
||||
@@ -159,7 +159,7 @@
|
||||
"node_not_found": "Узел не найден в текущем канале!"
|
||||
},
|
||||
"firehose": {
|
||||
"live_feed": "📡 Трафик в реальном времени",
|
||||
"live_feed": "📡 Прямой эфир",
|
||||
"pause": "Пауза",
|
||||
"resume": "Продолжить",
|
||||
"time": "Время",
|
||||
|
||||
+122
-93
@@ -1,98 +1,127 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Meshview Chat API</title>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/meshview-icon.svg">
|
||||
<script src="/static/theme.js"></script>
|
||||
<style>
|
||||
body { margin:0; background:#f5f9f6; color:#243247; font:15px/1.7 system-ui,sans-serif; }
|
||||
main { max-width:760px; margin:40px auto; padding:24px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; }
|
||||
h1 { color:var(--mesh-primary); font-size:24px; } a { color:var(--mesh-primary); }
|
||||
code { background:var(--mesh-soft); padding:3px 6px; border-radius:4px; overflow-wrap:anywhere; }
|
||||
@media(max-width:700px) { main { margin:16px; padding:18px; } }
|
||||
</style>
|
||||
<!-- mesh-theme:start -->
|
||||
<style>
|
||||
:root {
|
||||
color-scheme:light;
|
||||
--mesh-primary:#187346;
|
||||
--mesh-primary-dark:#0f5132;
|
||||
--mesh-primary-rgb:24,115,70;
|
||||
--mesh-brand:#187346;
|
||||
--mesh-brand-deep:#0f5132;
|
||||
--mesh-surface:#ffffff;
|
||||
--mesh-text:#243247;
|
||||
--mesh-soft:#eaf5ee;
|
||||
--mesh-hover:#dceee2;
|
||||
--mesh-border:#dce7df;
|
||||
--mesh-page:#f5f9f6;
|
||||
--mesh-stripe:#f7faf8;
|
||||
--mesh-muted:#64748b;
|
||||
--mesh-chat-stripe:#eef6f0;
|
||||
--mesh-pulse-soft:#edf8f0;
|
||||
--mesh-pulse-peak:#ccebd7;
|
||||
--mesh-pulse-mid:#e2f3e8;
|
||||
}
|
||||
[data-bs-theme="dark"] {
|
||||
color-scheme:dark;
|
||||
--mesh-primary:#80cfa3;
|
||||
--mesh-primary-dark:#a3e3be;
|
||||
--mesh-primary-rgb:128,207,163;
|
||||
--mesh-brand:#14532d;
|
||||
--mesh-brand-deep:#0c3a1f;
|
||||
--mesh-surface:#18231e;
|
||||
--mesh-text:#e2ece5;
|
||||
--mesh-soft:#203c2b;
|
||||
--mesh-hover:#294c36;
|
||||
--mesh-border:#34483c;
|
||||
--mesh-page:#101914;
|
||||
--mesh-stripe:#1c2a22;
|
||||
--mesh-muted:#9faea6;
|
||||
--mesh-chat-stripe:#203227;
|
||||
--mesh-pulse-soft:#203c2b;
|
||||
--mesh-pulse-peak:#356b49;
|
||||
--mesh-pulse-mid:#294c36;
|
||||
--bs-link-color:var(--mesh-primary);
|
||||
--bs-link-color-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-hover-color:var(--mesh-primary-dark);
|
||||
--bs-link-hover-color-rgb:163,227,190;
|
||||
}
|
||||
body { background:var(--mesh-page); color:var(--mesh-text); }
|
||||
.mesh-theme-toggle { flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border:1px solid #ffffff70; border-radius:6px; background:transparent; color:white; font:22px/1 system-ui,sans-serif; cursor:pointer; }
|
||||
.mesh-header .mesh-theme-toggle { margin-left:auto; }
|
||||
.mesh-theme-toggle:hover { background:#ffffff20; }
|
||||
.mesh-theme-toggle:focus-visible { outline:2px solid white; outline-offset:3px; }
|
||||
@media(max-width:1000px) { .mesh-header .mesh-menu-toggle { margin-left:auto; } .mesh-header .mesh-theme-toggle { margin-left:12px; } .mesh-header #site-menu { order:4; } }
|
||||
[data-bs-theme="dark"] :is(.chat-status,.chat-details,.chat-channel,.chat-status[data-state="paused"],.chat-status[data-state="loading"],.good-x) { background:var(--mesh-soft); color:var(--mesh-primary); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.chat-status[data-state="error"],.bad-x) { background:#472a24; color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .ok-x { background:#453820; color:#f1d38a; }
|
||||
[data-bs-theme="dark"] .chat-details:hover { background:var(--mesh-hover); color:var(--mesh-primary-dark); }
|
||||
[data-bs-theme="dark"] .chat-nick { filter:brightness(1.4) saturate(.8); }
|
||||
[data-bs-theme="dark"] :is(.summary-card:nth-child(2) .summary-count,.summary-card:nth-child(3) .summary-count,.summary-card:nth-child(4) .summary-count,.mesh-metric:nth-child(2) strong,.mesh-metric:nth-child(3) strong,.reach-metric:nth-child(2) .reach-metric-value) { color:var(--mesh-primary); }
|
||||
[data-bs-theme="dark"] :is(.reliability-status-heard) { color:#8fd7aa!important; }
|
||||
[data-bs-theme="dark"] .reliability-status-missed { color:#ffb4a6!important; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-value span { color:#17263c; }
|
||||
[data-bs-theme="dark"] .leaflet-tile-pane { filter:invert(1) hue-rotate(180deg) brightness(.85) saturate(.75); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-container,.leaflet-control-layers,.leaflet-bar a,.leaflet-popup-content-wrapper,.leaflet-popup-tip,.leaflet-tooltip,.leaflet-control-attribution,.leaflet-control-scale-line,#unmapped-packets,#legend,#node-info,.legend) { background:var(--mesh-surface); color:var(--mesh-text); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-control-layers label,.leaflet-popup-close-button,#unmapped-packets h3,.unmapped-node,.blinking-tooltip,.legend) { color:var(--mesh-text); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-bar a:hover,.leaflet-control-layers-expanded) { background:var(--mesh-stripe); }
|
||||
[data-bs-theme="dark"] :is(.unmapped-empty,.reach-muted) { color:var(--mesh-muted); }
|
||||
[data-bs-theme="dark"] :is(.source-marker,.reach-map-marker) { color:white; }
|
||||
[data-bs-theme="dark"] .qr-image { background:white; }
|
||||
[data-bs-theme="dark"] :is(#traceroute-error,#map-load-status,.text-danger) { color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-track { background:var(--mesh-soft); }
|
||||
</style>
|
||||
|
||||
<!-- mesh-theme:end -->
|
||||
<meta charset="UTF-8" />
|
||||
<title>API Documentation - Chat</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist/swagger-ui.css" />
|
||||
<style>
|
||||
body {
|
||||
margin: 0;
|
||||
background: #ffffff;
|
||||
color: #000000;
|
||||
}
|
||||
#swagger-ui { background: #ffffff; color: #000; }
|
||||
.swagger-ui { background-color: #ffffff !important; color: #000 !important; }
|
||||
.swagger-ui .topbar,
|
||||
.swagger-ui .info,
|
||||
.swagger-ui .opblock-summary-description,
|
||||
.swagger-ui .parameters-col_description,
|
||||
.swagger-ui .response-col_description { color: #000 !important; }
|
||||
.swagger-ui .opblock { background-color: #f9f9f9 !important; border-color: #ddd !important; }
|
||||
.swagger-ui .opblock-summary { background-color: #eaeaea !important; color: #000 !important; }
|
||||
.swagger-ui .opblock-section-header { color: #000 !important; }
|
||||
.swagger-ui .parameters,
|
||||
.swagger-ui .response { background-color: #fafafa !important; color: #000 !important; }
|
||||
.swagger-ui table { color: #000 !important; }
|
||||
.swagger-ui a { color: #1a0dab !important; }
|
||||
.swagger-ui input,
|
||||
.swagger-ui select,
|
||||
.swagger-ui textarea { background-color: #fff !important; color: #000 !important; border: 1px solid #ccc !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<button class="mesh-theme-toggle" style="position:fixed;top:12px;right:12px;z-index:2000;background:#187346" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false">☾</button><main>
|
||||
<h1>Chat messages API</h1>
|
||||
<p>Chat uses <code>GET /api/packets?portnum=1</code>. There is no separate <code>/api/chat</code> endpoint.</p>
|
||||
<p>Use <code>limit</code> and <code>since</code> for incremental polling. Direct port-1 text messages are returned as <code><redacted></code>.</p>
|
||||
<p><a href="/api.html#get-api-packets">Read the complete packets API reference ↗</a></p>
|
||||
<p><a href="/">Return to Meshview</a></p>
|
||||
</main></body>
|
||||
<div id="swagger-ui"></div>
|
||||
|
||||
<script src="https://unpkg.com/swagger-ui-dist/swagger-ui-bundle.js"></script>
|
||||
<script>
|
||||
const spec = {
|
||||
openapi: "3.0.0",
|
||||
info: {
|
||||
title: "Chat API",
|
||||
version: "1.0.0",
|
||||
description: "API for retrieving chat messages from the mesh network. Supports optional time-based filtering and result limits."
|
||||
},
|
||||
paths: {
|
||||
"/api/chat": {
|
||||
get: {
|
||||
summary: "Get chat messages",
|
||||
description: "Returns a list of chat messages. You can optionally filter by a timestamp (`since`) and limit the number of results (`limit`).",
|
||||
parameters: [
|
||||
{
|
||||
name: "since",
|
||||
in: "query",
|
||||
required: false,
|
||||
description: "ISO 8601 timestamp; only return messages newer than this.",
|
||||
schema: { type: "string", format: "date-time", example: "2025-09-10T15:29:33.307782" }
|
||||
},
|
||||
{
|
||||
name: "limit",
|
||||
in: "query",
|
||||
required: false,
|
||||
description: "Maximum number of messages to return (1-200). Default is 100.",
|
||||
schema: { type: "integer", minimum: 1, maximum: 200, default: 100 }
|
||||
}
|
||||
],
|
||||
responses: {
|
||||
"200": {
|
||||
description: "Successful response",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: {
|
||||
type: "object",
|
||||
properties: {
|
||||
packets: {
|
||||
type: "array",
|
||||
description: "Array of chat messages",
|
||||
items: {
|
||||
type: "object",
|
||||
properties: {
|
||||
id: { type: "integer", example: 4285655910 },
|
||||
import_time: { type: "string", format: "date-time", example: "2025-09-10T15:29:33.307782" },
|
||||
channel: { type: "string", example: "MediumSlow" },
|
||||
from_node_id: { type: "integer", example: 2695230252 },
|
||||
long_name: { type: "string", example: "Fight The Empire With Sticks And Rocks" },
|
||||
payload: { type: "string", example: "sunny in SF" },
|
||||
reply_id: { type: "integer", example: 670731015, nullable: true }
|
||||
}
|
||||
}
|
||||
},
|
||||
latest_import_time: {
|
||||
type: "string",
|
||||
format: "date-time",
|
||||
description: "Timestamp of the most recent message returned",
|
||||
example: "2025-09-10T16:54:14.124001"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
description: "Server error",
|
||||
content: {
|
||||
"application/json": {
|
||||
schema: { type: "object", properties: { error: { type: "string" } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.onload = () => {
|
||||
SwaggerUIBundle({
|
||||
spec,
|
||||
dom_id: '#swagger-ui',
|
||||
presets: [
|
||||
SwaggerUIBundle.presets.apis,
|
||||
SwaggerUIBundle.SwaggerUIStandalonePreset
|
||||
],
|
||||
layout: "BaseLayout"
|
||||
});
|
||||
};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
+264
-528
@@ -1,537 +1,273 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Meshview API Reference</title>
|
||||
<script src="/static/theme.js"></script>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/meshview-icon.svg">
|
||||
<title>Meshview API Documentation</title>
|
||||
<style>
|
||||
:root { color-scheme:light; --primary:var(--mesh-primary); --border:var(--mesh-border); }
|
||||
* { box-sizing:border-box; }
|
||||
html { scroll-padding-top:80px; }
|
||||
body { margin:0; background:var(--mesh-page); color:var(--mesh-text); font:14px/1.7 system-ui,-apple-system,"Segoe UI",sans-serif; }
|
||||
a { color:var(--primary); }
|
||||
a:hover { color:var(--mesh-primary-dark); }
|
||||
header { background:var(--mesh-brand); color:white; position:sticky; top:0; z-index:2; box-shadow:0 2px 8px #174b2d18; }
|
||||
.header-inner { max-width:1180px; margin:auto; min-height:56px; display:flex; align-items:center; gap:12px; padding:8px 24px; }
|
||||
header img { width:32px; height:32px; }
|
||||
header a { color:white; text-decoration:none; }
|
||||
header a:hover { color:white; text-decoration:underline; }
|
||||
.brand { font-size:18px; font-weight:700; display:flex; align-items:center; gap:10px; }
|
||||
.home-link { margin-left:auto; font-size:13px; }
|
||||
main { max-width:1180px; margin:auto; padding:28px 24px 60px; min-width:0; }
|
||||
h1 { font-size:28px; margin:0 0 16px; } h2 { font-size:21px; margin:32px 0 14px; } h3 { font-size:17px; margin:0 0 16px; }
|
||||
p,li { overflow-wrap:anywhere; }
|
||||
code { font:12px/1.7 ui-monospace,Consolas,monospace; color:var(--mesh-primary); background:var(--mesh-soft); border-radius:4px; padding:2px 5px; overflow-wrap:anywhere; }
|
||||
pre { background:var(--mesh-stripe); border:1px solid var(--border); border-radius:7px; padding:16px; overflow:auto; }
|
||||
pre code { background:none; padding:0; white-space:pre; color:var(--mesh-text); }
|
||||
h3 code { font-size:15px; }
|
||||
.endpoint { background:var(--mesh-surface); border:1px solid var(--border); border-radius:9px; padding:24px; margin-bottom:22px; scroll-margin-top:12px; min-width:0; }
|
||||
.method { display:inline-block; background:var(--mesh-brand); color:white; font-size:11px; padding:3px 8px; border-radius:5px; margin-right:5px; }
|
||||
hr { border:0; border-top:1px solid var(--border); margin:24px 0; }
|
||||
.api-index { background:var(--mesh-surface); border:1px solid var(--border); border-radius:9px; padding:16px 20px; margin-bottom:24px; }
|
||||
.api-index summary { color:var(--primary); font-weight:600; cursor:pointer; }
|
||||
.api-index ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px 24px; padding-left:20px; }
|
||||
.api-index a { font:12px ui-monospace,monospace; }
|
||||
:focus-visible { outline:2px solid var(--primary); outline-offset:3px; }
|
||||
footer { border-top:1px solid var(--border); padding:20px 24px; text-align:center; color:var(--mesh-muted); font-size:12px; }
|
||||
@media(max-width:700px) { main { padding:20px 14px 40px; } .header-inner { padding:8px 14px; } h1 { font-size:24px; } h2 { font-size:19px; } h3 code { font-size:12px; } .endpoint { padding:16px; } .api-index ul { grid-template-columns:minmax(0,1fr); } }
|
||||
body {
|
||||
background: #121212;
|
||||
color: #eee;
|
||||
font-family: monospace;
|
||||
margin: 20px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
h1, h2, h3 { color: #79c0ff; }
|
||||
code {
|
||||
background: #1e1e1e;
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
color: #ffd479;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
.endpoint {
|
||||
border: 1px solid #333;
|
||||
padding: 12px;
|
||||
margin-bottom: 18px;
|
||||
border-radius: 8px;
|
||||
background: #1a1a1a;
|
||||
}
|
||||
.method {
|
||||
display: inline-block;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
margin-right: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.get { background: #0066cc; }
|
||||
.path { font-weight: bold; color: #fff; }
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 8px;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #444;
|
||||
padding: 6px 10px;
|
||||
}
|
||||
th {
|
||||
background: #222;
|
||||
color: #9ddcff;
|
||||
}
|
||||
.example {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
background: #161616;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #333;
|
||||
}
|
||||
</style>
|
||||
<style>
|
||||
:root {
|
||||
color-scheme:light;
|
||||
--mesh-primary:#187346;
|
||||
--mesh-primary-dark:#0f5132;
|
||||
--mesh-primary-rgb:24,115,70;
|
||||
--mesh-brand:#187346;
|
||||
--mesh-brand-deep:#0f5132;
|
||||
--mesh-surface:#ffffff;
|
||||
--mesh-text:#243247;
|
||||
--mesh-soft:#eaf5ee;
|
||||
--mesh-hover:#dceee2;
|
||||
--mesh-border:#dce7df;
|
||||
--mesh-page:#f5f9f6;
|
||||
--mesh-stripe:#f7faf8;
|
||||
--mesh-muted:#64748b;
|
||||
--mesh-chat-stripe:#eef6f0;
|
||||
--mesh-pulse-soft:#edf8f0;
|
||||
--mesh-pulse-peak:#ccebd7;
|
||||
--mesh-pulse-mid:#e2f3e8;
|
||||
}
|
||||
[data-bs-theme="dark"] {
|
||||
color-scheme:dark;
|
||||
--mesh-primary:#80cfa3;
|
||||
--mesh-primary-dark:#a3e3be;
|
||||
--mesh-primary-rgb:128,207,163;
|
||||
--mesh-brand:#14532d;
|
||||
--mesh-brand-deep:#0c3a1f;
|
||||
--mesh-surface:#18231e;
|
||||
--mesh-text:#e2ece5;
|
||||
--mesh-soft:#203c2b;
|
||||
--mesh-hover:#294c36;
|
||||
--mesh-border:#34483c;
|
||||
--mesh-page:#101914;
|
||||
--mesh-stripe:#1c2a22;
|
||||
--mesh-muted:#9faea6;
|
||||
--mesh-chat-stripe:#203227;
|
||||
--mesh-pulse-soft:#203c2b;
|
||||
--mesh-pulse-peak:#356b49;
|
||||
--mesh-pulse-mid:#294c36;
|
||||
--bs-link-color:var(--mesh-primary);
|
||||
--bs-link-color-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-hover-color:var(--mesh-primary-dark);
|
||||
--bs-link-hover-color-rgb:163,227,190;
|
||||
}
|
||||
body { background:var(--mesh-page); color:var(--mesh-text); }
|
||||
.mesh-theme-toggle { flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border:1px solid #ffffff70; border-radius:6px; background:transparent; color:white; font:22px/1 system-ui,sans-serif; cursor:pointer; }
|
||||
.mesh-header .mesh-theme-toggle { margin-left:auto; }
|
||||
.mesh-theme-toggle:hover { background:#ffffff20; }
|
||||
.mesh-theme-toggle:focus-visible { outline:2px solid white; outline-offset:3px; }
|
||||
@media(max-width:1000px) { .mesh-header .mesh-menu-toggle { margin-left:auto; } .mesh-header .mesh-theme-toggle { margin-left:12px; } .mesh-header #site-menu { order:4; } }
|
||||
[data-bs-theme="dark"] :is(.chat-status,.chat-details,.chat-channel,.chat-status[data-state="paused"],.chat-status[data-state="loading"],.good-x) { background:var(--mesh-soft); color:var(--mesh-primary); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.chat-status[data-state="error"],.bad-x) { background:#472a24; color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .ok-x { background:#453820; color:#f1d38a; }
|
||||
[data-bs-theme="dark"] .chat-details:hover { background:var(--mesh-hover); color:var(--mesh-primary-dark); }
|
||||
[data-bs-theme="dark"] .chat-nick { filter:brightness(1.4) saturate(.8); }
|
||||
[data-bs-theme="dark"] :is(.summary-card:nth-child(2) .summary-count,.summary-card:nth-child(3) .summary-count,.summary-card:nth-child(4) .summary-count,.mesh-metric:nth-child(2) strong,.mesh-metric:nth-child(3) strong,.reach-metric:nth-child(2) .reach-metric-value) { color:var(--mesh-primary); }
|
||||
[data-bs-theme="dark"] :is(.reliability-status-heard) { color:#8fd7aa!important; }
|
||||
[data-bs-theme="dark"] .reliability-status-missed { color:#ffb4a6!important; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-value span { color:#17263c; }
|
||||
[data-bs-theme="dark"] .leaflet-tile-pane { filter:invert(1) hue-rotate(180deg) brightness(.85) saturate(.75); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-container,.leaflet-control-layers,.leaflet-bar a,.leaflet-popup-content-wrapper,.leaflet-popup-tip,.leaflet-tooltip,.leaflet-control-attribution,.leaflet-control-scale-line,#unmapped-packets,#legend,#node-info,.legend) { background:var(--mesh-surface); color:var(--mesh-text); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-control-layers label,.leaflet-popup-close-button,#unmapped-packets h3,.unmapped-node,.blinking-tooltip,.legend) { color:var(--mesh-text); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-bar a:hover,.leaflet-control-layers-expanded) { background:var(--mesh-stripe); }
|
||||
[data-bs-theme="dark"] :is(.unmapped-empty,.reach-muted) { color:var(--mesh-muted); }
|
||||
[data-bs-theme="dark"] :is(.source-marker,.reach-map-marker) { color:white; }
|
||||
[data-bs-theme="dark"] .qr-image { background:white; }
|
||||
[data-bs-theme="dark"] :is(#traceroute-error,#map-load-status,.text-danger) { color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-track { background:var(--mesh-soft); }
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header><div class="header-inner"><a class="brand" href="/"><img src="/static/meshview-icon.svg" alt="" width="32" height="32">Meshview</a><span>API reference</span><a class="home-link" href="/">Home ↗</a><button class="mesh-theme-toggle" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false">☾</button></div></header>
|
||||
<main>
|
||||
<details class="api-index"><summary>Browse all 16 endpoints</summary><nav aria-label="API endpoints"><ul><li><a href="#get-api-nodes">GET /api/nodes</a></li><li><a href="#get-api-packets">GET /api/packets</a></li><li><a href="#get-api-channels">GET /api/channels</a></li><li><a href="#get-api-stats">GET /api/stats</a></li><li><a href="#get-api-stats-count">GET /api/stats/count</a></li><li><a href="#get-api-stats-top">GET /api/stats/top</a></li><li><a href="#get-api-edges">GET /api/edges</a></li><li><a href="#get-api-snapshots-daily">GET /api/snapshots/daily</a></li><li><a href="#get-api-config">GET /api/config</a></li><li><a href="#get-api-lang">GET /api/lang</a></li><li><a href="#get-api-packets-seen-packet-id">GET /api/packets_seen/{packet_id}</a></li><li><a href="#get-api-traceroute-packet-id">GET /api/traceroute/{packet_id}</a></li><li><a href="#get-health">GET /health</a></li><li><a href="#get-version">GET /version</a></li><li><a href="#get-api-node-node-id-qr">GET /api/node/{node_id}/qr</a></li><li><a href="#get-api-coverage-node-id">GET /api/coverage/{node_id}</a></li></ul></nav></details>
|
||||
<h1 id="api-documentation">API Documentation</h1>
|
||||
<p>Base URL: <code>http(s)://<host></code></p>
|
||||
<p>This reference covers all 16 GET routes registered in <code>meshview/web_api/api.py</code>, including <code>/health</code> and <code>/version</code>. The browser version is served at <code>/api.html</code>. Responses below are illustrative examples; actual values depend on stored data. Regenerate the browser reference after editing this file with <code>node scripts/build-api-docs.mjs</code>.</p>
|
||||
<h2 id="conventions">Conventions</h2>
|
||||
<ul><li>Successful API responses are JSON. Explicit validation errors usually return JSON with an <code>error</code> field. Some unhandled errors return HTTP 500 with a plain-text body; check HTTP status and Content-Type before parsing an error response.</li><li>All routes are read-only. The application does not require an API token; a reverse proxy may impose authentication. There are no application-level write endpoints.</li><li><code>*_us</code> timestamps and <code>since</code> use microseconds since the Unix epoch. Snapshot dates and statistics buckets use UTC. Node latitude/longitude integers must be divided by 10,000,000 to obtain degrees; coverage coordinates are already degrees.</li><li>Packet <code>id</code> and <code>storage_id</code> are database row IDs. Use these for the <code>packet_id</code> query/path parameters on packet, observation, count, and traceroute endpoints. A response field named <code>packet_id</code> on a packet object is instead its over-the-air Meshtastic ID. <code>reply_id</code>, when present, is also an over-the-air ID. These ID types are not interchangeable. Node IDs are numeric Meshtastic node numbers; the node object's <code>id</code> is a separate string identifier.</li><li>Use decimal node IDs throughout. The packet sender/recipient filters and the QR and coverage paths also accept Python-style <code>0x</code> hexadecimal numbers. This is not supported consistently by the other routes.</li><li>Public broadcast text is readable. Direct text messages on port 1 are returned as <code><redacted></code>. Request chat with <code>/api/packets?portnum=1</code>; there is no <code>/api/chat</code> route. Do not treat a decoded <code>payload</code> string as trusted HTML.</li></ul>
|
||||
<h2 id="quick-examples">Quick examples</h2>
|
||||
<pre><code class="language-sh">curl 'http://localhost:8081/api/nodes?days_active=3'
|
||||
curl 'http://localhost:8081/api/packets?portnum=1&limit=100'
|
||||
curl 'http://localhost:8081/api/stats/count'
|
||||
curl 'http://localhost:8081/api/coverage/1234?mode=perimeter&radius_km=20'</code></pre>
|
||||
<h2 id="1-nodes-api">1. Nodes API</h2>
|
||||
<section class="endpoint" id="get-api-nodes"><h3><span class="method">GET</span> <code>/api/nodes</code></h3>
|
||||
<p>Returns a list of nodes, with optional filtering.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>node_id</code> (optional, int): Exact node ID.</li><li><code>role</code> (optional, string): Node role.</li><li><code>channel</code> (optional, string): Channel name.</li><li><code>hw_model</code> (optional, string): Hardware model.</li><li><code>days_active</code> (optional, int): Nodes seen within the last N days. Omit for all nodes with a non-null last-seen timestamp; invalid integers are ignored.</li></ul>
|
||||
<p>Nodes are sorted by <code>short_name</code> ascending. <code>role</code> is normalized to uppercase; channel and hardware filters are exact matches. No pagination is implemented.</p>
|
||||
<p>Errors: HTTP 500 with <code>{"error":"Failed to fetch nodes"}</code> for handler failures; the storage helper may return an empty list for database failures.</p>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "!000004d2",
|
||||
"node_id": 1234,
|
||||
"long_name": "Alice",
|
||||
"short_name": "A",
|
||||
"hw_model": "T-Beam",
|
||||
"firmware": "1.2.3",
|
||||
"role": "client",
|
||||
"last_lat": 377749000,
|
||||
"last_long": -1224194000,
|
||||
"channel": "main",
|
||||
"is_mqtt_gateway": true,
|
||||
"first_seen_us": 1736283723456789,
|
||||
"last_seen_us": 1736370123456789
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
|
||||
<h1>Meshview API Documentation</h1>
|
||||
<p>This page describes all REST endpoints provided by Meshview.</p>
|
||||
|
||||
|
||||
<!------------------------------ NODES ------------------------------>
|
||||
<h2>/api/nodes</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/nodes</span>
|
||||
<p>Returns a list of mesh nodes.</p>
|
||||
|
||||
<h3>Query Parameters</h3>
|
||||
<table>
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td>role</td><td>Filter by node role</td></tr>
|
||||
<tr><td>channel</td><td>Filter by channel</td></tr>
|
||||
<tr><td>hw_model</td><td>Hardware model filter</td></tr>
|
||||
<tr><td>days_active</td><td>Only nodes seen within X days</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="example">
|
||||
<b>Example:</b><br>
|
||||
<code>/api/nodes?days_active=3</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ PACKETS ------------------------------>
|
||||
<h2>/api/packets</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/packets</span>
|
||||
<p>Fetch packets with many filters. Returns decoded packet data.</p>
|
||||
|
||||
<h3>Query Parameters</h3>
|
||||
<table>
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td>packet_id</td><td>Return exactly one packet</td></tr>
|
||||
<tr><td>limit</td><td>Max number of results (1–100)</td></tr>
|
||||
<tr><td>since</td><td>Only packets newer than import_time_us</td></tr>
|
||||
<tr><td>from_node_id</td><td>Filter by sender node</td></tr>
|
||||
<tr><td>to_node_id</td><td>Filter by destination node</td></tr>
|
||||
<tr><td>node_id</td><td>Legacy: match either from or to</td></tr>
|
||||
<tr><td>portnum</td><td>Filter by port number</td></tr>
|
||||
<tr><td>contains</td><td>Substring filter for payload</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="example">
|
||||
<b>Example:</b><br>
|
||||
<code>/api/packets?from_node_id=123&limit=100</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ PACKETS SEEN ------------------------------>
|
||||
<h2>/api/packets_seen/{packet_id}</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/packets_seen/<packet_id></span>
|
||||
<p>Returns list of gateways that heard the packet (RSSI/SNR/hops).</p>
|
||||
|
||||
<div class="example">
|
||||
<b>Example:</b><br>
|
||||
<code>/api/packets_seen/3314808102</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ STATS ------------------------------>
|
||||
<h2>/api/stats</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/stats</span>
|
||||
<p>Returns aggregated packet statistics for a node or globally.</p>
|
||||
|
||||
<h3>Query Parameters</h3>
|
||||
<table>
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td>period_type</td><td>"hour" or "day"</td></tr>
|
||||
<tr><td>length</td><td>How many hours/days</td></tr>
|
||||
<tr><td>node</td><td>Node ID for combined sent+seen stats</td></tr>
|
||||
<tr><td>from_node</td><td>Filter by sender</td></tr>
|
||||
<tr><td>to_node</td><td>Filter by receiver</td></tr>
|
||||
<tr><td>portnum</td><td>Filter by port</td></tr>
|
||||
<tr><td>channel</td><td>Filter by channel</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="example">
|
||||
<b>Example:</b><br>
|
||||
<code>/api/stats?node=1128180332&period_type=day&length=1</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ STATS COUNT ------------------------------>
|
||||
<h2>/api/stats/count</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/stats/count</span>
|
||||
<p>
|
||||
Returns <b>total packets</b> and <b>total packet_seen entries</b>.
|
||||
When no filters are provided, it returns global totals.
|
||||
When filters are specified, they narrow the time, channel,
|
||||
direction, or specific packet.
|
||||
</p>
|
||||
|
||||
<h3>Query Parameters</h3>
|
||||
<table>
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td>period_type</td><td>"hour" or "day"</td></tr>
|
||||
<tr><td>length</td><td>Number of hours or days (depends on period_type)</td></tr>
|
||||
<tr><td>channel</td><td>Filter by channel</td></tr>
|
||||
<tr><td>from_node</td><td>Only packets sent by this node</td></tr>
|
||||
<tr><td>to_node</td><td>Only packets received by this node</td></tr>
|
||||
<tr><td>packet_id</td><td>Filter seen counts for specific packet_id</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="example">
|
||||
<b>Example:</b><br>
|
||||
<code>/api/stats/count?from_node=1128180332&period_type=day&length=1</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!------------------------------ EDGES ------------------------------>
|
||||
<h2>/api/edges</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/edges</span>
|
||||
<p>Returns traceroute and/or neighbor edges for graph rendering.</p>
|
||||
|
||||
<h3>Query Parameters</h3>
|
||||
<table>
|
||||
<tr><th>Parameter</th><th>Description</th></tr>
|
||||
<tr><td>type</td><td>"traceroute", "neighbor", or omitted for both</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="example">
|
||||
<b>Example:</b><br>
|
||||
<code>/api/edges?type=neighbor</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ CONFIG ------------------------------>
|
||||
<h2>/api/config</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/config</span>
|
||||
<p>Returns Meshview configuration (site, MQTT, cleanup, etc.).</p>
|
||||
|
||||
<div class="example">
|
||||
<code>/api/config</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ LANG ------------------------------>
|
||||
<h2>/api/lang</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/api/lang</span>
|
||||
<p>Returns translated text for the UI.</p>
|
||||
|
||||
<h3>Parameters</h3>
|
||||
<table>
|
||||
<tr><th>lang</th><td>Language code (e.g. "en")</td></tr>
|
||||
<tr><th>section</th><td>Optional UI section (firehose, map, top...)</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="example">
|
||||
<code>/api/lang?lang=en§ion=firehose</code>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ HEALTH ------------------------------>
|
||||
<h2>/health</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/health</span>
|
||||
<p>Returns API + database status.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<!------------------------------ VERSION ------------------------------>
|
||||
<h2>/version</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<span class="path">/version</span>
|
||||
<p>Returns Meshview version and Git revision.</p>
|
||||
</div>
|
||||
|
||||
|
||||
<br><br>
|
||||
<hr>
|
||||
</section>
|
||||
<h2 id="2-packets-api">2. Packets API</h2>
|
||||
<section class="endpoint" id="get-api-packets"><h3><span class="method">GET</span> <code>/api/packets</code></h3>
|
||||
<p>Returns packets with optional filters.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>packet_id</code> (optional, decimal int): Return one packet by database row ID (overrides other filters).</li><li><code>limit</code> (optional, int): Max packets to return, clamped 1-1000. Default: <code>50</code>.</li><li><code>since</code> (optional, int): Only packets imported after this microsecond timestamp.</li><li><code>portnum</code> (optional, int): Filter by port number.</li><li><code>contains</code> (optional, string): Payload substring filter.</li><li><code>from_node_id</code> (optional, int): Filter by sender node ID.</li><li><code>to_node_id</code> (optional, int): Filter by recipient node ID.</li><li><code>node_id</code> (optional, int): Legacy filter matching either from or to node ID.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"packets": [
|
||||
{
|
||||
"id": 123,
|
||||
"storage_id": 123,
|
||||
"packet_id": 3314808102,
|
||||
"import_time_us": 1736370123456789,
|
||||
"channel": "main",
|
||||
"from_node_id": 5678,
|
||||
"to_node_id": 4294967295,
|
||||
"portnum": 1,
|
||||
"long_name": "Alice",
|
||||
"payload": "Hello, mesh!",
|
||||
"to_long_name": null,
|
||||
"reply_id": 122
|
||||
}
|
||||
],
|
||||
"latest_import_time": 1736370123456789
|
||||
}</code></pre>
|
||||
<p>Notes</p>
|
||||
<ul><li>For <code>portnum=1</code> (text messages), packets are filtered to remove sequence-only payloads.</li><li>Results are newest first. <code>since</code> is strictly greater than the supplied timestamp. Store <code>latest_import_time</code> for the next poll and deduplicate by <code>id</code>. A bounded result can omit older records if more packets arrive than the requested limit; this endpoint is not a durable cursor or backfill API.</li><li><code>latest_import_time</code> is returned only when the list response has a positive import timestamp; it is absent for empty results and single-packet lookups.</li><li><code>packet_id</code> lookup returns <code>{"packets":[]}</code> with HTTP 200 when missing. Its objects omit <code>to_long_name</code> and <code>reply_id</code>; nullable <code>portnum</code> is possible in this mode.</li><li><code>contains</code> is case-insensitive. With <code>portnum=1</code>, matching is performed on decoded displayed payload text (including redaction placeholders) after the database limit is applied, so fewer than <code>limit</code> results may be returned. For other requests, it searches stored payload bytes cast to text; this is not a general search over decoded protobuf fields.</li><li>Invalid <code>limit</code> falls back to 50. Invalid <code>since</code>, <code>portnum</code>, and node filters are logged and ignored. Invalid single-packet IDs return HTTP 400; handler failures return HTTP 500 with <code>{"error":"Failed to fetch packets"}</code>.</li></ul>
|
||||
<hr>
|
||||
</section>
|
||||
<h2 id="3-channels-api">3. Channels API</h2>
|
||||
<section class="endpoint" id="get-api-channels"><h3><span class="method">GET</span> <code>/api/channels</code></h3>
|
||||
<p>Returns channels seen in a time period.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>period_type</code> (optional, string): <code>hour</code> or <code>day</code>. Default: <code>hour</code>.</li><li><code>length</code> (optional, int): Number of periods to look back. Default: <code>24</code>.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"channels": ["LongFast", "MediumFast", "ShortFast"]
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p>Errors: storage/period failures return HTTP 200 with <code>channels: []</code> and an <code>error</code> field. Non-integer <code>length</code> is parsed outside that handler and can return HTTP 500. Use a positive integer length and the literal <code>hour</code> or <code>day</code>.</p>
|
||||
</section>
|
||||
<h2 id="4-stats-api">4. Stats API</h2>
|
||||
<section class="endpoint" id="get-api-stats"><h3><span class="method">GET</span> <code>/api/stats</code></h3>
|
||||
<p>Returns packet statistics aggregated by time periods, with optional filtering.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>period_type</code> (optional, string): <code>hour</code> or <code>day</code>. Default: <code>hour</code>.</li><li><code>length</code> (optional, int): Number of periods to include. Default: <code>24</code>.</li><li><code>channel</code> (optional, string): Filter by channel (case-insensitive).</li><li><code>portnum</code> (optional, int): Filter by port number.</li><li><code>to_node</code> (optional, int): Filter by destination node ID.</li><li><code>from_node</code> (optional, int): Filter by source node ID.</li><li><code>node</code> (optional, int): If provided, return combined <code>sent</code> and <code>seen</code> totals for that node.</li></ul>
|
||||
<p>Response Example (series)</p>
|
||||
<pre><code class="language-json">{
|
||||
"period_type": "hour",
|
||||
"length": 24,
|
||||
"channel": "LongFast",
|
||||
"portnum": 1,
|
||||
"to_node": 12345678,
|
||||
"from_node": 87654321,
|
||||
"data": [
|
||||
{ "period": "2025-08-08 14:00", "count": 10 },
|
||||
{ "period": "2025-08-08 15:00", "count": 7 }
|
||||
]
|
||||
}</code></pre>
|
||||
<p>Response Example (<code>node</code> totals)</p>
|
||||
<pre><code class="language-json">{
|
||||
"node_id": 12345678,
|
||||
"period_type": "hour",
|
||||
"length": 24,
|
||||
"sent": 0,
|
||||
"seen": 0
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p>The series response contains only buckets with records, ordered oldest first; missing hours/days are not filled with zeroes. Periods are UTC strings.</p>
|
||||
<p>Current <code>node</code>-mode limitation: the handler reads a <code>total</code> key that the statistics helper does not provide, so <code>sent</code> and <code>seen</code> currently return zero. It also uses recipient filtering for the second query, rather than gateway observations. This mode ignores the other filters. For usable sent/observation totals, request <code>/api/stats/count?from_node=1234&period_type=day&length=1</code> instead.</p>
|
||||
<p>Errors: HTTP 400 for an unsupported <code>period_type</code>, non-integer <code>length</code>, <code>node</code>, <code>portnum</code>, <code>from_node</code>, or <code>to_node</code>. Storage failures can return HTTP 500. Use a positive <code>length</code>; the handler does not impose a positive lower bound.</p>
|
||||
</section>
|
||||
<section class="endpoint" id="get-api-stats-count"><h3><span class="method">GET</span> <code>/api/stats/count</code></h3>
|
||||
<p>Returns total packet counts, optionally filtered.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>packet_id</code> (optional, int): Filter packet_seen by packet ID.</li><li><code>period_type</code> (optional, string): <code>hour</code> or <code>day</code>.</li><li><code>length</code> (optional, int): Number of periods to include.</li><li><code>channel</code> (optional, string): Filter by channel.</li><li><code>from_node</code> (optional, int): Filter by source node ID.</li><li><code>to_node</code> (optional, int): Filter by destination node ID.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"total_packets": 12345,
|
||||
"total_seen": 67890
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p>Without filters, counts cover the whole retained database. With time, channel, or direction filters, omitted time settings default to <code>period_type=day&length=1</code>. <code>total_seen</code> counts observation rows for packets matching the packet import-time window, not distinct gateways. Channel matching is case-insensitive.</p>
|
||||
<p><code>packet_id</code> applies only to <code>total_seen</code> and overrides its other filters: it counts all observations of that database packet ID. It does not narrow <code>total_packets</code>. In particular, <code>packet_id</code> alone leaves <code>total_packets</code> as the global packet total.</p>
|
||||
<p>Errors: HTTP 400 for non-integer ID/length filters. Unsupported <code>period_type</code> or storage failures can return HTTP 500; use <code>hour</code> or <code>day</code> and a positive length.</p>
|
||||
</section>
|
||||
<section class="endpoint" id="get-api-stats-top"><h3><span class="method">GET</span> <code>/api/stats/top</code></h3>
|
||||
<p>Returns nodes sorted by packets seen, with pagination.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>period_type</code> (optional, string): <code>hour</code> or <code>day</code>. Default: <code>day</code>.</li><li><code>length</code> (optional, int): Number of periods to include. Default: <code>1</code>.</li><li><code>channel</code> (optional, string): Filter by channel.</li><li><code>limit</code> (optional, int): Max nodes to return. Default: <code>20</code>, max <code>100</code>.</li><li><code>offset</code> (optional, int): Pagination offset. Default: <code>0</code>.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"total": 250,
|
||||
"limit": 20,
|
||||
"offset": 0,
|
||||
"nodes": [
|
||||
{
|
||||
"node_id": 1234,
|
||||
"long_name": "Alice",
|
||||
"short_name": "A",
|
||||
"channel": "main",
|
||||
"sent": 100,
|
||||
"seen": 240,
|
||||
"avg": 2.4
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p><code>sent</code> counts packet records from each node; <code>seen</code> counts observation records for that sender's packets. <code>avg</code> is <code>round(seen / max(sent, 1), 2)</code>, not a distinct-gateway count. Windows are anchored to the newest packet and newest observation in the respective tables, not wall-clock time. Nodes with zero activity are included; <code>total</code> counts nodes matching the channel filter, not just active nodes.</p>
|
||||
<p>Channel matching is exact. Use positive <code>length</code> and <code>limit</code>, and a nonnegative <code>offset</code>. Only the upper limit of 100 is enforced. Invalid numeric strings can return HTTP 500; any <code>period_type</code> other than the literal <code>hour</code> is treated as days.</p>
|
||||
</section>
|
||||
<h2 id="5-edges-api">5. Edges API</h2>
|
||||
<section class="endpoint" id="get-api-edges"><h3><span class="method">GET</span> <code>/api/edges</code></h3>
|
||||
<p>Returns network edges (connections between nodes) based on traceroutes and neighbor info. Traceroute edges are collected over the last 12 hours. Neighbor edges are based on port 71 packets.</p>
|
||||
<p>A completed traceroute is observed as a response packet, whose <code>from</code>/<code>to</code> are reversed with respect to the traced path, so edges are built as <code>to -> route[] -> from</code>. <code>route[]</code> may contain <code>0xFFFFFFFF</code> placeholders for hops the mesh could not identify; the edges on either side of such a placeholder are omitted, because the nodes around an unknown hop are not neighbours.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>type</code> (optional, string): <code>traceroute</code> or <code>neighbor</code>. If omitted, returns both.</li><li><code>node_id</code> (optional, int): Filter edges to only those touching a node.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"edges": [
|
||||
{ "from": 12345678, "to": 87654321, "type": "traceroute" },
|
||||
{ "from": 11111111, "to": 22222222, "type": "neighbor" }
|
||||
]
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p>Unknown <code>type</code> values return an empty edge list. Invalid <code>node_id</code> returns HTTP 400; storage failures can return HTTP 500. A missing node is not an error and normally returns an empty list. Neighbor edges come from the latest stored port-71 sample (the storage helper defaults to 50 packets), not the traceroute 12-hour window.</p>
|
||||
</section>
|
||||
<h2 id="6-daily-snapshots-and-configuration">6. Daily Snapshots and Configuration</h2>
|
||||
<section class="endpoint" id="get-api-snapshots-daily"><h3><span class="method">GET</span> <code>/api/snapshots/daily</code></h3>
|
||||
<p>Returns stored daily snapshots. For new snapshots, <code>packet_count</code> is the number of packet records imported during <code>date</code> (00:00 UTC inclusive to the next midnight exclusive). The scheduled capture records the previous complete UTC day. Repeated observations of the same packet are not counted separately. <code>node_count</code> counts distinct packet senders whose packets were imported or observed during that UTC day (including observations of previously imported packets). <code>gateway_count</code> counts distinct MQTT gateways with packet observations imported during that day. These are activity counts, not database totals; recipients alone do not count as active nodes. Activity uses local import timestamps, not device timestamps. Older snapshots retain their originally stored counts and are not automatically converted. Counts depend on the packet and observation history still retained at capture time.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>length</code> (optional, int): Return the latest N snapshot records, clamped to 1-3650. Omit for all stored snapshots. Results are always ordered by date ascending. This is a record limit, not a guarantee of consecutive calendar dates.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{"data":[{"date":"2026-10-24","node_count":143,"packet_count":28465,"gateway_count":17,"captured_at_us":1792886400000000}]}</code></pre>
|
||||
<p>No stored snapshots returns <code>{"data":[]}</code>. Invalid <code>length</code> returns HTTP 400; storage failures return HTTP 500. <code>captured_at_us</code> is the capture time, which may be later than the day summarized by <code>date</code>.</p>
|
||||
</section>
|
||||
<section class="endpoint" id="get-api-config"><h3><span class="method">GET</span> <code>/api/config</code></h3>
|
||||
<p>Returns a safe subset of server configuration.</p>
|
||||
<p><code>site.map_channel_colors</code> contains channel color overrides from the optional <code>[map_channel_colors]</code> INI section. Each entry is <code>channel = #RRGGBB</code>; invalid colors are omitted. Channel matching on the map ignores case, spaces, hyphens, and underscores. Unlisted channels use generated colors. For example:</p>
|
||||
<pre><code class="language-ini">[map_channel_colors]
|
||||
LongFast = #4363d8
|
||||
LocalChat = #18aa18</code></pre>
|
||||
<p>No query parameters are supported. Only the <code>site</code>, MQTT server/topics, and cleanup fields shown here are exposed; credentials and the database connection string are not returned. Feature flags and cleanup booleans are lowercase strings (<code>"true"</code> / <code>"false"</code>), not JSON booleans. Cleanup scheduling values are strings; map bounds are numbers and refresh intervals are integers. The removed <code>starting</code> option is not returned: <code>/</code> always serves the dashboard. <code>site.api</code> controls visibility of the API documentation link in the navigation bar, defaults to <code>"true"</code>, and can be disabled with <code>api = False</code> in <code>[site]</code>. This setting does not disable documentation or API routes. Restart the web server and reload the page after changing it. Handler failures return HTTP 500.</p>
|
||||
<p>Restart the web server and reload the map after changing these settings. Omitting the section uses generated colors for every channel.</p>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"site": {
|
||||
"domain": "example.com",
|
||||
"language": "en",
|
||||
"title": "Meshview",
|
||||
"message": "",
|
||||
"nodes": "true",
|
||||
"chat": "true",
|
||||
"everything": "true",
|
||||
"graphs": "true",
|
||||
"stats": "true",
|
||||
"net": "true",
|
||||
"map": "true",
|
||||
"top": "true",
|
||||
"api": "true",
|
||||
"map_top_left_lat": 39.0,
|
||||
"map_top_left_lon": -123.0,
|
||||
"map_bottom_right_lat": 36.0,
|
||||
"map_bottom_right_lon": -121.0,
|
||||
"map_interval": 3,
|
||||
"map_channel_colors": {"LongFast":"#4363d8"},
|
||||
"firehose_interval": 3,
|
||||
"weekly_net_message": "Weekly Mesh check-in message.",
|
||||
"net_tag": "#BayMeshNet",
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"mqtt": {
|
||||
"server": "mqtt.example.com",
|
||||
"topics": ["msh/region/#"]
|
||||
},
|
||||
"cleanup": {
|
||||
"enabled": "false",
|
||||
"days_to_keep": "14",
|
||||
"hour": "2",
|
||||
"minute": "0",
|
||||
"vacuum": "false"
|
||||
}
|
||||
}</code></pre>
|
||||
<hr>
|
||||
</section>
|
||||
<h2 id="7-language-api">7. Language API</h2>
|
||||
<section class="endpoint" id="get-api-lang"><h3><span class="method">GET</span> <code>/api/lang</code></h3>
|
||||
<p>Returns translation strings.</p>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>lang</code> (optional, string): Language code (e.g., <code>en</code>, <code>es</code>). Default from config or <code>en</code>.</li><li><code>section</code> (optional, string): Return only one section (e.g., <code>nodelist</code>, <code>firehose</code>).</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"title": "Meshview",
|
||||
"search_placeholder": "Search..."
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p>Unknown or invalid language codes fall back to the English file. An unknown section returns HTTP 404. The response has no wrapper: it is either the full translation object or the requested section. Translation-file failures can return HTTP 500.</p>
|
||||
</section>
|
||||
<h2 id="8-packets-seen-api">8. Packets Seen API</h2>
|
||||
<section class="endpoint" id="get-api-packets-seen-packet-id"><h3><span class="method">GET</span> <code>/api/packets_seen/{packet_id}</code></h3>
|
||||
<p>Returns packet_seen entries for a packet.</p>
|
||||
<p>Path Parameters</p>
|
||||
<ul><li><code>packet_id</code> (required, int): Packet ID.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"seen": [
|
||||
{
|
||||
"packet_id": 123,
|
||||
"node_id": 456,
|
||||
"rx_time": 1753188300,
|
||||
"hop_limit": 7,
|
||||
"hop_start": 0,
|
||||
"channel": "main",
|
||||
"rx_snr": 5.0,
|
||||
"rx_rssi": -90,
|
||||
"topic": "msh/region/#",
|
||||
"import_time_us": 1736370123456789
|
||||
}
|
||||
]
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p><code>node_id</code> identifies the observing MQTT gateway. <code>rx_time</code> is the device-provided receive time in Unix seconds, while <code>import_time_us</code> is local import time in microseconds. Signal fields can be null. Multiple rows can describe the same gateway; consumers wanting unique gateways must deduplicate them. Hop count is usually <code>max(0, hop_start - hop_limit)</code> when both values are known. Observations do not by themselves prove a direct radio link from the sender to that gateway.</p>
|
||||
<p>No observations, including for an unknown packet, returns <code>{"seen":[]}</code> with HTTP 200. Invalid path IDs return HTTP 400; handler failures return HTTP 500.</p>
|
||||
</section>
|
||||
<h2 id="9-traceroute-api">9. Traceroute API</h2>
|
||||
<section class="endpoint" id="get-api-traceroute-packet-id"><h3><span class="method">GET</span> <code>/api/traceroute/{packet_id}</code></h3>
|
||||
<p>Returns traceroute details and derived paths for a packet.</p>
|
||||
<p>Path Parameters</p>
|
||||
<ul><li><code>packet_id</code> (required, int): Packet ID.</li></ul>
|
||||
<p>A completed traceroute is observed as a response packet, whose <code>from</code>/<code>to</code> are reversed with respect to the traced path. <code>initiator</code> and <code>target</code> resolve this: the forward path runs <code>initiator -> forward_hops -> target</code> and the return path runs <code>target -> reverse_hops -> initiator</code>, in both directions of travel. <code>forward_hops</code> and <code>reverse_hops</code> contain only the intermediate hops, never the endpoints.</p>
|
||||
<p>A gateway usually reports a response that is still travelling home, so <code>reverse_hops</code> is often incomplete. <code>reverse_complete</code> says whether that observation had reached the initiator; only then does the corresponding <code>winning_paths.reverse</code> entry end at the initiator.</p>
|
||||
<p><code>winning_paths</code> is built from response observations, since a response proves the request reached the target. <code>complete</code> on a <code>unique_forward_paths</code> entry says whether some response reported that hop list, and so whether it is known to end at the target.</p>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"packet": {
|
||||
"id": 123,
|
||||
"from": 222,
|
||||
"to": 111,
|
||||
"initiator": 111,
|
||||
"target": 222,
|
||||
"channel": "main"
|
||||
},
|
||||
"traceroute_packets": [
|
||||
{
|
||||
"index": 0,
|
||||
"gateway_node_id": 333,
|
||||
"done": true,
|
||||
"forward_hops": [444, 555],
|
||||
"reverse_hops": [555, 444],
|
||||
"reverse_complete": true
|
||||
}
|
||||
],
|
||||
"unique_forward_paths": [
|
||||
{ "path": [444, 555], "count": 2, "complete": true }
|
||||
],
|
||||
"unique_reverse_paths": [
|
||||
[555, 444]
|
||||
],
|
||||
"winning_paths": {
|
||||
"forward": [[111, 444, 555, 222]],
|
||||
"reverse": [[222, 555, 444, 111]]
|
||||
}
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p><code>traceroute_packets</code> can be empty even when the packet exists. Unknown database packet IDs return HTTP 404. Invalid integer IDs and storage failures can return HTTP 500; this handler does not implement a separate HTTP 400 validation branch.</p>
|
||||
</section>
|
||||
<h2 id="10-health-api">10. Health API</h2>
|
||||
<section class="endpoint" id="get-health"><h3><span class="method">GET</span> <code>/health</code></h3>
|
||||
<p>Returns service health and database status.</p>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"status": "healthy",
|
||||
"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
|
||||
}</code></pre>
|
||||
<hr>
|
||||
<p>No query parameters. HTTP 200 reports <code>status: "healthy"</code> with database connectivity. A database failure returns HTTP 503 with <code>status: "unhealthy"</code> and <code>database: "disconnected"</code>. <code>seconds_since_last_message</code> is included only when a latest imported packet exists; SQLite size fields appear only when available. Cleanup and backup reports include configured schedules and status-file contents when present. Their status may be <code>disabled</code>, <code>unknown</code>, <code>error</code>, or the last job's recorded status; a failed backup/cleanup does not itself change the top-level HTTP status. The optional <code>last_run</code> objects depend on the job's stored report.</p>
|
||||
</section>
|
||||
<h2 id="11-version-api">11. Version API</h2>
|
||||
<section class="endpoint" id="get-version"><h3><span class="method">GET</span> <code>/version</code></h3>
|
||||
<p>Returns version metadata.</p>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"version": "3.0.3",
|
||||
"release_date": "2026-1-15",
|
||||
"git_revision": "abc1234",
|
||||
"git_revision_short": "abc1234"
|
||||
}</code></pre>
|
||||
<p>No query parameters. HTTP 500 with an <code>error</code> field if version metadata cannot be retrieved. A revision may be <code>unknown</code> if Git metadata is unavailable.</p>
|
||||
</section>
|
||||
<h2 id="12-node-contact-url">12. Node Contact URL</h2>
|
||||
<section class="endpoint" id="get-api-node-node-id-qr"><h3><span class="method">GET</span> <code>/api/node/{node_id}/qr</code></h3>
|
||||
<p>Returns a Meshtastic shared-contact URL as JSON, not a PNG or SVG image. The client can encode <code>meshtastic_url</code> in a QR code. No query parameters are supported.</p>
|
||||
<p>Path Parameters</p>
|
||||
<ul><li><code>node_id</code> (required, int): Node number in decimal or <code>0x</code> hexadecimal form.</li></ul>
|
||||
<p>Response Example</p>
|
||||
<pre><code class="language-json">{
|
||||
"node_id":1234,
|
||||
"long_name":"Alice",
|
||||
"short_name":"A",
|
||||
"role":"CLIENT",
|
||||
"meshtastic_url":"https://meshtastic.org/v/#BASE64URL_CONTACT"
|
||||
}</code></pre>
|
||||
<p>The example contact payload is a placeholder, not an importable contact. The URL encodes node identity and available user metadata as a base64url SharedContact protobuf, with <code>manually_verified</code> false. Metadata can be null.</p>
|
||||
<p>Errors: HTTP 400 for invalid IDs; HTTP 404 when the node is absent; HTTP 500 for contact serialization failures or unhandled storage errors.</p>
|
||||
</section>
|
||||
<h2 id="13-predicted-radio-coverage">13. Predicted Radio Coverage</h2>
|
||||
<section class="endpoint" id="get-api-coverage-node-id"><h3><span class="method">GET</span> <code>/api/coverage/{node_id}</code></h3>
|
||||
<p>Computes an ITM area-model prediction centered on the node's last stored position. This is a model prediction, not a measured coverage boundary or terrain profile. The optional <code>pyitm</code> dependency is required. Calculations run off the event loop and reuse cached model results. All parameters are optional except the node ID.</p>
|
||||
<p>Path Parameters</p>
|
||||
<ul><li><code>node_id</code> (required, int): Node number in decimal or <code>0x</code> hexadecimal form.</li></ul>
|
||||
<p>Query Parameters</p>
|
||||
<ul><li><code>mode</code> (string, default <code>perimeter</code>): <code>perimeter</code> or <code>heatmap</code>. Currently every value other than the exact string <code>perimeter</code> selects the heatmap branch.</li><li><code>freq_mhz</code> (number, default <code>907</code>): Frequency in MHz; range 1-10000.</li><li><code>tx_dbm</code> (number, default <code>20</code>): Transmit power in dBm; range -50 to 60.</li><li><code>tx_height_m</code> (number, default <code>5</code>): Transmit antenna height in meters; range 0-1000.</li><li><code>rx_height_m</code> (number, default <code>1.5</code>): Receive antenna height in meters; range 0-1000.</li><li><code>radius_km</code> (number, default <code>40</code>): Maximum distance in kilometers; range 1-200.</li><li><code>step_km</code> (number, default <code>0.25</code>): Radial sample spacing in kilometers; range 0.05-50.</li><li><code>reliability</code> (number, default <code>0.5</code>): ITM time fraction; range 0.01-0.99.</li><li><code>threshold_dbm</code> (number, default <code>-120</code>): Perimeter received-power threshold in dBm; range -200 to 0. Ignored by heatmap computation, although still validated.</li></ul>
|
||||
<p>Numeric bounds are inclusive, values must be finite, and <code>radius_km / step_km</code> must not exceed 4000. Smaller steps increase computation cost.</p>
|
||||
<p>Response Example (<code>mode=perimeter</code>)</p>
|
||||
<pre><code class="language-json">{
|
||||
"mode":"perimeter",
|
||||
"threshold_dbm":-120.0,
|
||||
"perimeter":[[30.21,-93.20],[30.209,-93.198]]
|
||||
}</code></pre>
|
||||
<p><code>perimeter</code> contains <code>[latitude, longitude]</code> degree pairs for the furthest qualifying sample on each modeled bearing. Bearings with no qualifying sample are omitted; the list is not necessarily a closed GeoJSON polygon.</p>
|
||||
<p>Response Example (<code>mode=heatmap</code>)</p>
|
||||
<pre><code class="language-json">{
|
||||
"mode":"heatmap",
|
||||
"min_dbm":-130.0,
|
||||
"max_dbm":-80.0,
|
||||
"points":[[30.21,-93.20,-110.5]]
|
||||
}</code></pre>
|
||||
<p><code>points</code> contains <code>[latitude, longitude, received_power_dbm]</code> triples. Min/max values provide a color-scale range, extended from the defaults to include computed values. An empty perimeter or point list is a valid result when no samples qualify.</p>
|
||||
<p>Errors: HTTP 400 for invalid IDs, nonnumeric/nonfinite/out-of-range parameters, or an excessive radius/step ratio; HTTP 404 for an unknown node or missing/zero-valued stored coordinates; HTTP 503 when <code>pyitm</code> is unavailable. Dependency availability is checked before numeric query validation and node lookup. Unexpected model/storage failures can return HTTP 500.</p>
|
||||
</section>
|
||||
</main>
|
||||
<footer>Source: docs/API_Documentation.md · Generated with node scripts/build-api-docs.mjs</footer>
|
||||
<p style="text-align:center; color:#666;">Meshview API — generated documentation</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.6 KiB |
@@ -1,166 +0,0 @@
|
||||
/* Read-only chat presentation using Meshview's existing packet API. */
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const log = document.getElementById('chat-log');
|
||||
const channel = document.getElementById('channel-filter');
|
||||
const search = document.getElementById('chat-search');
|
||||
const status = document.getElementById('chat-status');
|
||||
const pause = document.getElementById('chat-pause');
|
||||
const latest = document.getElementById('chat-latest');
|
||||
const packets = new Map();
|
||||
let lastTime = null;
|
||||
let paused = false;
|
||||
let busy = false;
|
||||
let loaded = false;
|
||||
let unread = 0;
|
||||
let chatLang = {};
|
||||
const colors = ['#b54136', '#2563b4', '#23824d', '#8553af', '#a65d19', '#15817b', '#b63b79'];
|
||||
const timeOf = p => Number(p.import_time_us) || Date.parse(p.import_time) * 1000 || 0;
|
||||
const atBottom = () => log.scrollHeight - log.scrollTop - log.clientHeight < 60;
|
||||
const nodeName = p => (p.long_name || '').trim() || `Node ${p.from_node_id}`;
|
||||
const packetUrl = id => `/packet/${encodeURIComponent(id)}`;
|
||||
function setStatus(text, state) { status.textContent = text; status.dataset.state = state; }
|
||||
function goLatest() { log.scrollTop = log.scrollHeight; unread = 0; latest.textContent = '↓ Latest'; }
|
||||
|
||||
function render(scrollToBottom = false, highlights = new Set()) {
|
||||
const query = search.value.trim().toLowerCase();
|
||||
const sorted = [...packets.values()].sort((a, b) => timeOf(a) - timeOf(b));
|
||||
const visible = sorted.filter(p => (!channel.value || (p.channel || '') === channel.value) &&
|
||||
`${nodeName(p)} ${p.payload || ''} ${p.from_node_id} ${p.channel || ''}`.toLowerCase().includes(query));
|
||||
const fragment = document.createDocumentFragment();
|
||||
let lastDay = '';
|
||||
const parents = new Map(sorted.map(p => [String(p.packet_id ?? p.id), p]));
|
||||
for (const packet of visible) {
|
||||
const date = new Date(timeOf(packet) / 1000);
|
||||
const day = date.toLocaleDateString([], { weekday:'long', month:'long', day:'numeric', year:'numeric' });
|
||||
if (day !== lastDay) {
|
||||
const separator = document.createElement('div');
|
||||
separator.className = 'chat-date-sep'; separator.textContent = day;
|
||||
fragment.append(separator); lastDay = day;
|
||||
}
|
||||
const row = document.createElement('article');
|
||||
row.className = `chat-line${highlights.has(String(packet.id)) ? ' flash' : ''}`;
|
||||
row.dataset.packetId = packet.id;
|
||||
let hash = 0;
|
||||
for (const char of String(packet.from_node_id)) hash = (hash * 31 + char.charCodeAt(0)) >>> 0;
|
||||
const time = document.createElement('time');
|
||||
time.className = 'chat-time'; time.dateTime = date.toISOString(); time.title = date.toLocaleString();
|
||||
time.textContent = date.toLocaleTimeString([], {hour:'2-digit', minute:'2-digit', hour12:false});
|
||||
const nick = document.createElement('a');
|
||||
nick.className = 'chat-nick'; nick.href = `/node/${encodeURIComponent(packet.from_node_id)}`;
|
||||
nick.textContent = nodeName(packet); nick.title = nodeName(packet); nick.style.color = colors[hash % colors.length];
|
||||
const message = document.createElement('div'); message.className = 'chat-message';
|
||||
// Mesh payloads and node names are untrusted text, never markup.
|
||||
message.textContent = packet.payload ?? '';
|
||||
if (packet.reply_id) {
|
||||
const reply = document.createElement('span'); reply.className = 'replying-to';
|
||||
const parent = parents.get(String(packet.reply_id)) || packets.get(String(packet.reply_id));
|
||||
reply.append(`${chatLang.replying_to || 'Replying to:'} `);
|
||||
if (parent) reply.append(`${nodeName(parent)}: ${parent.payload || ''}`);
|
||||
else {
|
||||
const link = document.createElement('a'); link.href = packetUrl(packet.reply_id);
|
||||
link.textContent = String(packet.reply_id); reply.append(link);
|
||||
}
|
||||
message.append(reply);
|
||||
}
|
||||
const meta = document.createElement('span'); meta.className = 'chat-meta';
|
||||
const tag = document.createElement('span'); tag.className = 'chat-channel';
|
||||
tag.textContent = packet.channel ? `# ${packet.channel}` : 'Unknown channel'; tag.title = packet.channel || 'Unknown channel';
|
||||
const details = document.createElement('a'); details.className = 'chat-details'; details.href = packetUrl(packet.id);
|
||||
details.textContent = 'Details ↗'; details.title = chatLang.view_packet_details || 'View packet details';
|
||||
details.setAttribute('aria-label', details.title);
|
||||
meta.append(tag, details); row.append(time, nick, message, meta); fragment.append(row);
|
||||
}
|
||||
if (!visible.length) {
|
||||
const empty = document.createElement('p'); empty.className = 'chat-empty';
|
||||
empty.textContent = packets.size ? 'No messages match your filters.' : 'No text messages received yet.';
|
||||
fragment.append(empty);
|
||||
}
|
||||
const previousTop = log.scrollTop;
|
||||
log.replaceChildren(fragment);
|
||||
document.getElementById('chat-count').textContent = `${visible.length} message${visible.length === 1 ? '' : 's'}`;
|
||||
if (scrollToBottom) goLatest(); else log.scrollTop = previousTop;
|
||||
}
|
||||
|
||||
async function fetchMessages() {
|
||||
if (paused || busy || document.hidden) return;
|
||||
busy = true;
|
||||
try {
|
||||
const url = new URL('/api/packets', location.origin);
|
||||
url.searchParams.set('portnum', '1'); url.searchParams.set('limit', '100');
|
||||
if (lastTime) url.searchParams.set('since', lastTime);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
const data = await response.json();
|
||||
if (!Array.isArray(data.packets)) throw new Error('Invalid packet response');
|
||||
const follow = !loaded || atBottom();
|
||||
const added = new Set();
|
||||
for (const packet of data.packets) {
|
||||
const id = String(packet.id);
|
||||
if (!packets.has(id)) { packets.set(id, packet); added.add(id); }
|
||||
if (packet.channel && ![...channel.options].some(o => o.value === packet.channel)) {
|
||||
channel.add(new Option(packet.channel, packet.channel));
|
||||
}
|
||||
}
|
||||
// Keep the browser's session history bounded without changing the API.
|
||||
if (packets.size > 1000) {
|
||||
const oldest = [...packets.values()].sort((a, b) => timeOf(a) - timeOf(b));
|
||||
for (const p of oldest.slice(0, packets.size - 1000)) packets.delete(String(p.id));
|
||||
}
|
||||
if (!loaded || added.size) render(follow, loaded ? added : new Set());
|
||||
if (loaded && !follow && added.size) {
|
||||
unread += [...added].filter(id => {
|
||||
const p = packets.get(id);
|
||||
return p && (!channel.value || p.channel === channel.value) &&
|
||||
`${nodeName(p)} ${p.payload || ''} ${p.from_node_id} ${p.channel || ''}`.toLowerCase().includes(search.value.trim().toLowerCase());
|
||||
}).length;
|
||||
latest.textContent = unread ? `↓ Latest (${unread})` : '↓ Latest';
|
||||
}
|
||||
lastTime = data.latest_import_time || lastTime;
|
||||
loaded = true;
|
||||
setStatus(paused ? 'Paused' : 'Live', paused ? 'paused' : 'live');
|
||||
document.getElementById('chat-updated').textContent = `Updated ${new Date().toLocaleTimeString([], {hour:'2-digit',minute:'2-digit'})}`;
|
||||
} catch (error) {
|
||||
console.error('Chat fetch:', error);
|
||||
if (!paused) setStatus('Retrying…', 'error');
|
||||
if (!loaded) log.innerHTML = '<p class="chat-empty">Unable to load messages. Retrying automatically…</p>';
|
||||
} finally { busy = false; }
|
||||
}
|
||||
|
||||
channel.addEventListener('change', () => render(true));
|
||||
search.addEventListener('input', () => render(true));
|
||||
latest.addEventListener('click', goLatest);
|
||||
log.addEventListener('scroll', () => { if (atBottom()) { unread = 0; latest.textContent = '↓ Latest'; } });
|
||||
pause.addEventListener('click', () => {
|
||||
paused = !paused; pause.setAttribute('aria-pressed', String(paused));
|
||||
pause.textContent = paused ? 'Resume' : 'Pause';
|
||||
setStatus(paused ? 'Paused' : 'Connecting…', paused ? 'paused' : 'loading');
|
||||
if (!paused) fetchMessages();
|
||||
});
|
||||
document.addEventListener('visibilitychange', () => { if (!document.hidden) fetchMessages(); });
|
||||
|
||||
// Load optional translations and channel metadata without delaying messages.
|
||||
(async () => {
|
||||
try {
|
||||
const cfg = await window._siteConfigPromise;
|
||||
const response = await fetch(`/api/lang?lang=${encodeURIComponent(cfg?.site?.language || 'en')}§ion=chat`);
|
||||
if (!response.ok) return;
|
||||
chatLang = await response.json();
|
||||
document.querySelectorAll('[data-chat-translate]').forEach(el => {
|
||||
if (chatLang[el.dataset.chatTranslate]) el.textContent = chatLang[el.dataset.chatTranslate];
|
||||
});
|
||||
if (loaded) render(atBottom());
|
||||
} catch (error) { console.error('Chat translations:', error); }
|
||||
})();
|
||||
(async () => {
|
||||
try {
|
||||
const response = await fetch('/api/channels');
|
||||
if (!response.ok) return;
|
||||
const data = await response.json();
|
||||
for (const name of data.channels || []) {
|
||||
if (![...channel.options].some(o => o.value === name)) channel.add(new Option(name, name));
|
||||
}
|
||||
} catch (error) { console.error('Chat channels:', error); }
|
||||
})();
|
||||
await fetchMessages();
|
||||
setInterval(fetchMessages, 5000);
|
||||
});
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 15 KiB |
@@ -4,7 +4,6 @@
|
||||
<meta charset="utf-8" />
|
||||
<title>Mesh Nodes Population Heatmap</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
|
||||
<script src="/static/theme.js"></script>
|
||||
<style>
|
||||
body { margin: 0; background: #000; }
|
||||
#map { height: 100vh; width: 100%; }
|
||||
@@ -20,82 +19,8 @@
|
||||
.legend-item { display: flex; align-items: center; margin-bottom: 5px; }
|
||||
.legend-color { width: 18px; height: 18px; margin-right: 6px; border-radius: 3px; }
|
||||
</style>
|
||||
<!-- mesh-theme:start -->
|
||||
<style>
|
||||
:root {
|
||||
color-scheme:light;
|
||||
--mesh-primary:#187346;
|
||||
--mesh-primary-dark:#0f5132;
|
||||
--mesh-primary-rgb:24,115,70;
|
||||
--mesh-brand:#187346;
|
||||
--mesh-brand-deep:#0f5132;
|
||||
--mesh-surface:#ffffff;
|
||||
--mesh-text:#243247;
|
||||
--mesh-soft:#eaf5ee;
|
||||
--mesh-hover:#dceee2;
|
||||
--mesh-border:#dce7df;
|
||||
--mesh-page:#f5f9f6;
|
||||
--mesh-stripe:#f7faf8;
|
||||
--mesh-muted:#64748b;
|
||||
--mesh-chat-stripe:#eef6f0;
|
||||
--mesh-pulse-soft:#edf8f0;
|
||||
--mesh-pulse-peak:#ccebd7;
|
||||
--mesh-pulse-mid:#e2f3e8;
|
||||
}
|
||||
[data-bs-theme="dark"] {
|
||||
color-scheme:dark;
|
||||
--mesh-primary:#80cfa3;
|
||||
--mesh-primary-dark:#a3e3be;
|
||||
--mesh-primary-rgb:128,207,163;
|
||||
--mesh-brand:#14532d;
|
||||
--mesh-brand-deep:#0c3a1f;
|
||||
--mesh-surface:#18231e;
|
||||
--mesh-text:#e2ece5;
|
||||
--mesh-soft:#203c2b;
|
||||
--mesh-hover:#294c36;
|
||||
--mesh-border:#34483c;
|
||||
--mesh-page:#101914;
|
||||
--mesh-stripe:#1c2a22;
|
||||
--mesh-muted:#9faea6;
|
||||
--mesh-chat-stripe:#203227;
|
||||
--mesh-pulse-soft:#203c2b;
|
||||
--mesh-pulse-peak:#356b49;
|
||||
--mesh-pulse-mid:#294c36;
|
||||
--bs-link-color:var(--mesh-primary);
|
||||
--bs-link-color-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-hover-color:var(--mesh-primary-dark);
|
||||
--bs-link-hover-color-rgb:163,227,190;
|
||||
}
|
||||
body { background:var(--mesh-page); color:var(--mesh-text); }
|
||||
.mesh-theme-toggle { flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border:1px solid #ffffff70; border-radius:6px; background:transparent; color:white; font:22px/1 system-ui,sans-serif; cursor:pointer; }
|
||||
.mesh-header .mesh-theme-toggle { margin-left:auto; }
|
||||
.mesh-theme-toggle:hover { background:#ffffff20; }
|
||||
.mesh-theme-toggle:focus-visible { outline:2px solid white; outline-offset:3px; }
|
||||
@media(max-width:1000px) { .mesh-header .mesh-menu-toggle { margin-left:auto; } .mesh-header .mesh-theme-toggle { margin-left:12px; } .mesh-header #site-menu { order:4; } }
|
||||
[data-bs-theme="dark"] :is(.chat-status,.chat-details,.chat-channel,.chat-status[data-state="paused"],.chat-status[data-state="loading"],.good-x) { background:var(--mesh-soft); color:var(--mesh-primary); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.chat-status[data-state="error"],.bad-x) { background:#472a24; color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .ok-x { background:#453820; color:#f1d38a; }
|
||||
[data-bs-theme="dark"] .chat-details:hover { background:var(--mesh-hover); color:var(--mesh-primary-dark); }
|
||||
[data-bs-theme="dark"] .chat-nick { filter:brightness(1.4) saturate(.8); }
|
||||
[data-bs-theme="dark"] :is(.summary-card:nth-child(2) .summary-count,.summary-card:nth-child(3) .summary-count,.summary-card:nth-child(4) .summary-count,.mesh-metric:nth-child(2) strong,.mesh-metric:nth-child(3) strong,.reach-metric:nth-child(2) .reach-metric-value) { color:var(--mesh-primary); }
|
||||
[data-bs-theme="dark"] :is(.reliability-status-heard) { color:#8fd7aa!important; }
|
||||
[data-bs-theme="dark"] .reliability-status-missed { color:#ffb4a6!important; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-value span { color:#17263c; }
|
||||
[data-bs-theme="dark"] .leaflet-tile-pane { filter:invert(1) hue-rotate(180deg) brightness(.85) saturate(.75); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-container,.leaflet-control-layers,.leaflet-bar a,.leaflet-popup-content-wrapper,.leaflet-popup-tip,.leaflet-tooltip,.leaflet-control-attribution,.leaflet-control-scale-line,#unmapped-packets,#legend,#node-info,.legend) { background:var(--mesh-surface); color:var(--mesh-text); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-control-layers label,.leaflet-popup-close-button,#unmapped-packets h3,.unmapped-node,.blinking-tooltip,.legend) { color:var(--mesh-text); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-bar a:hover,.leaflet-control-layers-expanded) { background:var(--mesh-stripe); }
|
||||
[data-bs-theme="dark"] :is(.unmapped-empty,.reach-muted) { color:var(--mesh-muted); }
|
||||
[data-bs-theme="dark"] :is(.source-marker,.reach-map-marker) { color:white; }
|
||||
[data-bs-theme="dark"] .qr-image { background:white; }
|
||||
[data-bs-theme="dark"] :is(#traceroute-error,#map-load-status,.text-danger) { color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-track { background:var(--mesh-soft); }
|
||||
</style>
|
||||
|
||||
<!-- mesh-theme:end -->
|
||||
</head>
|
||||
<body>
|
||||
<button class="mesh-theme-toggle" style="position:fixed;top:12px;right:12px;z-index:2000;background:#187346" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false">☾</button>
|
||||
<div id="map"></div>
|
||||
<div id="legend"></div>
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
<meta charset="utf-8" />
|
||||
<title>Mesh Nodes Live Map</title>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/>
|
||||
<script src="/static/theme.js"></script>
|
||||
<style>
|
||||
body { margin: 0; font-family: monospace; background: #121212; color: #eee; }
|
||||
#map { height: 100vh; width: 100%; }
|
||||
@@ -34,82 +33,8 @@ body { margin: 0; font-family: monospace; background: #121212; color: #eee; }
|
||||
padding: 2px 5px;
|
||||
}
|
||||
</style>
|
||||
<!-- mesh-theme:start -->
|
||||
<style>
|
||||
:root {
|
||||
color-scheme:light;
|
||||
--mesh-primary:#187346;
|
||||
--mesh-primary-dark:#0f5132;
|
||||
--mesh-primary-rgb:24,115,70;
|
||||
--mesh-brand:#187346;
|
||||
--mesh-brand-deep:#0f5132;
|
||||
--mesh-surface:#ffffff;
|
||||
--mesh-text:#243247;
|
||||
--mesh-soft:#eaf5ee;
|
||||
--mesh-hover:#dceee2;
|
||||
--mesh-border:#dce7df;
|
||||
--mesh-page:#f5f9f6;
|
||||
--mesh-stripe:#f7faf8;
|
||||
--mesh-muted:#64748b;
|
||||
--mesh-chat-stripe:#eef6f0;
|
||||
--mesh-pulse-soft:#edf8f0;
|
||||
--mesh-pulse-peak:#ccebd7;
|
||||
--mesh-pulse-mid:#e2f3e8;
|
||||
}
|
||||
[data-bs-theme="dark"] {
|
||||
color-scheme:dark;
|
||||
--mesh-primary:#80cfa3;
|
||||
--mesh-primary-dark:#a3e3be;
|
||||
--mesh-primary-rgb:128,207,163;
|
||||
--mesh-brand:#14532d;
|
||||
--mesh-brand-deep:#0c3a1f;
|
||||
--mesh-surface:#18231e;
|
||||
--mesh-text:#e2ece5;
|
||||
--mesh-soft:#203c2b;
|
||||
--mesh-hover:#294c36;
|
||||
--mesh-border:#34483c;
|
||||
--mesh-page:#101914;
|
||||
--mesh-stripe:#1c2a22;
|
||||
--mesh-muted:#9faea6;
|
||||
--mesh-chat-stripe:#203227;
|
||||
--mesh-pulse-soft:#203c2b;
|
||||
--mesh-pulse-peak:#356b49;
|
||||
--mesh-pulse-mid:#294c36;
|
||||
--bs-link-color:var(--mesh-primary);
|
||||
--bs-link-color-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-hover-color:var(--mesh-primary-dark);
|
||||
--bs-link-hover-color-rgb:163,227,190;
|
||||
}
|
||||
body { background:var(--mesh-page); color:var(--mesh-text); }
|
||||
.mesh-theme-toggle { flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border:1px solid #ffffff70; border-radius:6px; background:transparent; color:white; font:22px/1 system-ui,sans-serif; cursor:pointer; }
|
||||
.mesh-header .mesh-theme-toggle { margin-left:auto; }
|
||||
.mesh-theme-toggle:hover { background:#ffffff20; }
|
||||
.mesh-theme-toggle:focus-visible { outline:2px solid white; outline-offset:3px; }
|
||||
@media(max-width:1000px) { .mesh-header .mesh-menu-toggle { margin-left:auto; } .mesh-header .mesh-theme-toggle { margin-left:12px; } .mesh-header #site-menu { order:4; } }
|
||||
[data-bs-theme="dark"] :is(.chat-status,.chat-details,.chat-channel,.chat-status[data-state="paused"],.chat-status[data-state="loading"],.good-x) { background:var(--mesh-soft); color:var(--mesh-primary); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.chat-status[data-state="error"],.bad-x) { background:#472a24; color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .ok-x { background:#453820; color:#f1d38a; }
|
||||
[data-bs-theme="dark"] .chat-details:hover { background:var(--mesh-hover); color:var(--mesh-primary-dark); }
|
||||
[data-bs-theme="dark"] .chat-nick { filter:brightness(1.4) saturate(.8); }
|
||||
[data-bs-theme="dark"] :is(.summary-card:nth-child(2) .summary-count,.summary-card:nth-child(3) .summary-count,.summary-card:nth-child(4) .summary-count,.mesh-metric:nth-child(2) strong,.mesh-metric:nth-child(3) strong,.reach-metric:nth-child(2) .reach-metric-value) { color:var(--mesh-primary); }
|
||||
[data-bs-theme="dark"] :is(.reliability-status-heard) { color:#8fd7aa!important; }
|
||||
[data-bs-theme="dark"] .reliability-status-missed { color:#ffb4a6!important; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-value span { color:#17263c; }
|
||||
[data-bs-theme="dark"] .leaflet-tile-pane { filter:invert(1) hue-rotate(180deg) brightness(.85) saturate(.75); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-container,.leaflet-control-layers,.leaflet-bar a,.leaflet-popup-content-wrapper,.leaflet-popup-tip,.leaflet-tooltip,.leaflet-control-attribution,.leaflet-control-scale-line,#unmapped-packets,#legend,#node-info,.legend) { background:var(--mesh-surface); color:var(--mesh-text); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-control-layers label,.leaflet-popup-close-button,#unmapped-packets h3,.unmapped-node,.blinking-tooltip,.legend) { color:var(--mesh-text); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-bar a:hover,.leaflet-control-layers-expanded) { background:var(--mesh-stripe); }
|
||||
[data-bs-theme="dark"] :is(.unmapped-empty,.reach-muted) { color:var(--mesh-muted); }
|
||||
[data-bs-theme="dark"] :is(.source-marker,.reach-map-marker) { color:white; }
|
||||
[data-bs-theme="dark"] .qr-image { background:white; }
|
||||
[data-bs-theme="dark"] :is(#traceroute-error,#map-load-status,.text-danger) { color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-track { background:var(--mesh-soft); }
|
||||
</style>
|
||||
|
||||
<!-- mesh-theme:end -->
|
||||
</head>
|
||||
<body>
|
||||
<button class="mesh-theme-toggle" style="position:fixed;top:12px;right:12px;z-index:2000;background:#187346" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false">☾</button>
|
||||
|
||||
<div id="map"></div>
|
||||
|
||||
@@ -180,12 +105,13 @@ body { background:var(--mesh-page); color:var(--mesh-text); }
|
||||
if(isInvalidCoord(node)) return;
|
||||
const lat = node.last_lat/1e7;
|
||||
const lng = node.last_long/1e7;
|
||||
const isRouter = node.role.toLowerCase().includes("router");
|
||||
|
||||
channels.add(node.channel);
|
||||
nodeMap.set(node.node_id,node);
|
||||
|
||||
const color = hashToColor(node.channel);
|
||||
const marker = L.circleMarker([lat,lng],{radius:6,color:"white",fillColor:color,fillOpacity:1,weight:0.7}).addTo(map);
|
||||
const marker = L.circleMarker([lat,lng],{radius:isRouter?9:7,color:"white",fillColor:color,fillOpacity:1,weight:0.7}).addTo(map);
|
||||
marker.nodeId = node.node_id;
|
||||
marker.originalColor = color;
|
||||
markerById[node.node_id]=marker;
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
/* UI only: reuse the map's nodes, markers, and existing API. */
|
||||
function initializeNodeExplorer() {
|
||||
const activeSince = Date.now() - 24 * 60 * 60 * 1000;
|
||||
if (document.getElementById('metric-nodes')) {
|
||||
document.getElementById('metric-nodes').textContent = nodes.length.toLocaleString();
|
||||
document.getElementById('metric-active').textContent = nodes.filter(n => n.last_seen_us / 1000 >= activeSince).length.toLocaleString();
|
||||
document.getElementById('metric-gateways').textContent = nodes.filter(n => n.is_mqtt_gateway).length.toLocaleString();
|
||||
}
|
||||
renderNodeExplorer();
|
||||
}
|
||||
|
||||
function renderNodeExplorer() {
|
||||
const query = document.getElementById('node-search').value.trim().toLowerCase();
|
||||
const matches = nodes.filter(n => `${n.long_name} ${n.short_name} ${n.key} ${Number(n.key).toString(16)}`.toLowerCase().includes(query));
|
||||
matches.sort((a, b) => (b.last_seen_us || 0) - (a.last_seen_us || 0));
|
||||
const list = document.getElementById('mesh-node-list');
|
||||
list.replaceChildren();
|
||||
document.getElementById('node-result-count').textContent = matches.length;
|
||||
if (!matches.length) {
|
||||
const empty = document.createElement('p');
|
||||
empty.className = 'mesh-empty';
|
||||
empty.textContent = query ? 'No nodes match your search.' : 'No nodes seen in the last 3 days.';
|
||||
list.append(empty);
|
||||
}
|
||||
for (const node of matches) {
|
||||
const row = document.createElement('button');
|
||||
row.type = 'button';
|
||||
row.className = 'mesh-node-row';
|
||||
const active = node.last_seen_us / 1000 >= Date.now() - 86400000;
|
||||
row.innerHTML = `<span class="mesh-node-dot${active ? '' : ' offline'}" aria-hidden="true"></span><span class="mesh-node-copy"><strong>${escapeHtml(node.long_name || node.short_name || String(node.key))}</strong><small>${escapeHtml(node.short_name || 'Node')} · ${active ? 'Seen within 24h' : 'Seen within 3 days'}</small></span><span class="mesh-node-role">${markerById[node.key] ? '↗' : 'No GPS'}</span>`;
|
||||
row.addEventListener('click', () => {
|
||||
const marker = markerById[node.key];
|
||||
if (!marker) {
|
||||
openMapNodeInspector(node);
|
||||
return;
|
||||
}
|
||||
// Selecting a search result also reveals it if a saved filter hid it.
|
||||
nodeLayer.addTo(map);
|
||||
nodeLayer.addLayer(marker);
|
||||
map.setView(marker.getLatLng(), Math.max(map.getZoom(), 12));
|
||||
marker.fire('click');
|
||||
});
|
||||
list.append(row);
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('node-search').addEventListener('input', renderNodeExplorer);
|
||||
document.getElementById('fit-network').addEventListener('click', () => {
|
||||
const points = Object.values(markerById).filter(marker => nodeLayer.hasLayer(marker)).map(marker => marker.getLatLng());
|
||||
if (points.length) map.fitBounds(L.latLngBounds(points), { padding: [35, 35], maxZoom: 13 });
|
||||
});
|
||||
|
||||
(async () => {
|
||||
if (!document.getElementById('metric-packets')) return;
|
||||
try {
|
||||
const response = await fetch('/api/stats/count');
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
const counts = await response.json();
|
||||
document.getElementById('metric-packets').textContent = Number(counts.total_packets || 0).toLocaleString();
|
||||
document.getElementById('metric-status').textContent = 'All packets in database';
|
||||
} catch (error) {
|
||||
document.getElementById('metric-status').textContent = 'Packet totals unavailable';
|
||||
console.error('Dashboard totals:', error);
|
||||
}
|
||||
})();
|
||||
@@ -1,165 +0,0 @@
|
||||
/* Shared node inspector for Home and Map, using existing APIs and packet events. */
|
||||
(() => {
|
||||
const byId = id => document.getElementById(id);
|
||||
let nodeRequest = null;
|
||||
let inspectedNodeId = null;
|
||||
let recentPackets = [];
|
||||
let telemetryTime = -1;
|
||||
const nodeKey = node => node.key ?? node.node_id;
|
||||
const findNode = id => nodeMap.get(Number(id)) || nodeMap.get(id);
|
||||
const nodeName = (id, fallback) => {
|
||||
const node = findNode(id);
|
||||
return node?.long_name || node?.short_name || fallback || `Node ${id}`;
|
||||
};
|
||||
const packetTime = packet => Number(packet.import_time_us) || 0;
|
||||
const packetId = packet => packet.storage_id ?? packet.id;
|
||||
const portName = packet => window.PORT_LABEL_MAP[packet.portnum] || `Port ${packet.portnum ?? '?'}`;
|
||||
const dateText = us => us ? new Date(Number(us) / 1000).toLocaleString() : 'Unknown time';
|
||||
const timeText = us => us ? new Date(Number(us) / 1000).toLocaleTimeString([], {hour:'2-digit', minute:'2-digit', hour12:false}) : '—';
|
||||
|
||||
|
||||
async function fetchJson(url, signal) {
|
||||
const response = await fetch(url, {signal});
|
||||
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||
return response.json();
|
||||
}
|
||||
function note(container, text) {
|
||||
const p = document.createElement('p');
|
||||
p.className = 'mesh-inspector-note'; p.textContent = text;
|
||||
container.replaceChildren(p);
|
||||
}
|
||||
function facts(node) {
|
||||
byId('inspector-name').textContent = node.long_name || node.short_name || `Node ${nodeKey(node)}`;
|
||||
byId('inspector-node-meta').textContent = `${node.short_name || 'Node'} · ${nodeKey(node)}`;
|
||||
const container = byId('inspector-facts'); container.replaceChildren();
|
||||
for (const [label, value] of [
|
||||
['Role', node.role || 'Unknown'], ['Hardware', node.hw_model || 'Unknown'],
|
||||
['Firmware', node.firmware || 'Unknown'], ['Channel', node.channel || 'Unknown'],
|
||||
['Gateway', node.is_mqtt_gateway == null ? 'Unknown' : node.is_mqtt_gateway ? 'Yes' : 'No'],
|
||||
['Last seen', dateText(node.last_seen_us)],
|
||||
['Location', isInvalidCoord(node) ? 'No reported position' : `${node.lat.toFixed(5)}, ${node.long.toFixed(5)}`]
|
||||
]) {
|
||||
const dt = document.createElement('dt'); dt.textContent = label;
|
||||
const dd = document.createElement('dd'); dd.textContent = value;
|
||||
container.append(dt, dd);
|
||||
}
|
||||
}
|
||||
function normalizeNode(node) {
|
||||
return {...node, key: node.node_id, lat: node.last_lat / 1e7 || null, long: node.last_long / 1e7 || null};
|
||||
}
|
||||
function renderTelemetry(packet) {
|
||||
const container = byId('inspector-telemetry');
|
||||
if (packet && packetTime(packet) < telemetryTime) return;
|
||||
if (packet) telemetryTime = packetTime(packet);
|
||||
if (!packet && telemetryTime >= 0) return;
|
||||
if (!packet) { note(container, 'No telemetry packets found.'); return; }
|
||||
const payload = String(packet.payload || '');
|
||||
const value = field => {
|
||||
const match = payload.match(new RegExp(`(?:^|[\\s{])${field}:\\s*(-?\\d+(?:\\.\\d+)?)`));
|
||||
return match ? Number(match[1]) : null;
|
||||
};
|
||||
const battery = value('battery_level');
|
||||
const voltage = value('voltage');
|
||||
const channelUtil = value('channel_utilization');
|
||||
const airUtil = value('air_util_tx');
|
||||
const values = [
|
||||
['Battery', battery === null ? null : battery > 100 ? 'Powered' : `${battery}%`],
|
||||
['Voltage', voltage === null ? null : `${voltage.toFixed(2)} V`],
|
||||
['Channel utilization', channelUtil === null ? null : `${channelUtil.toFixed(1)}%`],
|
||||
['Air utilization TX', airUtil === null ? null : `${airUtil.toFixed(1)}%`]
|
||||
].filter(([, value]) => value !== null);
|
||||
if (!values.length) { note(container, 'No device metrics in the latest telemetry packet.'); return; }
|
||||
container.replaceChildren();
|
||||
const grid = document.createElement('div'); grid.className = 'mesh-inspector-telemetry';
|
||||
for (const [label, value] of values) {
|
||||
const cell = document.createElement('div');
|
||||
const strong = document.createElement('strong'); strong.textContent = value;
|
||||
const span = document.createElement('span'); span.textContent = label;
|
||||
cell.append(strong, span); grid.append(cell);
|
||||
}
|
||||
const stamp = document.createElement('p'); stamp.className = 'mesh-inspector-note';
|
||||
stamp.textContent = `Reported ${dateText(packet.import_time_us)}`;
|
||||
container.append(grid, stamp);
|
||||
}
|
||||
function renderRecent() {
|
||||
const container = byId('inspector-recent');
|
||||
if (!recentPackets.length) { note(container, 'No recent packets found.'); return; }
|
||||
container.replaceChildren();
|
||||
for (const packet of recentPackets) {
|
||||
const button = document.createElement('a');
|
||||
button.href = `/packet/${encodeURIComponent(packetId(packet))}`;
|
||||
button.className = 'mesh-inspector-packet';
|
||||
const heading = document.createElement('strong');
|
||||
heading.textContent = `${portName(packet)} · ${timeText(packet.import_time_us)}`;
|
||||
const preview = document.createElement('small');
|
||||
preview.textContent = packet.payload || `From ${nodeName(packet.from_node_id, packet.long_name)}`;
|
||||
button.append(heading, preview);
|
||||
container.append(button);
|
||||
}
|
||||
}
|
||||
window.openMapNodeInspector = async (node, force = false) => {
|
||||
const id = String(nodeKey(node));
|
||||
if (!force && inspectedNodeId === id && !byId('mesh-node-inspector').hidden) return;
|
||||
nodeRequest?.abort();
|
||||
const request = new AbortController(); nodeRequest = request;
|
||||
inspectedNodeId = id; recentPackets = []; telemetryTime = -1;
|
||||
byId('mesh-node-browser').hidden = true;
|
||||
byId('mesh-node-inspector').hidden = false;
|
||||
byId('inspector-node-link').href = `/node/${encodeURIComponent(id)}`;
|
||||
byId('inspector-reliability-link').href = `/reliability?node_id=${encodeURIComponent(id)}`;
|
||||
facts(node);
|
||||
note(byId('inspector-telemetry'), 'Loading telemetry…');
|
||||
note(byId('inspector-recent'), 'Loading recent packets…');
|
||||
if (matchMedia('(max-width: 700px)').matches) byId('mesh-node-inspector').scrollIntoView({block:'nearest'});
|
||||
// A sender/gateway may be outside the map's recent-node snapshot.
|
||||
if (force || !findNode(id)) {
|
||||
fetchJson(`/api/nodes?node_id=${encodeURIComponent(id)}`, request.signal).then(data => {
|
||||
if (request.signal.aborted) return;
|
||||
const raw = data.nodes?.[0];
|
||||
if (raw) {
|
||||
const complete = normalizeNode(raw); nodeMap.set(Number(id), complete); facts(complete);
|
||||
} else byId('inspector-node-meta').textContent = `Node ${id} · no node information available`;
|
||||
}).catch(error => {
|
||||
if (error.name !== 'AbortError') byId('inspector-node-meta').textContent = `Node ${id} · details unavailable`;
|
||||
});
|
||||
}
|
||||
await Promise.all([
|
||||
fetchJson(`/api/packets?from_node_id=${encodeURIComponent(id)}&portnum=67&limit=1`, request.signal).then(data => {
|
||||
if (request.signal.aborted) return;
|
||||
if (!Array.isArray(data.packets)) throw new Error('Invalid telemetry response');
|
||||
renderTelemetry(data.packets[0]);
|
||||
}).catch(error => {
|
||||
if (error.name !== 'AbortError') note(byId('inspector-telemetry'), 'Telemetry unavailable. Use Refresh data to retry.');
|
||||
}),
|
||||
fetchJson(`/api/packets?node_id=${encodeURIComponent(id)}&limit=8`, request.signal).then(data => {
|
||||
if (request.signal.aborted) return;
|
||||
if (!Array.isArray(data.packets)) throw new Error('Invalid packet response');
|
||||
const merged = new Map([...data.packets, ...recentPackets].map(p => [String(packetId(p)), p]));
|
||||
recentPackets = [...merged.values()].sort((a,b) => packetTime(b)-packetTime(a)).slice(0,8);
|
||||
renderRecent();
|
||||
}).catch(error => {
|
||||
if (error.name !== 'AbortError') note(byId('inspector-recent'), 'Recent packets unavailable. Use Refresh data to retry.');
|
||||
})
|
||||
]);
|
||||
};
|
||||
byId('inspector-refresh').addEventListener('click', () => {
|
||||
if (inspectedNodeId) openMapNodeInspector(findNode(inspectedNodeId) || {key:Number(inspectedNodeId)}, true);
|
||||
});
|
||||
byId('inspector-back').addEventListener('click', () => {
|
||||
nodeRequest?.abort(); inspectedNodeId = null;
|
||||
byId('mesh-node-inspector').hidden = true;
|
||||
byId('mesh-node-browser').hidden = false;
|
||||
byId('node-search').focus({preventScroll:true});
|
||||
});
|
||||
|
||||
document.addEventListener('mesh:packets', event => {
|
||||
for (const packet of event.detail) {
|
||||
if (inspectedNodeId && [packet.from_node_id,packet.to_node_id].some(id => String(id) === inspectedNodeId)) {
|
||||
const merged = new Map([...recentPackets,packet].map(p => [String(packetId(p)),p]));
|
||||
recentPackets = [...merged.values()].sort((a,b) => packetTime(b)-packetTime(a)).slice(0,8);
|
||||
renderRecent();
|
||||
if (String(packet.from_node_id) === inspectedNodeId && Number(packet.portnum) === 67) renderTelemetry(packet);
|
||||
}
|
||||
}
|
||||
});
|
||||
})();
|
||||
@@ -1,138 +0,0 @@
|
||||
/* Home-only traffic table; shares packet polling with the map. */
|
||||
(() => {
|
||||
const byId = id => document.getElementById(id);
|
||||
const packetHistory = new Map();
|
||||
const expandedPackets = new Set();
|
||||
const displayedPackets = new Set();
|
||||
const packetArrivals = new Map();
|
||||
let trafficLoaded = false;
|
||||
let paused = false;
|
||||
let trafficState = 'loading';
|
||||
const findNode = id => nodeMap.get(Number(id)) || nodeMap.get(id);
|
||||
const nodeName = (id, fallback) => {
|
||||
const node = findNode(id);
|
||||
return node?.long_name || node?.short_name || fallback || `Node ${id}`;
|
||||
};
|
||||
const packetTime = packet => Number(packet.import_time_us) || 0;
|
||||
const packetId = packet => packet.storage_id ?? packet.id;
|
||||
const portName = packet => window.PORT_LABEL_MAP[packet.portnum] || `Port ${packet.portnum ?? '?'}`;
|
||||
const dateText = us => us ? new Date(Number(us) / 1000).toLocaleString() : 'Unknown time';
|
||||
|
||||
|
||||
function renderTraffic() {
|
||||
const list = byId('map-traffic-list');
|
||||
const body = byId('map-traffic-body');
|
||||
const scrollTop = list.scrollTop;
|
||||
const focusedRow = document.activeElement?.closest('.mesh-traffic-row');
|
||||
const focusedId = focusedRow?.dataset.packetId;
|
||||
const focusedControl = document.activeElement?.dataset.trafficFocus;
|
||||
body.replaceChildren();
|
||||
const channel = byId('map-traffic-channel').value;
|
||||
const packets = [...packetHistory.values()].sort((a,b) => packetTime(b)-packetTime(a))
|
||||
.slice(0,30).filter(packet => !channel || packet.channel === channel);
|
||||
if (!packets.length) {
|
||||
const row = document.createElement('tr'); const cell = document.createElement('td');
|
||||
cell.colSpan = 6; cell.className = 'mesh-empty';
|
||||
cell.textContent = trafficState === 'error' ? 'Unable to load traffic. Use Refresh to try again.' :
|
||||
channel ? 'No packets for this channel in the latest sample.' : 'No packets received yet.';
|
||||
row.append(cell); body.append(row);
|
||||
}
|
||||
function nodeCell(id, label, isDestination = false) {
|
||||
const cell = document.createElement('td');
|
||||
if (Number(id) === 4294967295 || (isDestination && Number(id) === 1)) {
|
||||
const muted = document.createElement('span'); muted.className = 'mesh-inspector-note';
|
||||
muted.textContent = Number(id) === 4294967295 ? 'All' : 'Direct to MQTT'; cell.append(muted);
|
||||
} else {
|
||||
const link = document.createElement('a'); link.href = `/node/${encodeURIComponent(id)}`;
|
||||
link.textContent = nodeName(id,label); cell.append(link);
|
||||
}
|
||||
return cell;
|
||||
}
|
||||
for (const packet of packets) {
|
||||
const id = String(packetId(packet));
|
||||
const row = document.createElement('tr'); row.className = 'mesh-traffic-row'; row.dataset.packetId = id;
|
||||
const time = document.createElement('td'); time.className = 'mesh-traffic-time';
|
||||
time.textContent = packet.import_time_us ? new Date(Number(packet.import_time_us)/1000).toLocaleTimeString([], {hour:'2-digit',minute:'2-digit',second:'2-digit',hour12:false}) : '—';
|
||||
time.title = dateText(packet.import_time_us);
|
||||
const packetCell = document.createElement('td');
|
||||
const toggle = document.createElement('button'); toggle.type = 'button'; toggle.className = 'mesh-traffic-toggle';
|
||||
toggle.dataset.trafficFocus = 'toggle';
|
||||
toggle.setAttribute('aria-label', `Toggle payload for packet ${id}`);
|
||||
toggle.setAttribute('aria-expanded',String(expandedPackets.has(id)));
|
||||
toggle.textContent = expandedPackets.has(id) ? '▼' : '▶';
|
||||
const details = document.createElement('a'); details.href = `/packet/${encodeURIComponent(id)}`;
|
||||
details.dataset.trafficFocus = 'details'; details.title = 'View packet details';
|
||||
details.textContent = packet.packet_id == null ? 'Details' : String(packet.packet_id);
|
||||
packetCell.append(toggle,details);
|
||||
const channelCell = document.createElement('td'); channelCell.textContent = packet.channel || '—';
|
||||
const port = document.createElement('td');
|
||||
const tag = document.createElement('span'); tag.className = 'mesh-traffic-type'; tag.textContent = portName(packet);
|
||||
tag.style.backgroundColor = window.PORT_COLOR_MAP[packet.portnum] || '#6c757d';
|
||||
tag.title = packet.payload || '';
|
||||
const number = document.createElement('span'); number.className = 'mesh-traffic-port-number'; number.textContent = `(${packet.portnum ?? '?'})`;
|
||||
port.append(tag,number);
|
||||
row.append(time,packetCell,nodeCell(packet.from_node_id,packet.long_name),nodeCell(packet.to_node_id,packet.to_long_name,true),channelCell,port);
|
||||
const payloadRow = document.createElement('tr'); payloadRow.className = 'mesh-traffic-payload';
|
||||
payloadRow.hidden = !expandedPackets.has(id);
|
||||
const payloadCell = document.createElement('td'); payloadCell.colSpan = 6;
|
||||
const payload = document.createElement('pre'); payload.textContent = packet.payload || '(No decoded payload)';
|
||||
payloadCell.append(payload); payloadRow.append(payloadCell);
|
||||
toggle.addEventListener('click', () => {
|
||||
if (expandedPackets.has(id)) expandedPackets.delete(id); else expandedPackets.add(id);
|
||||
payloadRow.hidden = !expandedPackets.has(id);
|
||||
toggle.setAttribute('aria-expanded',String(!payloadRow.hidden)); toggle.textContent = payloadRow.hidden ? '▶' : '▼';
|
||||
});
|
||||
body.append(row,payloadRow);
|
||||
if (!displayedPackets.has(id)) {
|
||||
displayedPackets.add(id);
|
||||
packetArrivals.set(id,Date.now());
|
||||
}
|
||||
if (packetArrivals.has(id)) markNewPacketArrival(row,packetArrivals.get(id));
|
||||
}
|
||||
list.scrollTop = scrollTop;
|
||||
if (focusedId && focusedControl) {
|
||||
const row = [...body.children].find(row => row.dataset.packetId === focusedId);
|
||||
[...(row?.querySelectorAll('[data-traffic-focus]') || [])]
|
||||
.find(el => el.dataset.trafficFocus === focusedControl)?.focus({preventScroll:true});
|
||||
}
|
||||
}
|
||||
function renderTrafficStatus() {
|
||||
const el = byId('map-traffic-status');
|
||||
el.dataset.state = trafficState;
|
||||
el.textContent = paused ? 'Feed paused' : trafficState === 'error' ? 'Traffic unavailable' :
|
||||
trafficState === 'loading' ? 'Loading packets…' : mapInterval > 0 ? `Live · every ${mapInterval}s` : 'Snapshot · auto-refresh off';
|
||||
}
|
||||
document.addEventListener('mesh:traffic-status', event => {
|
||||
trafficState = event.detail; renderTrafficStatus();
|
||||
if (!paused && !packetHistory.size) renderTraffic();
|
||||
});
|
||||
document.addEventListener('mesh:packets', event => {
|
||||
let added = false;
|
||||
for (const packet of event.detail) {
|
||||
if (!packetHistory.has(String(packetId(packet)))) added = true;
|
||||
packetHistory.set(String(packetId(packet)),packet);
|
||||
if (!trafficLoaded) displayedPackets.add(String(packetId(packet)));
|
||||
if (packet.channel && ![...byId('map-traffic-channel').options].some(o => o.value === packet.channel)) {
|
||||
byId('map-traffic-channel').add(new Option(packet.channel,packet.channel));
|
||||
}
|
||||
}
|
||||
trafficLoaded = true;
|
||||
if (packetHistory.size > 30) {
|
||||
const sorted = [...packetHistory.values()].sort((a,b) => packetTime(b)-packetTime(a));
|
||||
for (const packet of sorted.slice(30)) {
|
||||
packetHistory.delete(String(packetId(packet))); expandedPackets.delete(String(packetId(packet)));
|
||||
displayedPackets.delete(String(packetId(packet))); packetArrivals.delete(String(packetId(packet)));
|
||||
}
|
||||
}
|
||||
if (!paused && added) renderTraffic();
|
||||
});
|
||||
byId('map-traffic-channel').addEventListener('change', () => renderTraffic());
|
||||
byId('map-traffic-pause').addEventListener('click', () => {
|
||||
paused = !paused;
|
||||
byId('map-traffic-pause').textContent = paused ? 'Resume feed' : 'Pause feed';
|
||||
byId('map-traffic-pause').setAttribute('aria-pressed',String(paused));
|
||||
if (!paused) renderTraffic();
|
||||
renderTrafficStatus();
|
||||
});
|
||||
byId('map-traffic-refresh').addEventListener('click', () => fetchLatestPacket());
|
||||
})();
|
||||
@@ -1,13 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 64 64" role="img" aria-labelledby="title">
|
||||
<title id="title">Meshview: a mesh network through a magnifying glass</title>
|
||||
<rect width="64" height="64" rx="15" fill="#eaf5ee"/>
|
||||
<path d="M43 43 55 55" fill="none" stroke="#187346" stroke-width="7" stroke-linecap="round"/>
|
||||
<circle cx="28" cy="28" r="19" fill="none" stroke="#187346" stroke-width="4"/>
|
||||
<path d="m17 29 12-11 9 14-15 6-6-9 21 3" fill="none" stroke="#369361" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g fill="#187346" stroke="#eaf5ee" stroke-width="1.5">
|
||||
<circle cx="17" cy="29" r="3.8"/>
|
||||
<circle cx="29" cy="18" r="3.8"/>
|
||||
<circle cx="38" cy="32" r="3.8"/>
|
||||
<circle cx="23" cy="38" r="3.8"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 796 B |
@@ -1,17 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="396" height="88" viewBox="0 0 396 88" role="img" aria-labelledby="title desc">
|
||||
<title id="title">Meshview</title>
|
||||
<desc id="desc">Connected mesh nodes inside a green magnifying glass, alongside the Meshview wordmark.</desc>
|
||||
<g transform="translate(4 8) scale(1.125)">
|
||||
<rect width="64" height="64" rx="15" fill="#eaf5ee"/>
|
||||
<path d="M43 43 55 55" fill="none" stroke="#187346" stroke-width="7" stroke-linecap="round"/>
|
||||
<circle cx="28" cy="28" r="19" fill="none" stroke="#187346" stroke-width="4"/>
|
||||
<path d="m17 29 12-11 9 14-15 6-6-9 21 3" fill="none" stroke="#369361" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||
<g fill="#187346" stroke="#eaf5ee" stroke-width="1.5">
|
||||
<circle cx="17" cy="29" r="3.8"/>
|
||||
<circle cx="29" cy="18" r="3.8"/>
|
||||
<circle cx="38" cy="32" r="3.8"/>
|
||||
<circle cx="23" cy="38" r="3.8"/>
|
||||
</g>
|
||||
</g>
|
||||
<text x="94" y="61" fill="#143b29" font-family="Inter, system-ui, -apple-system, 'Segoe UI', sans-serif" font-size="51" font-weight="700" letter-spacing="-1.8">Meshview</text>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 1.1 KiB |
@@ -1,12 +0,0 @@
|
||||
/* A short, shared arrival cue for the two live packet tables. */
|
||||
window.markNewPacketArrival = function (row, startedAt = Date.now()) {
|
||||
const elapsed = Math.max(0, Date.now() - startedAt);
|
||||
const remaining = 1000 - elapsed;
|
||||
if (remaining <= 0) return;
|
||||
row.classList.add('packet-arrival-glow');
|
||||
row.style.setProperty('--packet-glow-delay', `${-elapsed}ms`);
|
||||
setTimeout(() => {
|
||||
row.classList.remove('packet-arrival-glow');
|
||||
row.style.removeProperty('--packet-glow-delay');
|
||||
}, remaining);
|
||||
};
|
||||
@@ -1,95 +0,0 @@
|
||||
/* Apply before paint; one preference shared by every Meshview page. */
|
||||
(() => {
|
||||
const root = document.documentElement;
|
||||
const key = 'meshview-theme';
|
||||
const system = matchMedia('(prefers-color-scheme: dark)');
|
||||
let preference = null;
|
||||
try { preference = localStorage.getItem(key); } catch {}
|
||||
if (!['light','dark'].includes(preference)) preference = null;
|
||||
root.dataset.bsTheme = preference || (system.matches ? 'dark' : 'light');
|
||||
|
||||
const colors = () => {
|
||||
const style = getComputedStyle(root);
|
||||
return {
|
||||
surface:style.getPropertyValue('--mesh-surface').trim(),
|
||||
text:style.getPropertyValue('--mesh-text').trim(),
|
||||
muted:style.getPropertyValue('--mesh-muted').trim(),
|
||||
border:style.getPropertyValue('--mesh-border').trim()
|
||||
};
|
||||
};
|
||||
// Neutral chart colors follow the theme; packet/route/series colors stay intact.
|
||||
function chartOption(option) {
|
||||
const palette = colors();
|
||||
const text = new Set(['#333','#334155','#243247','#26364a','#e7eef7','#e2ece5']);
|
||||
const muted = new Set(['#ccc','#64748b','#888','#9faea6','#8190a5']);
|
||||
const border = new Set(['#aaa','#c3cfdf','#34483c','#dce7df']);
|
||||
function visit(value, key) {
|
||||
if (Array.isArray(value)) return value.map(item => visit(item,key));
|
||||
if (value && Object.getPrototypeOf(value) === Object.prototype) {
|
||||
return Object.fromEntries(Object.entries(value).map(([k,v]) => [k,visit(v,k)]));
|
||||
}
|
||||
if (typeof value !== 'string') return value;
|
||||
const hex = value.toLowerCase();
|
||||
if (key === 'backgroundColor' && ['#fff','#ffffff','#18231e'].includes(hex)) return palette.surface;
|
||||
if (['borderColor','textBorderColor'].includes(key) && ['#fff','#ffffff','#000','#18231e'].includes(hex)) return palette.surface;
|
||||
if (key === 'color' && text.has(hex)) return palette.text;
|
||||
if (key === 'color' && muted.has(hex)) return palette.muted;
|
||||
if (key === 'color' && border.has(hex)) return palette.border;
|
||||
return value;
|
||||
}
|
||||
const themed = visit(option,'');
|
||||
themed.textStyle = {...themed.textStyle,color:palette.text};
|
||||
const tooltip = value => ({...value,backgroundColor:palette.surface,borderColor:palette.border,textStyle:{...value?.textStyle,color:palette.text}});
|
||||
if (Array.isArray(themed.tooltip)) themed.tooltip = themed.tooltip.map(tooltip);
|
||||
else themed.tooltip = tooltip(themed.tooltip);
|
||||
return themed;
|
||||
}
|
||||
const wrapped = new WeakSet();
|
||||
window.initMeshChart = (...args) => {
|
||||
const chart = window.echarts.init(...args);
|
||||
if (!wrapped.has(chart)) {
|
||||
const setOption = chart.setOption.bind(chart);
|
||||
chart.setOption = (option,...rest) => setOption(chartOption(option),...rest);
|
||||
wrapped.add(chart);
|
||||
}
|
||||
return chart;
|
||||
};
|
||||
function updateButton() {
|
||||
document.querySelectorAll('[data-theme-toggle]').forEach(button => {
|
||||
const dark = root.dataset.bsTheme === 'dark';
|
||||
button.textContent = dark ? '☀' : '☾';
|
||||
button.setAttribute('aria-label',dark ? 'Switch to day mode' : 'Switch to night mode');
|
||||
button.setAttribute('aria-pressed',String(dark));
|
||||
button.title = dark ? 'Day mode' : 'Night mode';
|
||||
});
|
||||
}
|
||||
function apply(theme) {
|
||||
root.dataset.bsTheme = theme;
|
||||
updateButton();
|
||||
if (window.echarts) {
|
||||
document.querySelectorAll('[_echarts_instance_]').forEach(el => {
|
||||
const chart = window.echarts.getInstanceByDom(el);
|
||||
if (chart) chart.setOption(chartOption(chart.getOption()));
|
||||
});
|
||||
}
|
||||
document.dispatchEvent(new CustomEvent('meshview:themechange',{detail:theme}));
|
||||
}
|
||||
document.addEventListener('DOMContentLoaded',() => {
|
||||
updateButton();
|
||||
document.querySelectorAll('[data-theme-toggle]').forEach(button => {
|
||||
button.addEventListener('click',() => {
|
||||
preference = root.dataset.bsTheme === 'dark' ? 'light' : 'dark';
|
||||
try { localStorage.setItem(key,preference); } catch {}
|
||||
apply(preference);
|
||||
});
|
||||
});
|
||||
});
|
||||
system.addEventListener('change',event => {
|
||||
if (!preference) apply(event.matches ? 'dark' : 'light');
|
||||
});
|
||||
window.addEventListener('storage',event => {
|
||||
if (event.key !== key && event.key !== null) return;
|
||||
preference = ['light','dark'].includes(event.newValue) ? event.newValue : null;
|
||||
apply(preference || (system.matches ? 'dark' : 'light'));
|
||||
});
|
||||
})();
|
||||
+20
-144
@@ -1,23 +1,16 @@
|
||||
<!doctype html>
|
||||
<html lang="en" data-bs-theme="{% block theme %}dark{% endblock %}">
|
||||
<html lang="en" data-bs-theme="dark">
|
||||
<head>
|
||||
<title>Meshview</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<link rel="icon" type="image/x-icon" sizes="16x16 32x32 48x48 64x64 256x256" href="/static/favicon.ico">
|
||||
<link rel="icon" type="image/svg+xml" sizes="any" href="/static/meshview-icon.svg">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/static/apple-touch-icon.png">
|
||||
|
||||
<script src="/static/theme.js"></script>
|
||||
|
||||
<!-- Scripts -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/>
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script>
|
||||
<script src="/static/html-escape.js"></script>
|
||||
<script src="/static/packet-arrival.js"></script>
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
|
||||
@@ -50,132 +43,22 @@
|
||||
</style>
|
||||
|
||||
{% block css %}{% endblock %}
|
||||
<style>
|
||||
/* Shared dashboard chrome and map explorer. */
|
||||
:root,[data-bs-theme="light"],[data-bs-theme="dark"] {
|
||||
--bs-primary:var(--mesh-brand);
|
||||
--bs-primary-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-color:var(--mesh-primary);
|
||||
--bs-link-color-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-hover-color:var(--mesh-primary-dark);
|
||||
--bs-link-hover-color-rgb:15,81,50;
|
||||
--bs-focus-ring-color:rgba(var(--mesh-primary-rgb),.25);
|
||||
}
|
||||
[data-bs-theme="dark"] { --bs-link-color:#75c99c; --bs-link-color-rgb:117,201,156; --bs-link-hover-color:#a3dfbc; --bs-link-hover-color-rgb:163,223,188; }
|
||||
.btn-primary {
|
||||
--bs-btn-bg:var(--mesh-brand); --bs-btn-border-color:var(--mesh-brand);
|
||||
--bs-btn-hover-bg:var(--mesh-brand-deep); --bs-btn-hover-border-color:var(--mesh-brand-deep);
|
||||
--bs-btn-active-bg:var(--mesh-brand-deep); --bs-btn-active-border-color:var(--mesh-brand-deep);
|
||||
--bs-btn-disabled-bg:var(--mesh-brand); --bs-btn-disabled-border-color:var(--mesh-brand);
|
||||
--bs-btn-focus-shadow-rgb:var(--mesh-primary-rgb);
|
||||
}
|
||||
.btn-outline-primary {
|
||||
--bs-btn-color:var(--mesh-primary); --bs-btn-border-color:var(--mesh-brand);
|
||||
--bs-btn-hover-bg:var(--mesh-brand); --bs-btn-hover-border-color:var(--mesh-brand);
|
||||
--bs-btn-active-bg:var(--mesh-brand-deep); --bs-btn-active-border-color:var(--mesh-brand-deep);
|
||||
--bs-btn-focus-shadow-rgb:var(--mesh-primary-rgb);
|
||||
}
|
||||
.form-control:focus,.form-select:focus { border-color:#91bda1; box-shadow:0 0 0 .25rem rgba(var(--mesh-primary-rgb),.2); }
|
||||
input[type="checkbox"],input[type="radio"] { accent-color:var(--mesh-primary); }
|
||||
.leaflet-popup-content a,.leaflet-control-attribution a { color:var(--mesh-primary); }
|
||||
.form-check-input:checked { background-color:var(--mesh-primary); border-color:var(--mesh-primary); }
|
||||
.form-check-input:focus { border-color:#91bda1; box-shadow:0 0 0 .25rem rgba(var(--mesh-primary-rgb),.2); }
|
||||
.page-link { --bs-pagination-color:var(--mesh-primary); --bs-pagination-hover-color:var(--mesh-primary-dark); --bs-pagination-active-bg:var(--mesh-primary); --bs-pagination-active-border-color:var(--mesh-primary); }
|
||||
[data-bs-theme="light"] body { background:var(--mesh-page); color:var(--mesh-text); font-family:Inter,system-ui,-apple-system,"Segoe UI",sans-serif; }
|
||||
/* Tint whole cells: an edge-only shadow is too subtle on wide packet tables. */
|
||||
.packet-arrival-glow > td {
|
||||
animation:packet-arrival-beat 1s ease-in-out 1;
|
||||
animation-delay:var(--packet-glow-delay,0ms);
|
||||
box-shadow:inset 0 0 14px rgba(24,115,70,.12);
|
||||
}
|
||||
.packet-arrival-glow > td:first-child {
|
||||
box-shadow:inset 4px 0 0 var(--mesh-primary),inset 0 0 14px rgba(24,115,70,.12);
|
||||
}
|
||||
@keyframes packet-arrival-beat {
|
||||
0%,100% { background-color:transparent; }
|
||||
45% { background-color:var(--mesh-pulse-peak); }
|
||||
75% { background-color:var(--mesh-pulse-mid); }
|
||||
}
|
||||
@media(prefers-reduced-motion:reduce) {
|
||||
.packet-arrival-glow > td { animation:none; background:var(--mesh-soft); }
|
||||
}
|
||||
.mesh-header { background:var(--mesh-brand); color:white; box-shadow:0 2px 8px #174b2d18; }
|
||||
.mesh-header-inner { max-width:1600px; margin:auto; padding:0 28px; min-height:56px; display:flex; align-items:center; gap:32px; }
|
||||
.mesh-brand { display:flex; align-items:center; gap:10px; font-size:19px; font-weight:700; color:white; text-decoration:none; flex-shrink:0; }
|
||||
.mesh-brand:hover { color:white; }
|
||||
.mesh-brand-icon { width:32px; height:32px; display:block; flex-shrink:0; }
|
||||
#site-menu { display:flex; align-items:center; flex-wrap:wrap; gap:4px; }
|
||||
#site-menu a { color:#e6f4ea; text-decoration:none; padding:10px 12px; border-radius:6px; font-size:14px; text-transform:capitalize; }
|
||||
#site-menu a:hover, #site-menu a.active { color:white; background:#ffffff26; }
|
||||
.mesh-menu-toggle { display:none; color:white; background:none; border:1px solid #ffffff70; border-radius:5px; font-size:22px; }
|
||||
.mesh-content { max-width:1600px; margin:0 auto; padding:28px; }
|
||||
.mesh-announcement { text-align:center; padding:10px 20px; background:var(--mesh-soft); color:var(--mesh-text); font-size:14px; }
|
||||
.mesh-announcement:empty { display:none; }
|
||||
.mesh-footer { display:flex; justify-content:space-between; gap:16px; padding:20px 28px; border-top:1px solid var(--mesh-border); color:var(--mesh-muted); font-size:12px; }
|
||||
.mesh-page-heading { display:flex; justify-content:space-between; align-items:center; gap:16px; margin-bottom:24px; }
|
||||
.mesh-eyebrow { font-size:10px; letter-spacing:1.6px; font-weight:700; color:var(--mesh-primary); }
|
||||
.mesh-page-heading h1 { font-size:28px; font-weight:650; margin:5px 0 7px; }
|
||||
.mesh-page-heading p { color:var(--mesh-muted); font-size:14px; margin:0; }
|
||||
.mesh-secondary-button,.mesh-fit-button { border:1px solid var(--mesh-border); background:var(--mesh-surface); color:var(--mesh-text); padding:9px 14px; border-radius:6px; text-decoration:none; font-size:13px; }
|
||||
.mesh-secondary-button:hover,.mesh-fit-button:hover { background:var(--mesh-soft); }
|
||||
.mesh-metrics { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:18px; margin-bottom:24px; }
|
||||
.mesh-metric { padding:20px 24px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; box-shadow:0 2px 4px var(--mesh-text)04; display:flex; flex-direction:column; gap:5px; }
|
||||
.mesh-metric>span { font-size:13px; font-weight:500; color:var(--mesh-muted); }
|
||||
.mesh-metric strong { font-size:30px; font-weight:650; color:var(--mesh-primary); font-variant-numeric:tabular-nums; }
|
||||
.mesh-metric:nth-child(2) strong { color:#198754; }
|
||||
.mesh-metric:nth-child(3) strong { color:#397955; }
|
||||
.mesh-metric small { font-size:11px; color:var(--mesh-muted); }
|
||||
.mesh-explorer { display:grid; grid-template-columns:290px minmax(0,1fr); gap:20px; }
|
||||
.mesh-node-panel,.mesh-map-panel { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; overflow:hidden; min-width:0; }
|
||||
.mesh-panel-title { display:flex; justify-content:space-between; align-items:center; padding:16px 18px; border-bottom:1px solid var(--mesh-border); gap:8px; min-height:64px; }
|
||||
.mesh-panel-title h2 { font-size:15px; font-weight:650; margin:0; }
|
||||
.mesh-count { color:var(--mesh-primary); background:var(--mesh-soft); padding:3px 8px; border-radius:5px; font-size:12px; }
|
||||
.mesh-search-label { margin:16px 16px 5px; font-size:11px; color:var(--mesh-muted); }
|
||||
.mesh-search { display:block; width:calc(100% - 32px); margin:0 16px 12px; border:1px solid var(--mesh-border); border-radius:6px; padding:10px; font-size:13px; }
|
||||
.mesh-search:focus-visible { outline:2px solid var(--mesh-primary); outline-offset:2px; }
|
||||
.mesh-node-list { max-height:535px; overflow:auto; }
|
||||
.mesh-node-row { display:flex; align-items:center; gap:10px; width:100%; padding:14px 16px; border:0; border-top:1px solid var(--mesh-stripe); background:var(--mesh-surface); text-align:left; color:var(--mesh-text); }
|
||||
.mesh-node-row:hover,.mesh-node-row:focus-visible { background:var(--mesh-soft); }
|
||||
.mesh-node-dot { width:9px; height:9px; border-radius:50%; background:#198754; flex-shrink:0; }
|
||||
.mesh-node-dot.offline { background:#c0c9d5; }
|
||||
.mesh-node-copy { min-width:0; flex:1; }
|
||||
.mesh-node-copy strong { display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-size:13px; font-weight:600; }
|
||||
.mesh-node-copy small { display:block; color:var(--mesh-muted); font-size:11px; margin-top:4px; }
|
||||
.mesh-node-role { font-size:10px; color:var(--mesh-muted); }
|
||||
.mesh-empty { color:var(--mesh-muted); padding:20px 16px; font-size:13px; }
|
||||
.mesh-map-panel #map-wrapper { height:520px; }
|
||||
.mesh-map-panel #filter-container { display:flex; align-items:center; justify-content:flex-start; flex-wrap:wrap; gap:5px; margin:0; padding:12px; font-size:12px; border-top:1px solid var(--mesh-border); }
|
||||
.mesh-map-panel .filter-checkbox { margin:0 2px 0 10px; accent-color:var(--mesh-primary); }
|
||||
.mesh-map-panel #share-button,.mesh-map-panel #reset-filters-button { background:var(--mesh-soft); color:var(--mesh-primary); margin:5px; padding:8px 12px; font-size:12px; }
|
||||
.mesh-map-panel #share-button.is-copied { background:var(--mesh-brand-deep); color:white; }
|
||||
.mesh-map-panel #reset-filters-button { color:var(--mesh-muted); background:var(--mesh-stripe); }
|
||||
.mesh-map-panel #map-legend { bottom:80px!important; left:12px; right:auto!important; box-shadow:0 2px 8px #0001; font-size:11px; }
|
||||
.mesh-map-panel #unmapped-packets { bottom:25px; right:10px; width:190px; }
|
||||
.mesh-map-panel .leaflet-control-layers { font-size:11px; border:1px solid var(--mesh-border); box-shadow:0 2px 8px #0001; }
|
||||
@media(min-width:1000px) { .mesh-header-inner { gap:20px; } #site-menu a { padding:9px; } }
|
||||
@media(max-width:1000px) { .mesh-header-inner { flex-wrap:wrap; gap:0; padding:8px 20px; justify-content:space-between; } .mesh-menu-toggle { display:block; } #site-menu { display:none; width:100%; padding-top:14px; } #site-menu.is-open { display:flex; } .mesh-explorer { grid-template-columns:240px minmax(0,1fr); } }
|
||||
@media(max-width:700px) { .mesh-content { padding:20px 14px; } .mesh-page-heading { align-items:flex-start; } .mesh-page-heading h1 { font-size:24px; } .mesh-secondary-button { white-space:nowrap; font-size:11px; padding:8px; } .mesh-metrics { grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; } .mesh-metric { padding:14px; } .mesh-metric strong { font-size:26px; } .mesh-explorer { display:flex; flex-direction:column-reverse; gap:16px; } .mesh-map-panel #map-wrapper { height:440px; } .mesh-node-list { max-height:300px; } .mesh-map-panel #unmapped-packets { width:155px; font-size:10px; } .mesh-footer { flex-direction:column; } }
|
||||
</style>
|
||||
{% include "theme-styles.html" %}
|
||||
</head>
|
||||
|
||||
<body class="{% block body_class %}{% endblock %}">
|
||||
<header class="mesh-header">
|
||||
<div class="mesh-header-inner">
|
||||
<a class="mesh-brand" href="/"><img class="mesh-brand-icon" src="/static/meshview-icon.svg" width="32" height="32" alt=""> <span id="site-header">Meshview</span></a>
|
||||
<button class="mesh-menu-toggle" type="button" aria-label="Toggle navigation" aria-expanded="false" aria-controls="site-menu">☰</button>
|
||||
<nav id="site-menu" aria-label="Main navigation"></nav>
|
||||
<button class="mesh-theme-toggle" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false" title="Night mode">☾</button>
|
||||
</div>
|
||||
</header>
|
||||
<div id="site-message" class="mesh-announcement"></div>
|
||||
<main class="mesh-content">
|
||||
<body>
|
||||
<br>
|
||||
<div style="text-align:center" id="site-header"></div>
|
||||
<div style="text-align:center" id="site-message"></div>
|
||||
<div style="text-align:center" id="site-menu"></div>
|
||||
|
||||
<br>
|
||||
|
||||
{% block body %}{% endblock %}
|
||||
</main>
|
||||
<footer class="mesh-footer">
|
||||
<span id="footer" data-translate="footer"></span>
|
||||
<span id="site-version">Meshview</span>
|
||||
</footer>
|
||||
|
||||
<br>
|
||||
<div style="text-align:center" id="footer" data-translate="footer"></div>
|
||||
<div style="text-align:center"><small id="site-version">ver. unknown</small></div>
|
||||
<br>
|
||||
|
||||
<script>
|
||||
// --- Shared Promises ---
|
||||
@@ -277,29 +160,27 @@ async function initializePage() {
|
||||
document.title = "Meshview - " + (site.title || "");
|
||||
|
||||
// Header & Message
|
||||
document.getElementById("site-header").textContent = site.title || "Meshview";
|
||||
document.getElementById("site-header").innerHTML =
|
||||
`<strong>${site.title || ""} ${site.domain ? "(" + site.domain + ")" : ""}</strong>`;
|
||||
|
||||
document.getElementById("site-message").textContent = site.message || "";
|
||||
|
||||
// Menu
|
||||
const menu = document.getElementById("site-menu");
|
||||
if (menu) {
|
||||
const items = ['<a href="/"' + (["/", "/index", "/index.html"].includes(location.pathname) ? ' class="active" aria-current="page"' : "") + '>Home</a>'];
|
||||
const items = [];
|
||||
const keys = ["nodes", "chat", "everything", "graphs", "net", "map", "stats", "top"];
|
||||
const urls = ["/nodelist", "/chat", "/firehose", "/nodegraph", "/net", "/map", "/stats", "/top"];
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (site[key] === "true" || site[key] === true) {
|
||||
items.push(`<a href="${urls[i]}"${(location.pathname === urls[i] || (key === "map" && location.pathname === "/map.html")) ? ' class="active" aria-current="page"' : ""}>${escapeHtml(dict[key] || (key === "everything" ? "Live Traffic" : key))}</a>`);
|
||||
if (site[key] === "true") {
|
||||
items.push(`<a href="${urls[i]}">${dict[key] || key}</a>`);
|
||||
}
|
||||
}
|
||||
if (site.api !== "false" && site.api !== false) {
|
||||
items.push('<a href="/api.html">API</a>');
|
||||
}
|
||||
items.push('<a href="https://meshview.world" target="_blank" rel="noopener noreferrer">MeshviewWorld</a>');
|
||||
|
||||
menu.innerHTML = items.join("");
|
||||
menu.innerHTML = items.join(" - ");
|
||||
}
|
||||
|
||||
// Version
|
||||
@@ -317,11 +198,6 @@ async function initializePage() {
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector(".mesh-menu-toggle").addEventListener("click", function () {
|
||||
const expanded = this.getAttribute("aria-expanded") !== "true";
|
||||
this.setAttribute("aria-expanded", String(expanded));
|
||||
document.getElementById("site-menu").classList.toggle("is-open", expanded);
|
||||
});
|
||||
document.addEventListener("DOMContentLoaded", initializePage);
|
||||
</script>
|
||||
|
||||
|
||||
+292
-75
@@ -1,87 +1,304 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
<style>
|
||||
body:has(#chat-container) { height:100dvh; display:flex; flex-direction:column; overflow:hidden; }
|
||||
body:has(#chat-container) .mesh-header { flex-shrink:0; }
|
||||
body:has(#chat-container) .mesh-content { display:flex; flex:1; min-height:0; width:100%; max-width:none; padding:0; }
|
||||
body:has(#chat-container) .mesh-footer { display:none; }
|
||||
body:has(#chat-container) .mesh-announcement { flex-shrink:0; }
|
||||
#chat-container { display:flex; flex-direction:column; flex:1; min-width:0; min-height:0; background:var(--mesh-stripe); }
|
||||
.chat-toolbar { display:flex; flex-wrap:wrap; align-items:center; gap:12px; padding:12px 24px; border-bottom:1px solid var(--mesh-border); background:var(--mesh-surface); flex-shrink:0; }
|
||||
.chat-heading { display:flex; align-items:center; gap:8px; margin:0 6px 0 0; font-size:15px; font-weight:650; }
|
||||
.chat-heading span:first-child { color:var(--mesh-primary); }
|
||||
.chat-channel-control { display:flex; align-items:center; gap:6px; color:var(--mesh-muted); }
|
||||
.chat-filter { width:170px; font-size:12px; border-color:var(--mesh-border); }
|
||||
.chat-search { width:210px; font-size:12px; border-color:var(--mesh-border); }
|
||||
.chat-actions { display:flex; align-items:center; gap:8px; margin-left:auto; }
|
||||
.chat-status { border-radius:20px; padding:4px 9px; background:#e8f5ee; color:#187346; font-size:11px; white-space:nowrap; }
|
||||
.chat-status[data-state="error"] { background:#fff0ed; color:#b23d2f; }
|
||||
.chat-status[data-state="paused"],.chat-status[data-state="loading"] { background:#eef2f7; color:var(--mesh-muted); }
|
||||
.chat-control { font-size:12px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:5px; padding:5px 9px; color:var(--mesh-text); }
|
||||
.chat-control:hover { background:var(--mesh-soft); }
|
||||
.chat-messages { flex:1; min-height:0; overflow-y:auto; overflow-anchor:none; padding:12px 0; font-family:ui-monospace,"SFMono-Regular",Consolas,monospace; font-size:13px; line-height:1.6; scrollbar-gutter:stable; }
|
||||
.chat-date-sep { display:flex; align-items:center; gap:14px; margin:12px 24px; color:var(--mesh-muted); font:600 10px system-ui,sans-serif; letter-spacing:.7px; text-transform:uppercase; }
|
||||
.chat-date-sep::before,.chat-date-sep::after { content:""; flex:1; height:1px; background:var(--mesh-border); }
|
||||
.chat-line { display:grid; grid-template-columns:64px 165px minmax(0,1fr) auto; gap:12px; align-items:baseline; padding:5px 24px; --chat-row-bg:var(--mesh-surface); background:var(--chat-row-bg); border-bottom:1px solid var(--mesh-border); }
|
||||
.chat-line:nth-of-type(even) { --chat-row-bg:var(--mesh-chat-stripe); }
|
||||
.chat-line:hover,.chat-line:focus-within { background:var(--mesh-hover); }
|
||||
.chat-time { color:var(--mesh-muted); font-size:11px; text-align:right; white-space:nowrap; }
|
||||
.chat-nick { overflow:hidden; text-overflow:ellipsis; white-space:nowrap; font-weight:600; font-size:12px; text-decoration:none; text-align:right; }
|
||||
.chat-nick:hover { text-decoration:underline; }
|
||||
.chat-message { min-width:0; color:var(--mesh-text); overflow-wrap:anywhere; white-space:pre-wrap; }
|
||||
.chat-meta { display:flex; align-items:center; gap:10px; font:11px system-ui,sans-serif; }
|
||||
.chat-channel { background:#edf1f7; color:var(--mesh-muted); border-radius:4px; padding:2px 6px; max-width:130px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
|
||||
.chat-details { display:inline-flex; align-items:center; padding:4px 8px; border:1px solid #9dceb0; border-radius:5px; background:#e8f5ee; color:#187346; font-weight:600; text-decoration:none; white-space:nowrap; }
|
||||
.chat-details:hover { color:#0f5132; background:#d1e7dd; border-color:#69aa85; }
|
||||
.chat-details:focus-visible { outline:2px solid #198754; outline-offset:2px; }
|
||||
.replying-to { display:block; border-left:2px solid var(--mesh-border); margin:4px 0; padding:2px 9px; color:var(--mesh-muted); font-size:11px; white-space:normal; }
|
||||
.chat-empty { text-align:center; color:var(--mesh-muted); padding:48px 20px; font:13px system-ui,sans-serif; }
|
||||
.chat-bottom { display:flex; align-items:center; justify-content:space-between; gap:12px; padding:8px 24px; border-top:1px solid var(--mesh-border); color:var(--mesh-muted); background:var(--mesh-surface); font-size:11px; flex-shrink:0; }
|
||||
.chat-bottom p { margin:0; }
|
||||
.chat-line.flash { animation:chat-flash 2s ease-out; }
|
||||
@keyframes chat-flash { from { background:var(--mesh-hover); } to { background:var(--chat-row-bg); } }
|
||||
@media(prefers-reduced-motion:reduce) { .chat-line.flash { animation:none; } }
|
||||
@media(max-width:700px) {
|
||||
.chat-toolbar { padding:10px 14px; gap:8px; }
|
||||
.chat-heading { width:100%; }
|
||||
.chat-filter { width:140px; }
|
||||
.chat-search { flex:1; width:120px; min-width:0; }
|
||||
.chat-actions { width:100%; margin-left:0; }
|
||||
#chat-count { margin-right:auto; }
|
||||
.chat-line { grid-template-columns:50px minmax(0,1fr) auto; gap:2px 8px; padding:7px 14px; }
|
||||
.chat-time { grid-column:1; grid-row:1; }
|
||||
.chat-nick { grid-column:2; grid-row:1; text-align:left; }
|
||||
.chat-meta { grid-column:3; grid-row:1; gap:5px; }
|
||||
.chat-channel { max-width:85px; }
|
||||
.chat-message { grid-column:2 / 4; grid-row:2; }
|
||||
.chat-date-sep { margin:12px 14px; }
|
||||
.chat-bottom { padding:8px 14px; }
|
||||
.timestamp {
|
||||
min-width: 10em;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.chat-packet:nth-of-type(odd) { background-color: #3a3a3a; }
|
||||
.chat-packet {
|
||||
border-bottom: 1px solid #555;
|
||||
padding: 3px 6px;
|
||||
border-radius: 6px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Same column spacing as before */
|
||||
.chat-packet > [class^="col-"] {
|
||||
padding-left: 10px !important;
|
||||
padding-right: 10px !important;
|
||||
padding-top: 1px !important;
|
||||
padding-bottom: 1px !important;
|
||||
}
|
||||
|
||||
.chat-packet:nth-of-type(even) { background-color: #333333; }
|
||||
|
||||
.channel {
|
||||
font-style: italic;
|
||||
color: #bbb;
|
||||
}
|
||||
.channel a {
|
||||
font-style: normal;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
@keyframes flash {
|
||||
0% { background-color: #ffe066; }
|
||||
100% { background-color: inherit; }
|
||||
}
|
||||
.chat-packet.flash { animation: flash 3.5s ease-out; }
|
||||
|
||||
.replying-to {
|
||||
font-size: 0.8em;
|
||||
color: #aaa;
|
||||
margin-top: 2px;
|
||||
padding-left: 10px;
|
||||
}
|
||||
.replying-to .reply-preview { color: #aaa; }
|
||||
.chat-controls {
|
||||
gap: 12px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.chat-filter {
|
||||
min-width: 220px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section id="chat-container" aria-label="Mesh chat">
|
||||
<div class="chat-toolbar">
|
||||
<h1 class="chat-heading"><span aria-hidden="true">#</span> <span data-chat-translate="chat_title">Mesh chat</span></h1>
|
||||
<div class="chat-channel-control">
|
||||
<label for="channel-filter" class="visually-hidden" data-chat-translate="channel">Channel</label>
|
||||
<span aria-hidden="true">#</span>
|
||||
<select id="channel-filter" class="form-select form-select-sm chat-filter"><option value="" data-chat-translate="all_channels">All channels</option></select>
|
||||
</div>
|
||||
<label for="chat-search" class="visually-hidden">Search messages or nodes</label>
|
||||
<input id="chat-search" class="form-control form-control-sm chat-search" type="search" placeholder="Search messages or nodes…" autocomplete="off">
|
||||
<div class="chat-actions">
|
||||
<span id="chat-count" class="text-secondary small">0 messages</span>
|
||||
<span id="chat-status" class="chat-status" data-state="loading" role="status">Connecting…</span>
|
||||
<button id="chat-pause" class="chat-control" type="button" aria-pressed="false">Pause</button>
|
||||
<button id="chat-latest" class="chat-control" type="button">↓ Latest</button>
|
||||
<div id="chat-container" class="mt-3">
|
||||
|
||||
<!-- ⭐ CHAT TITLE WITH ICON, aligned to container ⭐ -->
|
||||
<div class="container px-2">
|
||||
<div class="d-flex align-items-center justify-content-between chat-controls">
|
||||
<h2 style="color:white; margin:0;">
|
||||
<span class="icon">💬</span>
|
||||
<span data-translate="chat_title"></span>
|
||||
</h2>
|
||||
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<label for="channel-filter" class="mb-0" data-translate="channel">Channel</label>
|
||||
<select id="channel-filter" class="form-select form-select-sm chat-filter">
|
||||
<option value="" data-translate="all_channels">All Channels</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="chat-log" class="chat-messages" role="region" aria-label="Messages, oldest to newest" tabindex="0"><p class="chat-empty">Loading messages…</p></div>
|
||||
<div class="chat-bottom"><p>Received text messages · updates every 5 seconds</p><span id="chat-updated" role="status"></span></div>
|
||||
</section>
|
||||
<script src="/static/chat-dashboard.js"></script>
|
||||
|
||||
<div class="container" id="chat-log"></div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", async () => {
|
||||
const chatContainer = document.querySelector("#chat-log");
|
||||
if (!chatContainer) return console.error("#chat-log not found");
|
||||
|
||||
let lastTime = null;
|
||||
let selectedChannel = "";
|
||||
const renderedPacketIds = new Set();
|
||||
const packetMap = new Map();
|
||||
let chatLang = {};
|
||||
|
||||
/* ==========================================================
|
||||
TRANSLATIONS FOR CHAT PAGE
|
||||
========================================================== */
|
||||
function applyTranslations(dict, root=document) {
|
||||
root.querySelectorAll("[data-translate]").forEach(el => {
|
||||
const key = el.dataset.translate;
|
||||
const val = dict[key];
|
||||
if (!val) return;
|
||||
if (el.placeholder) el.placeholder = val;
|
||||
else el.textContent = val;
|
||||
});
|
||||
}
|
||||
|
||||
async function loadChatLang() {
|
||||
try {
|
||||
const cfg = await window._siteConfigPromise;
|
||||
const langCode = cfg?.site?.language || "en";
|
||||
const res = await fetch(`/api/lang?lang=${langCode}§ion=chat`);
|
||||
chatLang = await res.json();
|
||||
|
||||
// Apply to existing DOM
|
||||
applyTranslations(chatLang);
|
||||
} catch (err) {
|
||||
console.error("Chat translation load failed:", err);
|
||||
}
|
||||
}
|
||||
|
||||
async function loadChannels() {
|
||||
try {
|
||||
const res = await fetch("/api/channels");
|
||||
if (!res.ok) return;
|
||||
|
||||
const data = await res.json();
|
||||
const select = document.getElementById("channel-filter");
|
||||
const channels = data.channels || [];
|
||||
|
||||
for (const channel of channels) {
|
||||
const option = document.createElement("option");
|
||||
option.value = channel;
|
||||
option.textContent = channel;
|
||||
select.appendChild(option);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Failed loading channels:", err);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
SAFE HTML
|
||||
========================================================== */
|
||||
function escapeHtml(text) {
|
||||
const div = document.createElement("div");
|
||||
div.textContent = text ?? "";
|
||||
return div.innerHTML;
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
RENDERING PACKETS
|
||||
========================================================== */
|
||||
function renderPacket(packet, highlight = false) {
|
||||
if (renderedPacketIds.has(packet.id)) return;
|
||||
renderedPacketIds.add(packet.id);
|
||||
packetMap.set(packet.id, packet);
|
||||
|
||||
let date;
|
||||
if (packet.import_time_us && packet.import_time_us > 0) {
|
||||
date = new Date(packet.import_time_us / 1000);
|
||||
} else if (packet.import_time) {
|
||||
date = new Date(packet.import_time);
|
||||
} else {
|
||||
date = new Date();
|
||||
}
|
||||
|
||||
const formattedTime = date.toLocaleTimeString([], {
|
||||
hour:"numeric",
|
||||
minute:"2-digit",
|
||||
second:"2-digit",
|
||||
hour12:true
|
||||
});
|
||||
const formattedDate =
|
||||
`${(date.getMonth()+1).toString().padStart(2,"0")}/` +
|
||||
`${date.getDate().toString().padStart(2,"0")}/` +
|
||||
`${date.getFullYear()}`;
|
||||
|
||||
const formattedTimestamp = `${formattedTime} - ${formattedDate}`;
|
||||
|
||||
let replyHtml = "";
|
||||
if (packet.reply_id) {
|
||||
const parent = packetMap.get(packet.reply_id);
|
||||
const replyPrefix = `<i data-translate="replying_to"></i>`;
|
||||
if (parent) {
|
||||
replyHtml = `
|
||||
<div class="replying-to">
|
||||
${replyPrefix}
|
||||
<strong>${escapeHtml((parent.long_name || "").trim() || `Node ${parent.from_node_id}`)}</strong>:
|
||||
${escapeHtml(parent.payload || "")}
|
||||
</div>`;
|
||||
} else {
|
||||
replyHtml = `
|
||||
<div class="replying-to">
|
||||
${replyPrefix}
|
||||
<a href="/packet/${packet.reply_id}">${packet.reply_id}</a>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
const div = document.createElement("div");
|
||||
div.className = "row chat-packet" + (highlight ? " flash" : "");
|
||||
div.dataset.packetId = packet.id;
|
||||
|
||||
div.innerHTML = `
|
||||
<span class="col-2 timestamp" title="${packet.import_time_us}">
|
||||
${formattedTimestamp}
|
||||
</span>
|
||||
|
||||
<span class="col-2 channel">
|
||||
<a href="/packet/${packet.id}" title="${chatLang.view_packet_details || 'View details'}">🔎</a>
|
||||
${escapeHtml(packet.channel || "")}
|
||||
</span>
|
||||
|
||||
<span class="col-3 nodename">
|
||||
<a href="/node/${packet.from_node_id}">
|
||||
${escapeHtml((packet.long_name || "").trim() || `Node ${packet.from_node_id}`)}
|
||||
</a>
|
||||
</span>
|
||||
|
||||
<span class="col-5 message">
|
||||
${escapeHtml(packet.payload)}${replyHtml}
|
||||
</span>
|
||||
`;
|
||||
|
||||
chatContainer.prepend(div);
|
||||
|
||||
// Translate newly added DOM
|
||||
applyTranslations(chatLang, div);
|
||||
|
||||
if (highlight) setTimeout(() => div.classList.remove("flash"), 2500);
|
||||
}
|
||||
|
||||
function matchesSelectedChannel(packet) {
|
||||
if (!selectedChannel) return true;
|
||||
return (packet.channel || "").toLowerCase() === selectedChannel.toLowerCase();
|
||||
}
|
||||
|
||||
function resetChat() {
|
||||
lastTime = null;
|
||||
renderedPacketIds.clear();
|
||||
packetMap.clear();
|
||||
chatContainer.innerHTML = "";
|
||||
}
|
||||
|
||||
function renderPacketsEnsureDescending(packets, highlight=false) {
|
||||
if (!Array.isArray(packets) || packets.length===0) return;
|
||||
const sortedDesc = packets.slice().sort((a,b)=>{
|
||||
const aTime = a.import_time_us || (new Date(a.import_time).getTime() * 1000);
|
||||
const bTime = b.import_time_us || (new Date(b.import_time).getTime() * 1000);
|
||||
return bTime - aTime;
|
||||
});
|
||||
for (let i=sortedDesc.length-1; i>=0; i--) {
|
||||
if (!matchesSelectedChannel(sortedDesc[i])) continue;
|
||||
renderPacket(sortedDesc[i], highlight);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
FETCHING PACKETS
|
||||
========================================================== */
|
||||
async function fetchInitial() {
|
||||
try {
|
||||
const resp = await fetch("/api/packets?portnum=1&limit=100");
|
||||
const data = await resp.json();
|
||||
if (data?.packets?.length) renderPacketsEnsureDescending(data.packets);
|
||||
lastTime = data?.latest_import_time || lastTime;
|
||||
} catch(err){
|
||||
console.error("Initial fetch error:", err);
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchUpdates() {
|
||||
try {
|
||||
const url = new URL("/api/packets?portnum=1", window.location.origin);
|
||||
url.searchParams.set("limit","100");
|
||||
if (lastTime) url.searchParams.set("since", lastTime);
|
||||
const resp = await fetch(url);
|
||||
const data = await resp.json();
|
||||
if (data?.packets?.length) renderPacketsEnsureDescending(data.packets, true);
|
||||
lastTime = data?.latest_import_time || lastTime;
|
||||
} catch(err){
|
||||
console.error("Fetch updates error:", err);
|
||||
}
|
||||
}
|
||||
|
||||
/* ==========================================================
|
||||
INIT
|
||||
========================================================== */
|
||||
await loadChatLang(); // load translations FIRST
|
||||
await loadChannels();
|
||||
|
||||
document.getElementById("channel-filter").addEventListener("change", async (e) => {
|
||||
selectedChannel = e.target.value;
|
||||
resetChat();
|
||||
await fetchInitial();
|
||||
});
|
||||
|
||||
await fetchInitial(); // then fetch initial packets
|
||||
|
||||
setInterval(fetchUpdates, 5000);
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,42 +0,0 @@
|
||||
{# Shared presentation for the diagnostic pages; no backend changes. #}
|
||||
<style>
|
||||
.mesh-data-page .mesh-content > .container { max-width:none; padding:0; }
|
||||
.mesh-data-page .data-heading { display:flex; align-items:center; justify-content:space-between; gap:16px; margin-bottom:24px; }
|
||||
.mesh-data-page .data-heading h1 { font-size:28px; font-weight:650; margin:5px 0 7px; overflow-wrap:anywhere; }
|
||||
.mesh-data-page .data-heading p { margin:0; color:var(--mesh-muted); font-size:14px; }
|
||||
.mesh-data-page .data-heading a { white-space:nowrap; }
|
||||
.mesh-data-page .data-toolbar { display:flex; align-items:center; flex-wrap:wrap; gap:10px; background:var(--mesh-surface); border:1px solid var(--mesh-border); padding:16px; border-radius:9px; margin:0 0 18px; }
|
||||
.mesh-data-page select,.mesh-data-page input[type="text"],.mesh-data-page input[type="search"] { min-width:0; max-width:100%; padding:8px 10px; border:1px solid var(--mesh-border); border-radius:5px; background:var(--mesh-surface); color:var(--mesh-text); font-size:13px; }
|
||||
.mesh-data-page .mesh-content button { border:1px solid var(--mesh-border); border-radius:5px; background:var(--mesh-soft); color:var(--mesh-primary); padding:8px 12px; font-size:12px; cursor:pointer; }
|
||||
.mesh-data-page .mesh-content button:hover { background:var(--mesh-hover); }
|
||||
.mesh-data-page .mesh-content button:disabled { opacity:.5; cursor:default; }
|
||||
.mesh-data-page :is(button,a,input,select):focus-visible { outline:2px solid var(--mesh-primary); outline-offset:2px; }
|
||||
.mesh-data-page .data-table-wrap { width:100%; overflow:auto; border:1px solid var(--mesh-border); border-radius:9px; background:var(--mesh-surface); margin-bottom:20px; }
|
||||
.mesh-data-page table { width:100%; border-collapse:collapse; font-size:13px; margin:0; color:var(--mesh-text); }
|
||||
.mesh-data-page table th { padding:12px 14px; background:var(--mesh-brand); color:white; border:0; font-weight:500; font-size:12px; white-space:nowrap; text-align:left; }
|
||||
.mesh-data-page table td { padding:11px 14px; border:0; border-bottom:1px solid var(--mesh-border); text-align:left; }
|
||||
.mesh-data-page table tbody tr { background:var(--mesh-surface); }
|
||||
.mesh-data-page table tbody tr:nth-child(even) { background:var(--mesh-stripe); }
|
||||
.mesh-data-page table tbody tr:hover { background:var(--mesh-hover); }
|
||||
.mesh-data-page table a { text-decoration:none; }
|
||||
.mesh-data-page table a:hover { text-decoration:underline; }
|
||||
.mesh-data-page .port-tag { display:inline-block; padding:3px 7px; border-radius:5px; color:white; font-size:10px; font-weight:500; white-space:nowrap; }
|
||||
.mesh-data-page .to-mqtt { color:var(--mesh-muted); font-size:12px; font-style:italic; }
|
||||
.mesh-data-page .payload-row { display:none; }
|
||||
.mesh-data-page .packet-table tr.expanded + .payload-row { display:table-row; }
|
||||
.mesh-data-page .payload-cell { font:12px/1.7 ui-monospace,Consolas,monospace; white-space:pre-wrap; overflow-wrap:anywhere; background:var(--mesh-soft); color:var(--mesh-text); }
|
||||
.mesh-data-page .toggle-btn { cursor:pointer; color:var(--mesh-muted); display:inline-block; margin-right:7px; }
|
||||
.mesh-data-page .inline-link { margin-left:6px; color:var(--mesh-primary); text-decoration:none; }
|
||||
.mesh-data-page #map { width:100%; height:650px; border:1px solid var(--mesh-border); border-radius:9px; margin:18px 0 24px; }
|
||||
.mesh-data-page .leaflet-container { background:var(--mesh-stripe); z-index:1; }
|
||||
.mesh-data-page .data-empty { padding:30px 16px; text-align:center; color:var(--mesh-muted); }
|
||||
@media(max-width:700px) {
|
||||
.mesh-data-page .data-heading { align-items:flex-start; gap:10px; }
|
||||
.mesh-data-page .data-heading h1 { font-size:23px; }
|
||||
.mesh-data-page .data-heading p { font-size:12px; }
|
||||
.mesh-data-page .data-toolbar { padding:12px; gap:8px; }
|
||||
.mesh-data-page .data-table-wrap table { min-width:700px; }
|
||||
.mesh-data-page #map { height:500px; }
|
||||
.mesh-data-page .data-heading a { font-size:11px; padding:8px; }
|
||||
}
|
||||
</style>
|
||||
@@ -1,24 +1,104 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-firehose-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
.firehose-controls { justify-content:space-between; }
|
||||
.firehose-controls h2 { font-size:15px; font-weight:600; }
|
||||
.firehose-controls > div { flex-wrap:wrap; }
|
||||
.firehose-filter { width:190px; }
|
||||
@media(max-width:700px) { .firehose-controls > div { width:100%; } .firehose-filter { flex:1; width:120px; } }
|
||||
.container {
|
||||
margin: 0 auto;
|
||||
padding: 10px;
|
||||
}
|
||||
#pause-button {
|
||||
white-space: nowrap;
|
||||
padding: 4px 10px;
|
||||
font-size: 0.9rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.firehose-controls {
|
||||
gap: 12px;
|
||||
}
|
||||
.firehose-filter {
|
||||
min-width: 220px;
|
||||
}
|
||||
|
||||
.port-tag {
|
||||
display: inline-block;
|
||||
padding: 2px 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Packet table */
|
||||
.packet-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.85rem;
|
||||
color: #e4e9ee;
|
||||
}
|
||||
|
||||
.packet-table th, .packet-table td {
|
||||
border: 1px solid #3a3f44;
|
||||
padding: 6px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.packet-table th {
|
||||
background-color: #1f2226;
|
||||
font-weight: bold;
|
||||
}
|
||||
.packet-table tr:nth-of-type(odd) { background-color: #272b2f; }
|
||||
.packet-table tr:nth-of-type(even) { background-color: #212529; }
|
||||
|
||||
/* Port tag */
|
||||
.port-tag {
|
||||
display: inline-block;
|
||||
padding: 1px 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.to-mqtt { font-style: italic; color: #aaa; }
|
||||
|
||||
/* Payload rows */
|
||||
.payload-row { display: none; background-color: #1b1e22; }
|
||||
.payload-cell {
|
||||
padding: 8px 12px;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
color: #b0bec5;
|
||||
}
|
||||
.packet-table tr.expanded + .payload-row {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
/* Toggle arrow */
|
||||
.toggle-btn {
|
||||
cursor: pointer;
|
||||
color: #aaa;
|
||||
margin-right: 6px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.toggle-btn:hover { color: #fff; }
|
||||
|
||||
/* Inline link next to port tag */
|
||||
.inline-link {
|
||||
margin-left: 6px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: #9fd4ff;
|
||||
}
|
||||
.inline-link:hover {
|
||||
color: #c7e6ff;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">NETWORK ACTIVITY</span><h1>Live Traffic</h1><p>Follow packet traffic across your mesh network.</p></div><a class="mesh-secondary-button" href="/map">View map ↗</a></header>
|
||||
|
||||
<form class="data-toolbar firehose-controls">
|
||||
<h2 class="mb-0" data-translate-lang="live_feed">📡 Live Traffic</h2>
|
||||
<form class="d-flex align-items-center justify-content-between mb-3 firehose-controls">
|
||||
<h2 class="mb-0" data-translate-lang="live_feed">📡 Live Feed</h2>
|
||||
|
||||
<div class="d-flex align-items-center gap-2">
|
||||
<label for="channel-filter" class="mb-0" data-translate-lang="channel">Channel</label>
|
||||
@@ -35,7 +115,6 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="data-table-wrap" role="region" aria-label="Live packet table" tabindex="0">
|
||||
<table class="packet-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -49,7 +128,6 @@
|
||||
</thead>
|
||||
<tbody id="packet_list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -174,7 +252,6 @@ function logPacketTimes(packet) {
|
||||
FIREHOSE FETCHING
|
||||
====================================================== */
|
||||
let lastImportTimeUs = null;
|
||||
let firehoseLoaded = false;
|
||||
let updatesPaused = false;
|
||||
let updateInterval = 3000;
|
||||
let selectedChannel = "";
|
||||
@@ -208,7 +285,6 @@ async function loadChannels() {
|
||||
}
|
||||
|
||||
function resetFirehose() {
|
||||
firehoseLoaded = false;
|
||||
lastImportTimeUs = null;
|
||||
document.getElementById("packet_list").innerHTML = "";
|
||||
}
|
||||
@@ -233,8 +309,6 @@ async function fetchUpdates() {
|
||||
|
||||
const data = await res.json();
|
||||
const packets = data.packets || [];
|
||||
const highlightNewPackets = firehoseLoaded;
|
||||
firehoseLoaded = true;
|
||||
if (!packets.length) return;
|
||||
|
||||
const list = document.getElementById("packet_list");
|
||||
@@ -330,7 +404,6 @@ async function fetchUpdates() {
|
||||
`;
|
||||
|
||||
list.insertAdjacentHTML("afterbegin", html);
|
||||
if (highlightNewPackets) markNewPacketArrival(list.firstElementChild);
|
||||
}
|
||||
|
||||
// Limit table size
|
||||
@@ -353,7 +426,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
pauseBtn.addEventListener("click", () => {
|
||||
updatesPaused = !updatesPaused;
|
||||
pauseBtn.setAttribute("aria-pressed", String(updatesPaused));
|
||||
|
||||
pauseBtn.textContent =
|
||||
updatesPaused
|
||||
|
||||
@@ -1,2 +1,5 @@
|
||||
{% extends "map-view.html" %}
|
||||
{% set dashboard = true %}
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block body %}
|
||||
{% include "search_form.html" %}
|
||||
{% endblock %}
|
||||
File diff suppressed because it is too large.
Load diff
+1079
-2
File diff suppressed because it is too large.
Load diff
+33
-29
@@ -1,32 +1,44 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-net-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
#weekly-message { padding:18px 22px; background:var(--mesh-soft); border:1px solid var(--mesh-border); border-radius:9px; color:var(--mesh-primary-dark); font-size:14px; margin-bottom:18px; white-space:pre-wrap; overflow-wrap:anywhere; }
|
||||
#weekly-message:empty { display:none; }
|
||||
#total-count { padding:16px 20px; color:var(--mesh-muted); background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px 9px 0 0; font-size:13px; }
|
||||
#total-count-value { font-size:20px; font-weight:650; color:var(--mesh-primary); margin-left:8px; }
|
||||
#chat-log { padding:0; }
|
||||
#chat-container { border:1px solid var(--mesh-border); border-top:0; border-radius:0 0 9px 9px; background:var(--mesh-surface); overflow:hidden; }
|
||||
.chat-packet { display:grid; grid-template-columns:155px 130px 200px minmax(0,1fr); gap:16px; margin:0; padding:16px 20px; border-bottom:1px solid var(--mesh-border); font-size:13px; }
|
||||
.chat-packet:nth-child(even) { background:var(--mesh-stripe); }
|
||||
.chat-packet > span { width:auto; padding:0; min-width:0; overflow-wrap:anywhere; }
|
||||
.chat-packet .timestamp { color:var(--mesh-muted); font-size:11px; }
|
||||
.chat-packet .channel { color:var(--mesh-muted); font-size:12px; }
|
||||
.chat-packet .nodename { font-weight:600; }
|
||||
.chat-packet a { text-decoration:none; }
|
||||
#net-note { color:var(--mesh-muted); font-size:12px; margin-top:14px; }
|
||||
@media(max-width:900px) { .chat-packet { grid-template-columns:120px 100px minmax(0,1fr); } .chat-packet .message { grid-column:1 / -1; } }
|
||||
@media(max-width:500px) { .chat-packet { grid-template-columns:1fr 1fr; gap:8px; } .chat-packet .nodename { grid-column:1 / -1; } }
|
||||
.timestamp { min-width: 10em; color: #ccc; }
|
||||
|
||||
.chat-packet:nth-of-type(odd) { background-color: #3a3a3a; }
|
||||
.chat-packet {
|
||||
border-bottom: 1px solid #555;
|
||||
padding: 3px 6px;
|
||||
border-radius: 6px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.chat-packet > [class^="col-"] {
|
||||
padding-left: 10px !important;
|
||||
padding-right: 10px !important;
|
||||
padding-top: 1px !important;
|
||||
padding-bottom: 1px !important;
|
||||
}
|
||||
|
||||
.chat-packet:nth-of-type(even) { background-color: #333333; }
|
||||
|
||||
.channel { font-style: italic; color: #bbb; }
|
||||
.channel a { font-style: normal; color: #999; }
|
||||
|
||||
#weekly-message { margin: 15px 0; font-weight: bold; color: #ffeb3b; }
|
||||
#total-count { margin-bottom: 10px; font-style: italic; color: #ccc; }
|
||||
#net-note { margin: 16px 0 0; font-size: 0.9rem; color: #aaa; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">COMMUNITY NET</span><h1><span data-translate-lang="net_title">Network check-in</span></h1><p>Weekly check-ins and reports from your mesh.</p></div><a class="mesh-secondary-button" href="/map">View map ↗</a></header>
|
||||
<!-- ⭐ NET TITLE WITH ICON ⭐ -->
|
||||
<div class="container px-2">
|
||||
<h2 style="color:white; margin:0 0 10px 0;">
|
||||
<span class="icon">💬</span>
|
||||
<span data-translate-lang="net_title"></span>
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<!-- Weekly network message -->
|
||||
<div id="weekly-message"></div>
|
||||
@@ -120,7 +132,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
const fromName =
|
||||
(packet.long_name || "").trim() ||
|
||||
`${netTranslations.node_fallback || "Node"} ${packet.from_node_id}`;
|
||||
`${netTranslations.node_fallback} ${packet.from_node_id}`;
|
||||
|
||||
const div = document.createElement("div");
|
||||
div.className = "row chat-packet";
|
||||
@@ -189,7 +201,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
`/api/packets?portnum=1&contains=${encodeURIComponent(tag)}&since=${sinceUs}&limit=1000`;
|
||||
|
||||
const resp = await fetch(url);
|
||||
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
|
||||
const data = await resp.json();
|
||||
|
||||
if (data?.packets?.length)
|
||||
@@ -197,7 +208,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
} catch (err) {
|
||||
console.error("Initial fetch error:", err);
|
||||
chatContainer.innerHTML = '<p class="data-empty">Unable to load check-ins. Reload to try again.</p>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -229,12 +239,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
await loadTranslations(cfg);
|
||||
await fetchInitialPackets(netTag);
|
||||
if (!chatContainer.children.length) {
|
||||
const empty = document.createElement("p");
|
||||
empty.className = "data-empty";
|
||||
empty.textContent = netTag ? "No check-ins received in the last six days." : "No network check-in tag configured.";
|
||||
chatContainer.append(empty);
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error("Initialization failed:", err);
|
||||
|
||||
+327
-59
@@ -1,40 +1,311 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-node-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
.node-info { display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:16px; margin-bottom:20px; font-size:13px; }
|
||||
.node-info-col { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; padding:20px; overflow-wrap:anywhere; }
|
||||
.node-info-col > div { padding:5px 0; }
|
||||
.node-info strong { color:var(--mesh-muted); font-weight:500; }
|
||||
.node-actions { display:flex; gap:8px; flex-wrap:wrap; margin-bottom:20px; }
|
||||
.chart-container { width:100%; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; margin-bottom:20px; overflow:hidden; }
|
||||
.chart-header { display:flex; justify-content:space-between; align-items:center; flex-wrap:wrap; gap:10px; padding:16px 20px; border-bottom:1px solid var(--mesh-border); font-size:14px; font-weight:600; }
|
||||
.chart-actions { display:flex; gap:6px; }
|
||||
.filter-container { display:flex; gap:10px; flex-wrap:wrap; padding:16px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; margin-bottom:18px; }
|
||||
#chartModal,#qrModal { display:none; position:fixed; inset:0; background:#17263c99; z-index:9999; align-items:center; justify-content:center; padding:16px; }
|
||||
#chartModal > div { background:var(--mesh-surface); border-radius:10px; width:95%; height:85%; padding:14px; }
|
||||
#qrModal > div { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:12px; padding:24px; width:380px; max-width:100%; text-align:center; }
|
||||
.qr-header { display:flex; justify-content:space-between; align-items:center; gap:10px; }
|
||||
.qr-title { font-size:18px; margin:0; }
|
||||
.qr-node-name { font-size:15px; margin:16px 0; overflow-wrap:anywhere; }
|
||||
.qr-image { display:inline-block; padding:16px; background:var(--mesh-surface); margin-bottom:14px; }
|
||||
.qr-image img,.qr-image canvas { max-width:100%; }
|
||||
.qr-url-container { border:1px solid var(--mesh-border); border-radius:6px; background:var(--mesh-page); padding:12px; margin-bottom:16px; }
|
||||
.qr-url { display:block; max-height:80px; overflow:auto; overflow-wrap:anywhere; font:11px/1.6 monospace; color:var(--mesh-muted); }
|
||||
.qr-actions { display:flex; justify-content:center; }
|
||||
.mesh-data-page .copied { background:#e8f5ee; color:#187346; }
|
||||
@media(max-width:900px) { .node-info { grid-template-columns:minmax(0,1fr); gap:10px; } }
|
||||
@media(max-width:700px) { .chart-header { padding:12px; } .chart-actions button { padding:6px 8px; } }
|
||||
{{ super() }}
|
||||
|
||||
/* --- Map --- */
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 400px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 8px;
|
||||
display: block;
|
||||
}
|
||||
.leaflet-container {
|
||||
background: #1a1a1a;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
/* --- Node Info --- */
|
||||
.node-info {
|
||||
color: #ddd;
|
||||
font-size: 0.88rem;
|
||||
margin-bottom: 14px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, minmax(120px, 1fr));
|
||||
grid-column-gap: 12px;
|
||||
grid-row-gap: 12px;
|
||||
}
|
||||
|
||||
.node-info-col {
|
||||
background-color: #1f2226;
|
||||
border: 1px solid #3a3f44;
|
||||
border-radius: 8px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
|
||||
.node-info-col div { padding: 2px 0; }
|
||||
.node-info strong {
|
||||
color: #9fd4ff;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* --- Charts --- */
|
||||
.chart-container {
|
||||
width: 100%;
|
||||
height: 380px;
|
||||
margin-bottom: 25px;
|
||||
border: 1px solid #3a3f44;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
background-color: #16191d;
|
||||
}
|
||||
.chart-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: #1f2226;
|
||||
padding: 6px 12px;
|
||||
font-weight: bold;
|
||||
border-bottom: 1px solid #333;
|
||||
font-size: 1rem;
|
||||
}
|
||||
.chart-actions button {
|
||||
background: rgba(255,255,255,0.05);
|
||||
border: 1px solid #555;
|
||||
border-radius: 4px;
|
||||
color: #ccc;
|
||||
font-size: 0.8rem;
|
||||
padding: 2px 6px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.chart-actions button:hover {
|
||||
color: #fff;
|
||||
background: rgba(255,255,255,0.15);
|
||||
border-color: #888;
|
||||
}
|
||||
|
||||
/* --- Packet Table --- */
|
||||
.packet-table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
font-size: 0.85rem;
|
||||
color: #e4e9ee;
|
||||
}
|
||||
.packet-table th, .packet-table td {
|
||||
border: 1px solid #3a3f44;
|
||||
padding: 6px 10px;
|
||||
text-align: left;
|
||||
}
|
||||
.packet-table th {
|
||||
background-color: #1f2226;
|
||||
font-weight: bold;
|
||||
}
|
||||
.packet-table tr:nth-of-type(odd) { background-color: #272b2f; }
|
||||
.packet-table tr:nth-of-type(even) { background-color: #212529; }
|
||||
|
||||
.port-tag {
|
||||
padding: 2px 6px;
|
||||
border-radius: 6px;
|
||||
font-size: 0.75rem;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.to-mqtt { font-style: italic; color: #aaa; }
|
||||
|
||||
.payload-row { display: none; background-color: #1b1e22; }
|
||||
.payload-cell {
|
||||
padding: 8px 12px;
|
||||
font-family: monospace;
|
||||
white-space: pre-wrap;
|
||||
color: #b0bec5;
|
||||
}
|
||||
.packet-table tr.expanded + .payload-row { display: table-row; }
|
||||
.toggle-btn { cursor: pointer; color: #aaa; margin-right: 6px; }
|
||||
.toggle-btn:hover { color: #fff; }
|
||||
|
||||
/* --- Chart Modal --- */
|
||||
#chartModal {
|
||||
display:none; position:fixed; top:0; left:0; width:100%; height:100%;
|
||||
background:rgba(0,0,0,0.9); z-index:9999;
|
||||
align-items:center; justify-content:center;
|
||||
}
|
||||
#chartModal > div {
|
||||
background:#1b1e22; border-radius:8px;
|
||||
width:90%; height:85%; padding:10px;
|
||||
}
|
||||
|
||||
/* Inline link */
|
||||
.inline-link {
|
||||
margin-left: 6px;
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: #9fd4ff;
|
||||
}
|
||||
.inline-link:hover { color: #c7e6ff; }
|
||||
|
||||
/* --- QR Code & Import --- */
|
||||
.node-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 14px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.node-actions {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
margin-bottom: 16px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.node-actions button {
|
||||
background: linear-gradient(135deg, #2d3748 0%, #1a202c 100%);
|
||||
border: 1px solid #4a5568;
|
||||
border-radius: 8px;
|
||||
color: #e4e9ee;
|
||||
padding: 8px 16px;
|
||||
font-size: 0.9rem;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
font-weight: 500;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
.node-actions button:hover {
|
||||
background: linear-gradient(135deg, #3d4758 0%, #2a303c 100%);
|
||||
border-color: #6a7788;
|
||||
transform: translateY(-1px);
|
||||
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
|
||||
}
|
||||
.node-actions button.copied {
|
||||
background: linear-gradient(135deg, #276749 0%, #22543d 100%);
|
||||
border-color: #48bb78;
|
||||
color: #fff;
|
||||
}
|
||||
.copy-success {
|
||||
color: #4ade80 !important;
|
||||
transition: opacity 0.3s;
|
||||
}
|
||||
|
||||
/* --- QR Modal --- */
|
||||
#qrModal {
|
||||
display:none;
|
||||
position:fixed;
|
||||
top:0; left:0; width:100%; height:100%;
|
||||
background:rgba(0,0,0,0.95);
|
||||
z-index:10000;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
backdrop-filter:blur(4px);
|
||||
}
|
||||
#qrModal > div {
|
||||
background:linear-gradient(145deg, #1e2228, #16191d);
|
||||
border:1px solid #3a4450;
|
||||
border-radius:16px;
|
||||
padding:28px;
|
||||
max-width:380px;
|
||||
text-align:center;
|
||||
color:#e4e9ee;
|
||||
box-shadow:0 25px 80px rgba(0,0,0,0.6);
|
||||
}
|
||||
#qrModal .qr-header {
|
||||
display:flex;
|
||||
justify-content:space-between;
|
||||
align-items:center;
|
||||
margin-bottom:16px;
|
||||
}
|
||||
#qrModal .qr-title {
|
||||
font-size:1.3rem;
|
||||
font-weight:600;
|
||||
margin:0;
|
||||
color:#9fd4ff;
|
||||
}
|
||||
#qrModal .qr-close {
|
||||
background:rgba(255,255,255,0.05);
|
||||
border:1px solid #4a5568;
|
||||
color:#9ca3af;
|
||||
width:32px;
|
||||
height:32px;
|
||||
border-radius:8px;
|
||||
cursor:pointer;
|
||||
font-size:1.2rem;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
transition:all 0.2s;
|
||||
}
|
||||
#qrModal .qr-close:hover {
|
||||
background:rgba(255,255,255,0.1);
|
||||
color:#fff;
|
||||
border-color:#6a7788;
|
||||
}
|
||||
#qrModal .qr-node-name {
|
||||
font-size:1.15rem;
|
||||
color:#fff;
|
||||
margin:12px 0 20px;
|
||||
font-weight:500;
|
||||
}
|
||||
#qrModal .qr-image {
|
||||
background:#fff;
|
||||
padding:16px;
|
||||
border-radius:12px;
|
||||
display:inline-block;
|
||||
margin-bottom:16px;
|
||||
box-shadow:0 8px 30px rgba(0,0,0,0.4);
|
||||
}
|
||||
#qrModal .qr-image img {
|
||||
display:block;
|
||||
border-radius:4px;
|
||||
}
|
||||
#qrModal .qr-url-container {
|
||||
background:rgba(0,0,0,0.4);
|
||||
border-radius:8px;
|
||||
padding:12px;
|
||||
margin-bottom:18px;
|
||||
}
|
||||
#qrModal .qr-url {
|
||||
font-size:0.65rem;
|
||||
color:#9ca3af;
|
||||
word-break:break-all;
|
||||
font-family:'Monaco', 'Menlo', monospace;
|
||||
line-height:1.4;
|
||||
max-height:48px;
|
||||
overflow-y:auto;
|
||||
display:block;
|
||||
}
|
||||
#qrModal .qr-actions {
|
||||
display:flex;
|
||||
gap:12px;
|
||||
justify-content:center;
|
||||
}
|
||||
#qrModal .qr-btn {
|
||||
background:linear-gradient(135deg, #2d3748 0%, #1a202c 100%);
|
||||
border:1px solid #4a5568;
|
||||
color:#e4e9ee;
|
||||
padding:12px 24px;
|
||||
border-radius:10px;
|
||||
cursor:pointer;
|
||||
font-size:0.9rem;
|
||||
font-weight:500;
|
||||
transition:all 0.2s;
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap:8px;
|
||||
min-width:140px;
|
||||
justify-content:center;
|
||||
}
|
||||
#qrModal .qr-btn:hover {
|
||||
background:linear-gradient(135deg, #3d4758 0%, #2a303c 100%);
|
||||
border-color:#6a7788;
|
||||
transform:translateY(-2px);
|
||||
box-shadow:0 4px 12px rgba(0,0,0,0.3);
|
||||
}
|
||||
#qrModal .qr-btn.copied {
|
||||
background:linear-gradient(135deg, #276749 0%, #22543d 100%);
|
||||
border-color:#48bb78;
|
||||
color:#fff;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container">
|
||||
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">DEVICE INSPECTOR</span><h1><span id="nodeLabel">Node details</span></h1><p>Device information, telemetry, and recent packet activity.</p></div><a class="mesh-secondary-button" href="/nodelist">All nodes ↗</a></header>
|
||||
<h5 class="mb-3">
|
||||
📡 <span data-translate-lang="specifications">Specifications:</span><strong>:</strong>
|
||||
<span id="nodeLabel"></span>
|
||||
</h5>
|
||||
|
||||
<!-- Node Actions -->
|
||||
<div class="node-actions" id="nodeActions" style="display:none;">
|
||||
@@ -151,18 +422,18 @@
|
||||
|
||||
<!-- Packet Filters -->
|
||||
<div class="filter-container" style="margin-bottom:10px; display:flex; gap:12px; flex-wrap:wrap;">
|
||||
<select id="packet_since" aria-label="Packet time range">
|
||||
<select id="packet_since">
|
||||
<option value="">All time</option>
|
||||
<option value="3600">Last hour</option>
|
||||
<option value="21600">Last 6 hours</option>
|
||||
<option value="86400">Last 24 hours</option>
|
||||
<option value="172800">Last 2 days</option>
|
||||
<option value="259200" selected>Last 3 days</option>
|
||||
<option value="259200">Last 3 days</option>
|
||||
<option value="432000">Last 5 days</option>
|
||||
<option value="604800">Last 7 days</option>
|
||||
</select>
|
||||
|
||||
<select id="packet_port" aria-label="Packet port">
|
||||
<select id="packet_port">
|
||||
<option value="">All ports</option>
|
||||
</select>
|
||||
|
||||
@@ -174,7 +445,6 @@
|
||||
|
||||
|
||||
<!-- Packets -->
|
||||
<div class="data-table-wrap" role="region" aria-label="Node packet table" tabindex="0">
|
||||
<table class="packet-table">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -189,7 +459,6 @@
|
||||
|
||||
<tbody id="packet_list"></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -197,7 +466,7 @@
|
||||
<div id="chartModal">
|
||||
<div>
|
||||
<div style="text-align:right;">
|
||||
<button onclick="closeModal()" style="background:none;border:none;color:var(--mesh-muted);">✖</button>
|
||||
<button onclick="closeModal()" style="background:none;border:none;color:#ccc;">✖</button>
|
||||
</div>
|
||||
<div id="modalChart" style="width:100%; height:90%;"></div>
|
||||
</div>
|
||||
@@ -399,7 +668,6 @@ async function loadNodeInfo(){
|
||||
|
||||
if (!node) {
|
||||
document.getElementById("node-info").style.display = "none";
|
||||
document.getElementById("nodeLabel").textContent = "Node unavailable";
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -934,14 +1202,14 @@ async function loadTelemetryCharts(){
|
||||
// Battery / Voltage chart
|
||||
if (hasBattery || hasVoltage) {
|
||||
batteryContainer.style.display = "block";
|
||||
chart1 = initMeshChart(document.getElementById('chart_battery_voltage'));
|
||||
chart1 = echarts.init(document.getElementById('chart_battery_voltage'));
|
||||
chart1.setOption({
|
||||
tooltip: { trigger:'axis' },
|
||||
legend: { data:['Battery Level','Voltage'], textStyle:{ color:'#64748b' } },
|
||||
xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#64748b' } },
|
||||
legend: { data:['Battery Level','Voltage'], textStyle:{ color:'#ccc' } },
|
||||
xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#ccc' } },
|
||||
yAxis: [
|
||||
{ type:'value', name:'Battery (%)', axisLabel:{ color:'#64748b' } },
|
||||
{ type:'value', name:'Voltage (V)', axisLabel:{ color:'#64748b' } }
|
||||
{ type:'value', name:'Battery (%)', axisLabel:{ color:'#ccc' } },
|
||||
{ type:'value', name:'Voltage (V)', axisLabel:{ color:'#ccc' } }
|
||||
],
|
||||
series: [
|
||||
makeLine('Battery Level', 'rgba(255,214,82,1)', chartData.battery),
|
||||
@@ -955,12 +1223,12 @@ async function loadTelemetryCharts(){
|
||||
// Air / Channel chart
|
||||
if (hasAir || hasChan) {
|
||||
airContainer.style.display = "block";
|
||||
chart2 = initMeshChart(document.getElementById('chart_air_channel'));
|
||||
chart2 = echarts.init(document.getElementById('chart_air_channel'));
|
||||
chart2.setOption({
|
||||
tooltip: { trigger:'axis' },
|
||||
legend: { data:['Air Util Tx','Channel Utilization'], textStyle:{ color:'#64748b' } },
|
||||
xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#64748b' } },
|
||||
yAxis: { type:'value', name:'%', axisLabel:{ color:'#64748b' } },
|
||||
legend: { data:['Air Util Tx','Channel Utilization'], textStyle:{ color:'#ccc' } },
|
||||
xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#ccc' } },
|
||||
yAxis: { type:'value', name:'%', axisLabel:{ color:'#ccc' } },
|
||||
series: [
|
||||
makeLine('Air Util Tx', 'rgba(138,255,108,1)', chartData.airUtil),
|
||||
makeLine('Channel Utilization', 'rgba(255,102,204,1)', chartData.chanUtil)
|
||||
@@ -973,14 +1241,14 @@ async function loadTelemetryCharts(){
|
||||
// Environment chart
|
||||
if (hasEnv) {
|
||||
envContainer.style.display = "block";
|
||||
chart3 = initMeshChart(document.getElementById('chart_environment'));
|
||||
chart3 = echarts.init(document.getElementById('chart_environment'));
|
||||
chart3.setOption({
|
||||
tooltip: { trigger:'axis' },
|
||||
legend: { data:['Temperature (°C)','Humidity (%)','Pressure (hPa)'], textStyle:{ color:'#64748b' } },
|
||||
xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#64748b' } },
|
||||
legend: { data:['Temperature (°C)','Humidity (%)','Pressure (hPa)'], textStyle:{ color:'#ccc' } },
|
||||
xAxis: { type:'category', data:chartData.times, axisLabel:{ color:'#ccc' } },
|
||||
yAxis: [
|
||||
{ type:'value', name:'°C / %', axisLabel:{ color:'#64748b' } },
|
||||
{ type:'value', name:'hPa', axisLabel:{ color:'#64748b' } }
|
||||
{ type:'value', name:'°C / %', axisLabel:{ color:'#ccc' } },
|
||||
{ type:'value', name:'hPa', axisLabel:{ color:'#ccc' } }
|
||||
],
|
||||
series: [
|
||||
makeLine('Temperature (°C)', 'rgba(255,138,82,1)', chartData.temperature),
|
||||
@@ -1170,7 +1438,7 @@ async function loadNeighborTimeSeries() {
|
||||
.replace("{n}", kept.length)
|
||||
.replace("{total}", ranked.length);
|
||||
|
||||
const chart = initMeshChart(chartEl);
|
||||
const chart = echarts.init(chartEl);
|
||||
|
||||
chart.setOption({
|
||||
title: {
|
||||
@@ -1187,13 +1455,13 @@ async function loadNeighborTimeSeries() {
|
||||
legend: {
|
||||
type: "scroll",
|
||||
data: legend,
|
||||
textStyle: { color: "#64748b" }
|
||||
textStyle: { color: "#ccc" }
|
||||
},
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: xTimes,
|
||||
axisLabel: {
|
||||
color: "#64748b",
|
||||
color: "#ccc",
|
||||
formatter: value =>
|
||||
new Date(value / 1000).toLocaleString([], {
|
||||
year: "2-digit",
|
||||
@@ -1207,7 +1475,7 @@ async function loadNeighborTimeSeries() {
|
||||
yAxis: {
|
||||
type: "value",
|
||||
name: "SNR",
|
||||
axisLabel: { color: "#64748b" }
|
||||
axisLabel: { color: "#ccc" }
|
||||
},
|
||||
series
|
||||
});
|
||||
@@ -1291,22 +1559,22 @@ async function loadPacketHistogram() {
|
||||
data: dayKeys.map(d => counts[port]?.[d] || 0)
|
||||
}));
|
||||
|
||||
const chart = initMeshChart(
|
||||
const chart = echarts.init(
|
||||
document.getElementById("chart_packet_histogram")
|
||||
);
|
||||
|
||||
chart.setOption({
|
||||
animation: false,
|
||||
tooltip: { trigger: "axis" },
|
||||
legend: { textStyle: { color: "#64748b" } },
|
||||
legend: { textStyle: { color: "#ccc" } },
|
||||
xAxis: {
|
||||
type: "category",
|
||||
data: dayLabels,
|
||||
axisLabel: { color: "#64748b" }
|
||||
axisLabel: { color: "#ccc" }
|
||||
},
|
||||
yAxis: {
|
||||
type: "value",
|
||||
axisLabel: { color: "#64748b" }
|
||||
axisLabel: { color: "#ccc" }
|
||||
},
|
||||
series
|
||||
});
|
||||
@@ -1327,7 +1595,7 @@ function expandChart(type){
|
||||
if (!sourceChart) return;
|
||||
|
||||
const modal = document.getElementById('chartModal');
|
||||
const modalChart = initMeshChart(document.getElementById('modalChart'));
|
||||
const modalChart = echarts.init(document.getElementById('modalChart'));
|
||||
modal.style.display = "flex";
|
||||
modalChart.setOption(sourceChart.getOption());
|
||||
modalChart.resize();
|
||||
@@ -1415,7 +1683,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
await drawNeighbors(fromNodeId, neighborIds);
|
||||
}
|
||||
|
||||
await reloadPackets();
|
||||
await loadPackets();
|
||||
initPacketPortFilter();
|
||||
await loadTelemetryCharts();
|
||||
await loadNeighborTimeSeries();
|
||||
@@ -1485,7 +1753,7 @@ async function loadNodeStats(nodeId) {
|
||||
filters.portnum = portSel;
|
||||
}
|
||||
|
||||
return loadPackets(filters);
|
||||
loadPackets(filters);
|
||||
}
|
||||
|
||||
function exportPacketsCSV() {
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
#mynetwork {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
border: 1px solid var(--mesh-border);
|
||||
background-color: var(--mesh-surface);
|
||||
border: 1px solid #ddd;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 4px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
@@ -30,15 +30,15 @@
|
||||
.search-container button {
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--mesh-border);
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
.search-container button {
|
||||
background-color: var(--mesh-brand);
|
||||
background-color: #007bff;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
}
|
||||
.search-container button:hover {
|
||||
background-color: var(--mesh-brand-deep);
|
||||
background-color: #0056b3;
|
||||
}
|
||||
|
||||
/* Node info box */
|
||||
@@ -49,10 +49,10 @@
|
||||
background-color: rgba(255,255,255,0.95);
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--mesh-border);
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.1);
|
||||
font-size: 14px;
|
||||
color: var(--mesh-text);
|
||||
color: #333;
|
||||
width: 260px;
|
||||
max-height: 250px;
|
||||
overflow-y: auto;
|
||||
@@ -66,13 +66,11 @@
|
||||
background: rgba(255,255,255,0.9);
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
border: 1px solid var(--mesh-border);
|
||||
border: 1px solid #ccc;
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
font-size: 14px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-width: calc(100% - 20px);
|
||||
color: var(--mesh-text);
|
||||
color: #333;
|
||||
}
|
||||
.legend-category {
|
||||
margin-right: 10px;
|
||||
@@ -93,7 +91,7 @@
|
||||
|
||||
<!-- SEARCH + FILTER -->
|
||||
<div class="search-container">
|
||||
<label style="color:var(--mesh-text);">Channel:</label>
|
||||
<label style="color:#333;">Channel:</label>
|
||||
<select id="channel-select" onchange="filterByChannel()"></select>
|
||||
|
||||
<input type="text" id="node-search" placeholder="Search node...">
|
||||
@@ -133,7 +131,7 @@
|
||||
|
||||
<script>
|
||||
// Initialize ECharts
|
||||
const chart = initMeshChart(document.getElementById("mynetwork"));
|
||||
const chart = echarts.init(document.getElementById("mynetwork"));
|
||||
|
||||
// -----------------------------------
|
||||
// COLOR + ROLE HELPERS
|
||||
|
||||
@@ -1,35 +1,226 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-nodelist-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
#node-list { width:100%; overflow:auto; border:1px solid var(--mesh-border); border-radius:9px; background:var(--mesh-surface); }
|
||||
#node-list table { min-width:1150px; }
|
||||
#node-list th { cursor:pointer; }
|
||||
.filter-container { display:flex; flex-wrap:wrap; gap:10px; margin-bottom:18px; padding:16px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; }
|
||||
.search-box { flex:1 1 220px; }
|
||||
.count-container { font-size:13px; color:var(--mesh-muted); margin-bottom:10px; }
|
||||
#node-count { color:var(--mesh-primary); font-weight:700; }
|
||||
.node-list-note { display:flex; align-items:center; gap:8px; color:var(--mesh-muted); font-size:12px; margin-bottom:18px; flex-wrap:wrap; }
|
||||
.node-status { opacity:0; padding:3px 8px; border-radius:20px; background:var(--mesh-soft); color:var(--mesh-primary); margin-left:10px; font-size:11px; }
|
||||
.node-status.active { opacity:1; }
|
||||
.favorite-star { cursor:pointer; font-size:20px; color:#8b98aa; user-select:none; }
|
||||
.favorite-star.active { color:#ad7800; }
|
||||
.mesh-data-page .favorites-btn.active { background:#fff3d6; border-color:#eacb80; color:#8b6200; }
|
||||
.sort-icon { font-size:10px; }
|
||||
#mobile-node-list { display:none; }
|
||||
.node-card { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; padding:16px; margin-bottom:12px; font-size:13px; overflow-wrap:anywhere; }
|
||||
.node-card-header { display:flex; justify-content:space-between; align-items:center; margin-bottom:10px; font-size:16px; font-weight:600; }
|
||||
.node-card-field { padding:3px 0; }
|
||||
.node-card-field b { color:var(--mesh-muted); font-weight:500; }
|
||||
@media(max-width:768px) { #node-list { display:none; } #mobile-node-list { display:block!important; } .filter-container { padding:12px; gap:8px; } .filter-container select { flex:1 1 130px; } }
|
||||
html, body {
|
||||
overflow-x: auto !important;
|
||||
}
|
||||
|
||||
table {
|
||||
/* FIX: allow table to keep natural width so scrolling works */
|
||||
width: max-content;
|
||||
min-width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 1em auto;
|
||||
}
|
||||
|
||||
/* Desktop scroll wrapper */
|
||||
#node-list {
|
||||
width: 100%;
|
||||
overflow-x: auto; /* allows horizontal scroll */
|
||||
overflow-y: hidden;
|
||||
/* !!! removed display:flex because it prevents scrolling */
|
||||
}
|
||||
|
||||
#node-list table {
|
||||
width: max-content; /* table keeps its natural width */
|
||||
min-width: 100%; /* won't shrink smaller than viewport */
|
||||
}
|
||||
th, td {
|
||||
padding: 10px;
|
||||
border: 1px solid #333;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #1f1f1f;
|
||||
color: white;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 2;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sort-icon {
|
||||
font-size: 0.7em;
|
||||
margin-left: 4px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #181818;
|
||||
}
|
||||
|
||||
tr:nth-child(odd) {
|
||||
background-color: #222;
|
||||
}
|
||||
|
||||
tr:hover {
|
||||
background-color: #2a2a2a;
|
||||
}
|
||||
|
||||
.filter-container {
|
||||
width: 80%;
|
||||
margin: 1em auto;
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
select, .export-btn, .search-box, .clear-btn {
|
||||
padding: 6px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.export-btn {
|
||||
background-color: #28a745;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.export-btn:hover {
|
||||
background-color: #218838;
|
||||
}
|
||||
|
||||
.clear-btn {
|
||||
background-color: #dc3545;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.clear-btn:hover {
|
||||
background-color: #c82333;
|
||||
}
|
||||
|
||||
.count-container {
|
||||
width: 80%;
|
||||
margin: 0 auto 10px;
|
||||
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;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #2a6a8a;
|
||||
background: #0d2a3a;
|
||||
color: #9fd4ff;
|
||||
font-size: 0.9em;
|
||||
display: inline-block;
|
||||
opacity: 0;
|
||||
transition: opacity 0.15s ease-in-out;
|
||||
}
|
||||
.node-status.active {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
/* Favorite stars */
|
||||
.favorite-star {
|
||||
cursor: pointer;
|
||||
font-size: 1.2em;
|
||||
user-select: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.favorite-star:hover {
|
||||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.favorite-star.active {
|
||||
color: #ffd700;
|
||||
}
|
||||
|
||||
/* Favorite filter button */
|
||||
.favorites-btn {
|
||||
background-color: #ffd700;
|
||||
color: #000;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.favorites-btn:hover {
|
||||
background-color: #ffed4e;
|
||||
}
|
||||
|
||||
.favorites-btn.active {
|
||||
background-color: #ff6b6b;
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* --------------------------------------------- */
|
||||
/* MOBILE CARD VIEW */
|
||||
/* --------------------------------------------- */
|
||||
@media (max-width: 768px) {
|
||||
|
||||
/* Hide desktop view */
|
||||
#node-list table {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Show mobile cards */
|
||||
#mobile-node-list {
|
||||
display: block !important;
|
||||
width: 100%;
|
||||
padding: 0 10px;
|
||||
|
||||
/* If you want horizontal swiping, uncomment:
|
||||
overflow-x: auto;
|
||||
white-space: nowrap; */
|
||||
}
|
||||
|
||||
.node-card {
|
||||
background: #1e1e1e;
|
||||
border: 1px solid #333;
|
||||
border-radius: 8px;
|
||||
padding: 12px 15px;
|
||||
margin-bottom: 12px;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.node-card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
font-size: 1.2em;
|
||||
font-weight: bold;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.node-card-field {
|
||||
margin: 4px 0;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.node-card-field b {
|
||||
color: #9fd4ff;
|
||||
}
|
||||
|
||||
.favorite-star {
|
||||
font-size: 1.4em;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">NODE DIRECTORY</span><h1>Network nodes</h1><p>Find devices, inspect their activity, and manage your favorites.</p></div><a class="mesh-secondary-button" href="/map">View map ↗</a></header>
|
||||
<div class="filter-container">
|
||||
|
||||
<input
|
||||
@@ -40,19 +231,19 @@
|
||||
placeholder="Search by name or ID or HEX ID..."
|
||||
/>
|
||||
|
||||
<select id="role-filter" aria-label="Filter by role">
|
||||
<select id="role-filter">
|
||||
<option value="" data-translate-lang="all_roles">All Roles</option>
|
||||
</select>
|
||||
|
||||
<select id="channel-filter" aria-label="Filter by channel">
|
||||
<select id="channel-filter">
|
||||
<option value="" data-translate-lang="all_channels">All Channels</option>
|
||||
</select>
|
||||
|
||||
<select id="hw-filter" aria-label="Filter by hardware">
|
||||
<select id="hw-filter">
|
||||
<option value="" data-translate-lang="all_hw">All HW Models</option>
|
||||
</select>
|
||||
|
||||
<select id="firmware-filter" aria-label="Filter by firmware">
|
||||
<select id="firmware-filter">
|
||||
<option value="" data-translate-lang="all_firmware">All Firmware</option>
|
||||
</select>
|
||||
|
||||
@@ -105,7 +296,7 @@
|
||||
</thead>
|
||||
<tbody id="node-table-body">
|
||||
<tr>
|
||||
<td colspan="11" style="text-align:center; color:var(--mesh-muted);" data-translate-lang="loading_nodes">
|
||||
<td colspan="11" style="text-align:center; color:white;" data-translate-lang="loading_nodes">
|
||||
Loading nodes...
|
||||
</td>
|
||||
</tr>
|
||||
@@ -439,12 +630,12 @@ document.addEventListener("DOMContentLoaded", async function() {
|
||||
if (!nodes.length) {
|
||||
if (shouldRenderTable) {
|
||||
tbody.innerHTML = `<tr>
|
||||
<td colspan="11" style="text-align:center; color:var(--mesh-muted);">
|
||||
<td colspan="11" style="text-align:center; color:white;">
|
||||
${nodelistTranslations.no_nodes_found || "No nodes found"}
|
||||
</td>
|
||||
</tr>`;
|
||||
} else {
|
||||
mobileList.innerHTML = `<div style="text-align:center; color:var(--mesh-muted);">
|
||||
mobileList.innerHTML = `<div style="text-align:center; color:white;">
|
||||
${nodelistTranslations.no_nodes_found || "No nodes found"}
|
||||
</div>`;
|
||||
}
|
||||
@@ -502,7 +693,7 @@ document.addEventListener("DOMContentLoaded", async function() {
|
||||
<div class="node-card-field"><b>Channel:</b> ${escapeHtml(node.channel || "N/A")}</div>
|
||||
<div class="node-card-field"><b>Last Seen:</b> ${timeAgoFromMs(node.last_seen_ms)}</div>
|
||||
|
||||
<a href="/node/${node.node_id}" style="color:var(--mesh-primary); text-decoration:none; margin-top:10px; display:block;">
|
||||
<a href="/node/${node.node_id}" style="color:#9fd4ff; text-decoration:underline; margin-top:5px; display:block;">
|
||||
View Node →
|
||||
</a>
|
||||
`;
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-packet-page{% endblock %}
|
||||
|
||||
{% block title %}Packet Details{% endblock %}
|
||||
|
||||
@@ -9,30 +7,99 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
{{ super() }}
|
||||
<style>
|
||||
.mesh-data-page .packet-container { max-width:1150px!important; margin:0 auto!important; }
|
||||
.packet-card { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; overflow:hidden; color:var(--mesh-text); }
|
||||
.packet-card .card-header { display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; background:var(--mesh-soft); padding:18px 22px; border-bottom:1px solid var(--mesh-border); color:var(--mesh-primary-dark); font-size:15px; font-weight:600; }
|
||||
.packet-card .card-header small { font-size:11px; font-weight:400; }
|
||||
.packet-card .card-body { padding:24px; }
|
||||
.packet-card dl { display:grid; grid-template-columns:180px minmax(0,1fr); gap:16px 24px; margin:0; font-size:13px; }
|
||||
.packet-card dt { color:var(--mesh-muted); font-weight:500; }
|
||||
.packet-card dd { margin:0; overflow-wrap:anywhere; }
|
||||
.packet-card pre { padding:14px; background:var(--mesh-stripe); border:1px solid var(--mesh-border); border-radius:6px; color:var(--mesh-text); font-size:12px; white-space:pre-wrap; overflow-wrap:anywhere; margin:0; }
|
||||
#map { display:none; }
|
||||
.source-marker { width:24px; height:24px; background:#f4484866; border:3px solid #e33; border-radius:50%; box-shadow:0 0 6px #f007; }
|
||||
#seen-container { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; overflow:hidden; }
|
||||
#seen-container h5 { padding:16px 20px; margin:0!important; color:var(--mesh-text); font-size:15px; }
|
||||
.seen-table { margin:0; }
|
||||
#loading { color:var(--mesh-muted); padding:24px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; }
|
||||
@media(max-width:700px) { .packet-card dl { grid-template-columns:minmax(0,1fr); gap:6px; } .packet-card dd { margin-bottom:14px; } .packet-card .card-body { padding:18px; } }
|
||||
|
||||
/* --- Packet page container --- */
|
||||
.packet-container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
padding: 20px 15px;
|
||||
font-family: "JetBrains Mono", monospace;
|
||||
}
|
||||
|
||||
/* --- Packet Details Card --- */
|
||||
.packet-card .card-body { padding: 26px 30px; }
|
||||
.packet-card {
|
||||
background-color: #1e1f22;
|
||||
border: 1px solid #3a3a3a;
|
||||
border-radius: 12px;
|
||||
color: #ddd;
|
||||
margin-top: 35px;
|
||||
box-shadow: 0 0 20px rgba(0,0,0,0.35);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.packet-card .card-header {
|
||||
background: linear-gradient(90deg, #2c2f35, #25262a);
|
||||
border-bottom: 1px solid #3f3f3f;
|
||||
font-weight: 600;
|
||||
font-size: 1.1em;
|
||||
padding: 14px 18px;
|
||||
color: #e2e6ea;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* --- Map --- */
|
||||
#map {
|
||||
width: 100%;
|
||||
height: 640px;
|
||||
border-radius: 10px;
|
||||
margin-top: 20px;
|
||||
border: 1px solid #333;
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* --- SOURCE MARKER --- */
|
||||
.source-marker {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
background: rgba(255,0,0,0.55);
|
||||
border: 3px solid #ff0000;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 6px rgba(255,0,0,0.7);
|
||||
}
|
||||
|
||||
/* --- Seen Table --- */
|
||||
.seen-table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0 6px;
|
||||
font-size: 0.92em;
|
||||
}
|
||||
.seen-table thead th {
|
||||
background-color: #2a2b2f;
|
||||
color: #e2e2e2;
|
||||
padding: 10px 12px;
|
||||
border: none !important;
|
||||
text-transform: uppercase;
|
||||
font-size: 0.75em;
|
||||
}
|
||||
.seen-table tbody td {
|
||||
background: #323338;
|
||||
color: #f0f0f0;
|
||||
border-top: 1px solid #4a4c4f !important;
|
||||
border-bottom: 1px solid #4a4c4f !important;
|
||||
padding: 10px 12px !important;
|
||||
}
|
||||
.seen-table tbody tr:hover td { background-color: #3a3c41 !important; }
|
||||
.seen-table tbody tr td:first-child {
|
||||
border-left: 1px solid #4a4c4f;
|
||||
border-top-left-radius: 8px;
|
||||
border-bottom-left-radius: 8px;
|
||||
}
|
||||
.seen-table tbody tr td:last-child {
|
||||
border-right: 1px solid #4a4c4f;
|
||||
border-top-right-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
}
|
||||
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="container packet-container">
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">PACKET INSPECTOR</span><h1>Packet details</h1><p>Inspect the payload, route, and gateways that received this packet.</p></div><a class="mesh-secondary-button" href="/firehose">Live packets ↗</a></header>
|
||||
<div class="container mt-4 mb-5 packet-container">
|
||||
|
||||
<div id="loading" data-translate-lang="loading">Loading packet information...</div>
|
||||
<div id="packet-card" class="packet-card d-none"></div>
|
||||
@@ -40,13 +107,13 @@
|
||||
<div id="map"></div>
|
||||
|
||||
<div id="seen-container" class="mt-4 d-none">
|
||||
<h5 >
|
||||
<h5 style="color:#ccc; margin:15px 0 10px 0;">
|
||||
📡 <span data-translate-lang="seen_by">Seen By</span>
|
||||
<span id="seen-count" style="color:var(--mesh-primary);"></span>
|
||||
<span id="seen-count" style="color:#4da6ff;"></span>
|
||||
</h5>
|
||||
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm seen-table">
|
||||
<table class="table table-dark table-sm seen-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th data-translate-lang="gateway">Gateway</th>
|
||||
@@ -443,10 +510,10 @@ seenTableBody.innerHTML = Object.keys(hopGroups)
|
||||
<tr>
|
||||
<td colspan="6"
|
||||
style="
|
||||
background:var(--mesh-soft);
|
||||
background:#1f2327;
|
||||
font-weight:700;
|
||||
color:var(--mesh-primary-dark);
|
||||
border-top:1px solid var(--mesh-border);
|
||||
color:#9ecbff;
|
||||
border-top:1px solid #444;
|
||||
padding:8px 12px;
|
||||
">
|
||||
🔁 ${hopLabel} (${hopGroups[hopKey].length})
|
||||
|
||||
@@ -1,60 +1,280 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-reliability-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
.reach-page { width:100%; }
|
||||
.reach-description { margin-bottom:20px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; padding:14px 18px; font-size:13px; color:var(--mesh-muted); }
|
||||
.reach-description summary { cursor:pointer; color:var(--mesh-text); font-weight:500; }
|
||||
.reach-description p { margin:12px 0 0; line-height:1.7; }
|
||||
.reach-controls { display:flex; align-items:center; flex-wrap:wrap; gap:10px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; padding:16px; margin-bottom:20px; }
|
||||
.reach-search { flex:1 1 260px; }
|
||||
.reach-search-label,.reach-limit-label { color:var(--mesh-muted); font-size:12px; }
|
||||
.reach-node-link { white-space:nowrap; font-size:12px; }
|
||||
.reach-summary { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:18px; margin-bottom:20px; }
|
||||
.reach-metric { background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; padding:20px 24px; font-size:13px; }
|
||||
.reach-metric-value { font-size:30px; font-weight:650; color:var(--mesh-primary); margin-top:6px; font-variant-numeric:tabular-nums; }
|
||||
.reach-metric:nth-child(2) .reach-metric-value { color:#198754; }
|
||||
.reach-table-wrap { overflow-x:auto; border:1px solid var(--mesh-border); border-radius:9px; background:var(--mesh-surface); margin-bottom:20px; }
|
||||
.reach-table { min-width:520px; }
|
||||
.reach-map { width:100%; height:450px; border:1px solid var(--mesh-border); border-radius:9px; overflow:hidden; margin-bottom:20px; background:var(--mesh-stripe); }
|
||||
.reach-map-marker { width:34px; height:34px; border:2px solid white; border-radius:50%; display:flex; align-items:center; justify-content:center; color:white; font-size:10px; font-weight:800; line-height:1; text-shadow:0 1px 2px #000b; box-shadow:0 2px 8px #0003; }
|
||||
.reach-map-marker-source { font-size:14px; }
|
||||
.reach-gateway-panels { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:20px; }
|
||||
.reach-gateway-panel { min-width:0; overflow:auto; border:1px solid var(--mesh-border); border-radius:9px; background:var(--mesh-surface); margin-bottom:20px; }
|
||||
.reach-gateway-table { min-width:480px; }
|
||||
.reach-count-bar-cell { min-width:180px; }
|
||||
.reach-count-bar-track { position:relative; height:24px; border-radius:5px; background:#edf1f7; overflow:hidden; }
|
||||
.reach-count-bar-value span { background:#fffffff2; border-radius:3px; padding:0 5px; }
|
||||
.reach-count-bar-fill { height:100%; border-radius:inherit; background:var(--reach-bar-color,#22c55e); }
|
||||
.reach-count-bar-value { position:absolute; inset:0; display:flex; align-items:center; padding-left:9px; font:600 12px ui-monospace,monospace; color:#17263c; }
|
||||
.reach-muted { color:var(--mesh-muted); }
|
||||
.mesh-data-page .mesh-content .reach-heard-link { padding:2px 7px; font-weight:600; }
|
||||
.reliability-modal { display:none; position:fixed; inset:0; z-index:9999; align-items:center; justify-content:center; padding:16px; background:#17263c99; }
|
||||
.reliability-modal.open { display:flex; }
|
||||
.reliability-modal-panel { width:min(900px,100%); max-height:90dvh; overflow:auto; border:1px solid var(--mesh-border); border-radius:10px; background:var(--mesh-surface); padding:20px; box-shadow:0 16px 48px #17263c33; }
|
||||
.reliability-modal-header { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:18px; }
|
||||
.reliability-modal-title { font-size:15px; font-weight:600; overflow-wrap:anywhere; }
|
||||
.reliability-status-heard { color:#187346!important; font-weight:600; }
|
||||
.reliability-status-missed { color:#b23d2f!important; font-weight:600; }
|
||||
.reliability-status-skipped { color:var(--mesh-muted)!important; font-weight:600; }
|
||||
.reliability-row-skipped td { text-decoration:line-through; color:var(--mesh-muted)!important; }
|
||||
@media(max-width:1000px) { .reach-gateway-panels { grid-template-columns:minmax(0,1fr); gap:0; } }
|
||||
@media(max-width:600px) { .reach-controls { align-items:stretch; } .reach-search-label { width:100%; } .reach-search { flex-basis:100%; } .reach-summary { gap:10px; } .reach-metric { padding:16px; } .reach-metric-value { font-size:26px; } .reach-map { height:340px; } .reliability-modal-panel { padding:14px; } }
|
||||
.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;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<section class="reach-page">
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">GATEWAY DIAGNOSTICS</span><h1>Reliability</h1><p>See how consistently gateways hear packets from a selected node.</p></div><a class="mesh-secondary-button" href="/nodelist">All nodes ↗</a></header>
|
||||
<details class="reach-description"><summary>How reliability is calculated</summary><p>Review how often each gateway hears packets from a selected node. The report uses the
|
||||
<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></details>
|
||||
are shown in packet details but skipped from the calculation.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<section class="reach-panel">
|
||||
<form class="reach-controls" id="reach-search-form">
|
||||
@@ -94,19 +314,8 @@
|
||||
</a>
|
||||
</form>
|
||||
|
||||
<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-table-wrap" role="region" aria-label="Reliability report table" tabindex="0">
|
||||
<table class="table table-sm reach-table">
|
||||
<div class="reach-table-wrap">
|
||||
<table class="table table-dark table-sm table-striped reach-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Reliability Bands</th>
|
||||
@@ -123,9 +332,20 @@
|
||||
|
||||
<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" role="region" aria-label="Gateway reliability table" tabindex="0">
|
||||
<table class="table table-sm reach-table reach-gateway-table">
|
||||
<div class="reach-gateway-panel">
|
||||
<table class="table table-dark table-sm table-striped reach-table reach-gateway-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Gateway</th>
|
||||
@@ -141,8 +361,8 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="reach-gateway-panel" role="region" aria-label="Gateway reliability table" tabindex="0">
|
||||
<table class="table table-sm reach-table reach-gateway-table">
|
||||
<div class="reach-gateway-panel">
|
||||
<table class="table table-dark table-sm table-striped reach-table reach-gateway-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Gateway</th>
|
||||
@@ -160,16 +380,16 @@
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</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-secondary" type="button" onclick="closeGatewayPacketModal()">Close</button>
|
||||
<button class="btn btn-sm btn-outline-light" type="button" onclick="closeGatewayPacketModal()">Close</button>
|
||||
</div>
|
||||
<div class="reach-table-wrap" role="region" aria-label="Reliability report table" tabindex="0">
|
||||
<table class="table table-sm reach-table">
|
||||
<div class="reach-table-wrap">
|
||||
<table class="table table-dark table-sm table-striped reach-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Packet</th>
|
||||
@@ -541,7 +761,7 @@ async function loadReachReport(nodeId = reachNodeId) {
|
||||
<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"><span>${row.count}</span></div>
|
||||
<div class="reach-count-bar-value">${row.count}</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
+158
-64
@@ -1,29 +1,100 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-stats-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
.main-container { width:100%; }
|
||||
.summary-container { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:18px; margin-bottom:24px; }
|
||||
.summary-card { padding:20px 24px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; min-width:0; }
|
||||
.summary-card p { color:var(--mesh-muted); font-size:13px; margin:0 0 8px; }
|
||||
.summary-count { font-size:30px; font-weight:650; color:var(--mesh-primary); font-variant-numeric:tabular-nums; }
|
||||
.summary-card:nth-child(2) .summary-count { color:#198754; }
|
||||
.summary-card:nth-child(3) .summary-count { color:#236b4b; }
|
||||
.summary-card:nth-child(4) .summary-count { color:#497b55; }
|
||||
.stats-chart-grid { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:20px; }
|
||||
.card-section { min-width:0; display:flex; align-items:center; align-content:flex-start; flex-wrap:wrap; gap:10px; padding:20px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; }
|
||||
.section-header { width:100%; font-size:15px; font-weight:600; color:var(--mesh-text); padding-bottom:14px; margin:0 0 2px; border-bottom:1px solid var(--mesh-border); }
|
||||
.total-count { font-size:12px; color:var(--mesh-muted); margin-right:auto; }
|
||||
.chart { width:100%; min-width:0; height:340px; margin-top:8px; }
|
||||
#chartModal { display:none; position:fixed; inset:0; background:#17263c99; z-index:9999; justify-content:center; align-items:center; padding:16px; }
|
||||
#chartModal > div { position:relative; width:95%; max-width:1200px; height:85%; background:var(--mesh-surface); border-radius:10px; padding:48px 16px 16px; display:flex; flex-direction:column; }
|
||||
#chartModal #closeModal { position:absolute; top:10px; right:12px; font-size:22px; padding:0; width:32px; height:32px; line-height:1; }
|
||||
#modalChart { flex:1; min-height:0; width:100%; }
|
||||
@media(max-width:1000px) { .stats-chart-grid { grid-template-columns:minmax(0,1fr); } }
|
||||
@media(max-width:700px) { .summary-container { grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; } .summary-card { padding:16px; } .summary-count { font-size:26px; } .card-section { padding:14px; gap:8px; } .chart { height:320px; } }
|
||||
#packet_details {
|
||||
height: 95vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.main-container, .container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.card-section {
|
||||
background-color: #272b2f;
|
||||
border: 1px solid #474b4e;
|
||||
padding: 15px 20px;
|
||||
margin-bottom: 20px;
|
||||
border-radius: 10px;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
|
||||
.card-section:hover {
|
||||
background-color: #2f3338;
|
||||
}
|
||||
|
||||
.section-header {
|
||||
font-size: 16px;
|
||||
margin: 0 0 6px 0;
|
||||
font-weight: 500;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.main-header {
|
||||
font-size: 22px;
|
||||
margin-bottom: 20px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.chart {
|
||||
height: 400px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.total-count {
|
||||
color: #ccc;
|
||||
font-size: 14px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.expand-btn, .export-btn {
|
||||
margin-bottom: 8px;
|
||||
padding: 4px 8px;
|
||||
cursor: pointer;
|
||||
background-color: #444;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.expand-btn:hover { background-color: #666; }
|
||||
.export-btn:hover { background-color: #777; }
|
||||
|
||||
/* Summary cards at top */
|
||||
.summary-card {
|
||||
background-color: #1f2124;
|
||||
border: 1px solid #474b4e;
|
||||
padding: 10px 15px;
|
||||
margin-bottom: 15px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.summary-count {
|
||||
font-size: 18px;
|
||||
color: #66bb6a;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#channelSelect {
|
||||
margin-bottom: 8px;
|
||||
padding: 4px 6px;
|
||||
background:#444;
|
||||
color:#fff;
|
||||
border:none;
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.chart-filter {
|
||||
margin-bottom: 8px;
|
||||
padding: 4px 6px;
|
||||
background: #444;
|
||||
color: #fff;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
@@ -34,29 +105,30 @@
|
||||
|
||||
{% block body %}
|
||||
<div class="main-container">
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">NETWORK ANALYTICS</span><h1>Mesh statistics</h1><p>Explore packet history, device activity, and gateway distribution.</p></div><a class="mesh-secondary-button" href="/top">Top nodes ↗</a></header>
|
||||
<h2 class="main-header" data-translate-lang="mesh_stats_summary">
|
||||
Mesh Statistics - Summary (all available in Database)
|
||||
</h2>
|
||||
|
||||
<!-- Summary cards now fully driven by API + JS -->
|
||||
<div class="summary-container">
|
||||
<div class="summary-card">
|
||||
<div class="summary-container" style="display:flex; justify-content:space-between; gap:10px; margin-bottom:20px;">
|
||||
<div class="summary-card" style="flex:1;">
|
||||
<p data-translate-lang="total_nodes">Total Nodes</p>
|
||||
<div class="summary-count" id="summary_nodes">0</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-card" style="flex:1;">
|
||||
<p data-translate-lang="total_packets">Total Packets</p>
|
||||
<div class="summary-count" id="summary_packets">0</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-card" style="flex:1;">
|
||||
<p data-translate-lang="total_packets_seen">Total Packets Seen</p>
|
||||
<div class="summary-count" id="summary_seen">0</div>
|
||||
</div>
|
||||
<div class="summary-card">
|
||||
<div class="summary-card" style="flex:1;">
|
||||
<p data-translate-lang="total_gateways">Total Gateways</p>
|
||||
<div class="summary-count" id="summary_gateways">0</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="stats-chart-grid">
|
||||
<div class="card-section">
|
||||
<p class="section-header" data-translate-lang="daily_snapshot_packets_history">
|
||||
Daily Packet Snapshot History
|
||||
@@ -96,7 +168,7 @@
|
||||
<p class="section-header" data-translate-lang="packet_types_last_24h">
|
||||
Packet Types - Last 24 Hours
|
||||
</p>
|
||||
<select id="channelSelect" aria-label="Packet type channel">
|
||||
<select id="channelSelect">
|
||||
<option value="" data-translate-lang="all_channels">All Channels</option>
|
||||
</select>
|
||||
<button class="expand-btn" data-chart="chart_packet_types" data-translate-lang="expand_chart">Expand Chart</button>
|
||||
@@ -179,13 +251,17 @@
|
||||
<div id="chart_gateway_firmware" class="chart"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal for expanded charts -->
|
||||
<div id="chartModal" role="dialog" aria-modal="true" aria-label="Expanded chart">
|
||||
<div>
|
||||
<button id="closeModal" type="button" aria-label="Close expanded chart">×</button>
|
||||
<div id="modalChart"></div>
|
||||
<div id="chartModal" style="display:none; position:fixed; top:0; left:0; width:100%; height:100%;
|
||||
background:rgba(0,0,0,0.7); z-index:1000; justify-content:center; align-items:center;">
|
||||
<div style="position:relative; width:80%; max-width:1000px; height:80%;
|
||||
background:#272b2f; border-radius:10px; padding:10px; display:flex; flex-direction:column;">
|
||||
|
||||
<button id="closeModal" style="position:absolute; top:10px; right:10px; z-index:1010;
|
||||
background:#ff4c4c; border:none; color:white; font-size:24px; width:36px; height:36px;
|
||||
border-radius:50%; cursor:pointer;">×</button>
|
||||
<div id="modalChart" style="flex:1; width:100%; height:100%;"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -292,23 +368,23 @@ function filterSnapshotsByRange(data, rangeValue){
|
||||
function renderChart(domId,data,type,color){
|
||||
const el=document.getElementById(domId);
|
||||
if(!el) return;
|
||||
const chart=initMeshChart(el);
|
||||
const chart=echarts.init(el);
|
||||
const periods=data.map(d=>(d.period??d.period===0)?d.period.toString():'');
|
||||
const counts=data.map(d=>d.count??d.packet_count??0);
|
||||
chart.setOption({
|
||||
backgroundColor:'#ffffff',
|
||||
backgroundColor:'#272b2f',
|
||||
tooltip:{trigger:'axis'},
|
||||
grid:{left:'6%', right:'6%', bottom:'18%'},
|
||||
xAxis:{
|
||||
type:'category',
|
||||
data:periods,
|
||||
axisLine:{lineStyle:{color:'#c3cfdf'}},
|
||||
axisLabel:{rotate:45,color:'#64748b'}
|
||||
axisLine:{lineStyle:{color:'#aaa'}},
|
||||
axisLabel:{rotate:45,color:'#ccc'}
|
||||
},
|
||||
yAxis:{
|
||||
type:'value',
|
||||
axisLine:{lineStyle:{color:'#c3cfdf'}},
|
||||
axisLabel:{color:'#64748b'}
|
||||
axisLine:{lineStyle:{color:'#aaa'}},
|
||||
axisLabel:{color:'#ccc'}
|
||||
},
|
||||
series:[{
|
||||
data:counts,
|
||||
@@ -324,10 +400,10 @@ function renderChart(domId,data,type,color){
|
||||
function renderPieChart(elId,data,name){
|
||||
const el=document.getElementById(elId);
|
||||
if(!el) return;
|
||||
const chart=initMeshChart(el);
|
||||
const chart=echarts.init(el);
|
||||
const top20=prepareTopN(data,20);
|
||||
chart.setOption({
|
||||
backgroundColor:"#ffffff",
|
||||
backgroundColor:"#272b2f",
|
||||
tooltip:{
|
||||
trigger:"item",
|
||||
formatter: params=>`${params.name}: ${Math.round(params.percent)}% (${params.value})`
|
||||
@@ -340,13 +416,13 @@ function renderPieChart(elId,data,name){
|
||||
avoidLabelOverlap:true,
|
||||
itemStyle:{
|
||||
borderRadius:6,
|
||||
borderColor:"#ffffff",
|
||||
borderColor:"#272b2f",
|
||||
borderWidth:2
|
||||
},
|
||||
label:{
|
||||
show:true,
|
||||
formatter:"{b}\n{d}%",
|
||||
color:"#64748b",
|
||||
color:"#ccc",
|
||||
fontSize:10
|
||||
},
|
||||
labelLine:{
|
||||
@@ -395,28 +471,28 @@ function makeTelemetryLine(name, color, seriesData) {
|
||||
function renderDailySnapshotPacketsChart(domId,data){
|
||||
const el=document.getElementById(domId);
|
||||
if(!el) return;
|
||||
const chart=echarts.getInstanceByDom(el) || initMeshChart(el);
|
||||
const chart=echarts.getInstanceByDom(el) || echarts.init(el);
|
||||
const labels=data.map(d=>d.date||"");
|
||||
const packetCounts=data.map(d=>d.packet_count??0);
|
||||
|
||||
chart.setOption({
|
||||
backgroundColor:'#ffffff',
|
||||
backgroundColor:'#272b2f',
|
||||
tooltip:{trigger:'axis'},
|
||||
legend:{
|
||||
data:['Packets'],
|
||||
textStyle:{color:'#64748b'}
|
||||
textStyle:{color:'#ccc'}
|
||||
},
|
||||
grid:{left:'6%', right:'6%', bottom:'18%'},
|
||||
xAxis:{
|
||||
type:'category',
|
||||
data:labels,
|
||||
axisLine:{lineStyle:{color:'#c3cfdf'}},
|
||||
axisLabel:{rotate:45,color:'#64748b'}
|
||||
axisLine:{lineStyle:{color:'#aaa'}},
|
||||
axisLabel:{rotate:45,color:'#ccc'}
|
||||
},
|
||||
yAxis:{
|
||||
type:'value',
|
||||
axisLine:{lineStyle:{color:'#c3cfdf'}},
|
||||
axisLabel:{color:'#64748b'}
|
||||
axisLine:{lineStyle:{color:'#aaa'}},
|
||||
axisLabel:{color:'#ccc'}
|
||||
},
|
||||
series:[
|
||||
makeTelemetryLine("Packets", "rgba(255,214,82,1)", packetCounts)
|
||||
@@ -428,29 +504,29 @@ function renderDailySnapshotPacketsChart(domId,data){
|
||||
function renderDailySnapshotNodesGatewaysChart(domId,data){
|
||||
const el=document.getElementById(domId);
|
||||
if(!el) return;
|
||||
const chart=echarts.getInstanceByDom(el) || initMeshChart(el);
|
||||
const chart=echarts.getInstanceByDom(el) || echarts.init(el);
|
||||
const labels=data.map(d=>d.date||"");
|
||||
const nodeCounts=data.map(d=>d.node_count??0);
|
||||
const gatewayCounts=data.map(d=>d.gateway_count??0);
|
||||
|
||||
chart.setOption({
|
||||
backgroundColor:'#ffffff',
|
||||
backgroundColor:'#272b2f',
|
||||
tooltip:{trigger:'axis'},
|
||||
legend:{
|
||||
data:['Nodes','Gateways'],
|
||||
textStyle:{color:'#64748b'}
|
||||
textStyle:{color:'#ccc'}
|
||||
},
|
||||
grid:{left:'6%', right:'6%', bottom:'18%'},
|
||||
xAxis:{
|
||||
type:'category',
|
||||
data:labels,
|
||||
axisLine:{lineStyle:{color:'#c3cfdf'}},
|
||||
axisLabel:{rotate:45,color:'#64748b'}
|
||||
axisLine:{lineStyle:{color:'#aaa'}},
|
||||
axisLabel:{rotate:45,color:'#ccc'}
|
||||
},
|
||||
yAxis:{
|
||||
type:'value',
|
||||
axisLine:{lineStyle:{color:'#c3cfdf'}},
|
||||
axisLabel:{color:'#64748b'}
|
||||
axisLine:{lineStyle:{color:'#aaa'}},
|
||||
axisLabel:{color:'#ccc'}
|
||||
},
|
||||
series:[
|
||||
makeTelemetryLine("Nodes", "rgba(79,155,255,1)", nodeCounts),
|
||||
@@ -526,11 +602,11 @@ async function init(){
|
||||
// Hourly all ports
|
||||
const hourlyAllData=await fetchStats('hour',24);
|
||||
updateTotalCount('total_hourly_all',hourlyAllData);
|
||||
chartHourlyAll=renderChart('chart_hourly_all',hourlyAllData,'bar','#168e84');
|
||||
chartHourlyAll=renderChart('chart_hourly_all',hourlyAllData,'bar','#03dac6');
|
||||
|
||||
// Hourly per port
|
||||
const portnums=[1,3,4,67,70,71];
|
||||
const colors=['#ff5722','#2196f3','#9c27b0','#b88a15','#795548','#4caf50'];
|
||||
const colors=['#ff5722','#2196f3','#9c27b0','#ffeb3b','#795548','#4caf50'];
|
||||
const domIds=['chart_portnum_1','chart_portnum_3','chart_portnum_4','chart_portnum_67','chart_portnum_70','chart_portnum_71'];
|
||||
const totalIds=['total_portnum_1','total_portnum_3','total_portnum_4','total_portnum_67','total_portnum_70','total_portnum_71'];
|
||||
|
||||
@@ -606,8 +682,26 @@ async function init(){
|
||||
}
|
||||
|
||||
window.addEventListener('resize',()=>{
|
||||
document.querySelectorAll('.chart').forEach(el => echarts.getInstanceByDom(el)?.resize());
|
||||
modalChart?.resize();
|
||||
[
|
||||
chartHourlyAll,
|
||||
chartPortnum1,
|
||||
chartPortnum3,
|
||||
chartPortnum4,
|
||||
chartPortnum67,
|
||||
chartPortnum70,
|
||||
chartPortnum71,
|
||||
chartDailySnapshotPackets,
|
||||
chartDailySnapshotNodesGateways,
|
||||
chartDailyAll,
|
||||
chartDailyPortnum1,
|
||||
chartHwModel,
|
||||
chartRole,
|
||||
chartChannel,
|
||||
chartGatewayChannel,
|
||||
chartGatewayRole,
|
||||
chartGatewayFirmware,
|
||||
chartPacketTypes
|
||||
].forEach(c=>c?.resize());
|
||||
});
|
||||
|
||||
const modal=document.getElementById("chartModal");
|
||||
@@ -620,7 +714,7 @@ document.querySelectorAll(".expand-btn").forEach(btn=>{
|
||||
const sourceChart=echarts.getInstanceByDom(document.getElementById(chartId));
|
||||
if(!sourceChart)return;
|
||||
modal.style.display="flex";
|
||||
modalChart=initMeshChart(modalChartEl);
|
||||
modalChart=echarts.init(modalChartEl);
|
||||
modalChart.setOption(sourceChart.getOption());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
<style>
|
||||
:root {
|
||||
color-scheme:light;
|
||||
--mesh-primary:#187346;
|
||||
--mesh-primary-dark:#0f5132;
|
||||
--mesh-primary-rgb:24,115,70;
|
||||
--mesh-brand:#187346;
|
||||
--mesh-brand-deep:#0f5132;
|
||||
--mesh-surface:#ffffff;
|
||||
--mesh-text:#243247;
|
||||
--mesh-soft:#eaf5ee;
|
||||
--mesh-hover:#dceee2;
|
||||
--mesh-border:#dce7df;
|
||||
--mesh-page:#f5f9f6;
|
||||
--mesh-stripe:#f7faf8;
|
||||
--mesh-muted:#64748b;
|
||||
--mesh-chat-stripe:#eef6f0;
|
||||
--mesh-pulse-soft:#edf8f0;
|
||||
--mesh-pulse-peak:#ccebd7;
|
||||
--mesh-pulse-mid:#e2f3e8;
|
||||
}
|
||||
[data-bs-theme="dark"] {
|
||||
color-scheme:dark;
|
||||
--mesh-primary:#80cfa3;
|
||||
--mesh-primary-dark:#a3e3be;
|
||||
--mesh-primary-rgb:128,207,163;
|
||||
--mesh-brand:#14532d;
|
||||
--mesh-brand-deep:#0c3a1f;
|
||||
--mesh-surface:#18231e;
|
||||
--mesh-text:#e2ece5;
|
||||
--mesh-soft:#203c2b;
|
||||
--mesh-hover:#294c36;
|
||||
--mesh-border:#34483c;
|
||||
--mesh-page:#101914;
|
||||
--mesh-stripe:#1c2a22;
|
||||
--mesh-muted:#9faea6;
|
||||
--mesh-chat-stripe:#203227;
|
||||
--mesh-pulse-soft:#203c2b;
|
||||
--mesh-pulse-peak:#356b49;
|
||||
--mesh-pulse-mid:#294c36;
|
||||
--bs-link-color:var(--mesh-primary);
|
||||
--bs-link-color-rgb:var(--mesh-primary-rgb);
|
||||
--bs-link-hover-color:var(--mesh-primary-dark);
|
||||
--bs-link-hover-color-rgb:163,227,190;
|
||||
}
|
||||
body { background:var(--mesh-page); color:var(--mesh-text); }
|
||||
.mesh-theme-toggle { flex-shrink:0; display:inline-flex; align-items:center; justify-content:center; width:34px; height:34px; border:1px solid #ffffff70; border-radius:6px; background:transparent; color:white; font:22px/1 system-ui,sans-serif; cursor:pointer; }
|
||||
.mesh-header .mesh-theme-toggle { margin-left:auto; }
|
||||
.mesh-theme-toggle:hover { background:#ffffff20; }
|
||||
.mesh-theme-toggle:focus-visible { outline:2px solid white; outline-offset:3px; }
|
||||
@media(max-width:1000px) { .mesh-header .mesh-menu-toggle { margin-left:auto; } .mesh-header .mesh-theme-toggle { margin-left:12px; } .mesh-header #site-menu { order:4; } }
|
||||
[data-bs-theme="dark"] :is(.chat-status,.chat-details,.chat-channel,.chat-status[data-state="paused"],.chat-status[data-state="loading"],.good-x) { background:var(--mesh-soft); color:var(--mesh-primary); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.chat-status[data-state="error"],.bad-x) { background:#472a24; color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .ok-x { background:#453820; color:#f1d38a; }
|
||||
[data-bs-theme="dark"] .chat-details:hover { background:var(--mesh-hover); color:var(--mesh-primary-dark); }
|
||||
[data-bs-theme="dark"] .chat-nick { filter:brightness(1.4) saturate(.8); }
|
||||
[data-bs-theme="dark"] :is(.summary-card:nth-child(2) .summary-count,.summary-card:nth-child(3) .summary-count,.summary-card:nth-child(4) .summary-count,.mesh-metric:nth-child(2) strong,.mesh-metric:nth-child(3) strong,.reach-metric:nth-child(2) .reach-metric-value) { color:var(--mesh-primary); }
|
||||
[data-bs-theme="dark"] :is(.reliability-status-heard) { color:#8fd7aa!important; }
|
||||
[data-bs-theme="dark"] .reliability-status-missed { color:#ffb4a6!important; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-value span { color:#17263c; }
|
||||
[data-bs-theme="dark"] .leaflet-tile-pane { filter:invert(1) hue-rotate(180deg) brightness(.85) saturate(.75); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-container,.leaflet-control-layers,.leaflet-bar a,.leaflet-popup-content-wrapper,.leaflet-popup-tip,.leaflet-tooltip,.leaflet-control-attribution,.leaflet-control-scale-line,#unmapped-packets,#legend,#node-info,.legend) { background:var(--mesh-surface); color:var(--mesh-text); border-color:var(--mesh-border); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-control-layers label,.leaflet-popup-close-button,#unmapped-packets h3,.unmapped-node,.blinking-tooltip,.legend) { color:var(--mesh-text); }
|
||||
[data-bs-theme="dark"] :is(.leaflet-bar a:hover,.leaflet-control-layers-expanded) { background:var(--mesh-stripe); }
|
||||
[data-bs-theme="dark"] :is(.unmapped-empty,.reach-muted) { color:var(--mesh-muted); }
|
||||
[data-bs-theme="dark"] :is(.source-marker,.reach-map-marker) { color:white; }
|
||||
[data-bs-theme="dark"] .qr-image { background:white; }
|
||||
[data-bs-theme="dark"] :is(#traceroute-error,#map-load-status,.text-danger) { color:#ffb4a6; }
|
||||
[data-bs-theme="dark"] .reach-count-bar-track { background:var(--mesh-soft); }
|
||||
</style>
|
||||
+63
-35
@@ -1,49 +1,87 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-top-page{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
.top-container { width:100%; }
|
||||
.filter-bar { display:flex; align-items:center; flex-wrap:wrap; gap:12px; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; padding:16px; margin-bottom:18px; }
|
||||
.filter-bar > div { display:flex; align-items:center; flex-wrap:wrap; gap:10px; }
|
||||
.filter-bar label { color:var(--mesh-muted); font-size:13px; }
|
||||
#channelFilter { width:200px; }
|
||||
.top-count { color:var(--mesh-muted); font-size:13px; margin-bottom:14px; }
|
||||
#node-count { font-weight:650; color:var(--mesh-primary); }
|
||||
#nodesTable tbody tr { cursor:pointer; }
|
||||
#nodesTable td:nth-child(n+4) { font-variant-numeric:tabular-nums; }
|
||||
.good-x,.ok-x,.bad-x { display:inline-block; padding:3px 8px; border-radius:5px; font-weight:600; font-size:12px; }
|
||||
.good-x { background:#e8f5ee; color:#187346; }
|
||||
.ok-x { background:#fff4d9; color:#8a6200; }
|
||||
.bad-x { background:#fff0ed; color:#b23d2f; }
|
||||
.pagination { display:flex; align-items:center; justify-content:center; gap:16px; margin:20px 0 0; }
|
||||
#pageInfo { font-size:12px; color:var(--mesh-muted); }
|
||||
@media(max-width:700px) { #channelFilter { width:180px; } }
|
||||
body { background-color: #121212; color: #ddd; }
|
||||
h1 { text-align: center; margin-top: 20px; color: #fff; }
|
||||
|
||||
.top-container {
|
||||
max-width: 1100px;
|
||||
margin: 25px auto;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.filter-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
.filter-bar select {
|
||||
background-color: #1f2327;
|
||||
border: 1px solid #444;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
table th, table td {
|
||||
padding: 12px;
|
||||
border: 1px solid #444;
|
||||
text-align: left;
|
||||
color: #ddd;
|
||||
}
|
||||
|
||||
table th { background-color: #333; }
|
||||
|
||||
table tbody tr:nth-child(odd) { background-color: #272b2f; }
|
||||
table tbody tr:nth-child(even) { background-color: #212529; }
|
||||
table tbody tr:hover { background-color: #555; cursor: pointer; }
|
||||
|
||||
.node-link {
|
||||
color: #9fd4ff;
|
||||
text-decoration: none;
|
||||
}
|
||||
.node-link:hover { text-decoration: underline; }
|
||||
|
||||
.good-x { color: #81ff81; font-weight: bold; }
|
||||
.ok-x { color: #e8e86d; font-weight: bold; }
|
||||
.bad-x { color: #ff6464; font-weight: bold; }
|
||||
|
||||
.pagination {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">TRAFFIC LEADERBOARD</span><h1 data-translate-lang="top_traffic_nodes">Top nodes</h1><p>Compare packets sent and gateway observations over the last 24 hours.</p></div><a class="mesh-secondary-button" href="/stats">View statistics ↗</a></header>
|
||||
<h1 data-translate-lang="top_traffic_nodes">Top Nodes Traffic</h1>
|
||||
|
||||
<div class="top-container">
|
||||
|
||||
<div class="filter-bar">
|
||||
<div>
|
||||
<label for="channelFilter" data-translate-lang="channel">Channel:</label>
|
||||
<label data-translate-lang="channel">Channel:</label>
|
||||
<select id="channelFilter"></select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="top-count">
|
||||
<div style="margin-bottom:10px;font-weight:bold;">
|
||||
<span data-translate-lang="showing_nodes">Showing</span>
|
||||
<span id="node-count">0</span>
|
||||
<span data-translate-lang="nodes_suffix">nodes</span>
|
||||
</div>
|
||||
|
||||
<div class="data-table-wrap" role="region" aria-label="Top nodes traffic table" tabindex="0">
|
||||
<table id="nodesTable">
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -57,11 +95,10 @@
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="pagination" aria-label="Leaderboard pagination">
|
||||
<div class="pagination">
|
||||
<button id="prevPage" class="btn btn-sm btn-secondary">Prev</button>
|
||||
<span id="pageInfo" role="status"></span>
|
||||
<span id="pageInfo"></span>
|
||||
<button id="nextPage" class="btn btn-sm btn-secondary">Next</button>
|
||||
</div>
|
||||
|
||||
@@ -148,15 +185,6 @@ async function renderTable() {
|
||||
const data = await res.json();
|
||||
|
||||
totalRows = data.total || 0;
|
||||
if (!(data.nodes || []).length) {
|
||||
const row = document.createElement("tr");
|
||||
const cell = document.createElement("td");
|
||||
cell.colSpan = 6;
|
||||
cell.className = "data-empty";
|
||||
cell.textContent = "No node traffic found for this channel.";
|
||||
row.append(cell);
|
||||
tbody.append(row);
|
||||
}
|
||||
|
||||
for (const n of data.nodes || []) {
|
||||
const tr = document.createElement("tr");
|
||||
|
||||
@@ -1,35 +1,75 @@
|
||||
{% extends "base.html" %}
|
||||
{% block theme %}light{% endblock %}
|
||||
{% block body_class %}mesh-data-page mesh-traceroute-page{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block css %}
|
||||
{% include "data-page-styles.html" %}
|
||||
<style>
|
||||
#traceroute-graph-wrap { position:relative; background:var(--mesh-surface); border:1px solid var(--mesh-border); border-radius:9px; overflow:hidden; }
|
||||
#traceroute-graph { width:100%; height:clamp(460px,calc(100dvh - 280px),900px); }
|
||||
#traceroute-legend { position:absolute; right:16px; bottom:16px; z-index:2; display:grid; gap:9px; padding:14px 16px; color:var(--mesh-muted); background:#fffffff2; border:1px solid var(--mesh-border); border-radius:7px; font-size:12px; box-shadow:0 2px 8px #17263c08; pointer-events:none; }
|
||||
.traceroute-legend-row { display:grid; grid-template-columns:34px auto; align-items:center; gap:10px; }
|
||||
.traceroute-legend-line { height:0; border-top:3px solid var(--line-color); }
|
||||
.traceroute-legend-line.muted { border-top-width:2px; opacity:.55; }
|
||||
.traceroute-legend-line.dashed { border-top-style:dashed; }
|
||||
#traceroute-meta { display:flex; align-items:center; flex-wrap:wrap; gap:12px; padding:14px 18px; border:1px solid var(--mesh-border); border-radius:9px; background:var(--mesh-surface); margin-bottom:18px; color:var(--mesh-muted); font-size:13px; }
|
||||
#traceroute-title { color:var(--mesh-primary); font-weight:600; }
|
||||
#traceroute-error { color:#b23d2f; }
|
||||
.traceroute-help { margin-left:auto; font-size:12px; }
|
||||
@media(max-width:700px) { #traceroute-graph { height:500px; } #traceroute-legend { left:12px; right:auto; bottom:12px; font-size:11px; padding:12px; } .traceroute-help { width:100%; margin:0; } }
|
||||
#traceroute-graph {
|
||||
width: 100%;
|
||||
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;
|
||||
}
|
||||
|
||||
#traceroute-error {
|
||||
color: #ff6b6b;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<header class="data-heading"><div><span class="mesh-eyebrow">ROUTE EXPLORER</span><h1>Traceroute</h1><p>Explore forward paths, reported return routes, and the nodes along the way.</p></div><a class="mesh-secondary-button" href="/firehose">Live packets ↗</a></header>
|
||||
<div id="traceroute-meta">
|
||||
<div><b>Traceroute</b> <span id="traceroute-title"></span></div>
|
||||
<div id="traceroute-error" role="status"></div>
|
||||
<span class="traceroute-help">Drag nodes to rearrange · Scroll to zoom</span>
|
||||
<div id="traceroute-error"></div>
|
||||
</div>
|
||||
<div id="traceroute-graph-wrap">
|
||||
<div id="traceroute-graph"></div>
|
||||
@@ -51,7 +91,7 @@
|
||||
|
||||
<script>
|
||||
const el = document.getElementById("traceroute-graph");
|
||||
const chart = initMeshChart(el);
|
||||
const chart = echarts.init(el);
|
||||
|
||||
function packetIdFromPath() {
|
||||
const parts = window.location.pathname.split("/").filter(Boolean);
|
||||
@@ -184,10 +224,7 @@ async function loadTraceroute() {
|
||||
itemStyle: { color },
|
||||
label: {
|
||||
show: true,
|
||||
color: "#334155",
|
||||
position: "bottom",
|
||||
textBorderColor: "#ffffff",
|
||||
textBorderWidth: 3,
|
||||
color: "#e7eef7",
|
||||
fontWeight: "bold"
|
||||
},
|
||||
tooltip: {
|
||||
@@ -201,7 +238,7 @@ async function loadTraceroute() {
|
||||
|
||||
const option = {
|
||||
backgroundColor: "transparent",
|
||||
tooltip: { trigger: "item", renderMode: "richText" },
|
||||
tooltip: { trigger: "item" },
|
||||
series: [
|
||||
{
|
||||
type: "graph",
|
||||
@@ -222,10 +259,7 @@ async function loadTraceroute() {
|
||||
chart.setOption(option);
|
||||
}
|
||||
|
||||
loadTraceroute().catch(error => {
|
||||
console.error("Failed to load traceroute:", error);
|
||||
document.getElementById("traceroute-error").textContent = "Unable to load traceroute. Reload to try again.";
|
||||
});
|
||||
loadTraceroute();
|
||||
window.addEventListener("resize", () => chart.resize());
|
||||
</script>
|
||||
{% endblock %}
|
||||
+8
-12
@@ -214,14 +214,14 @@ routes = web.RouteTableDef()
|
||||
|
||||
|
||||
@routes.get("/")
|
||||
@routes.get("/index")
|
||||
@routes.get("/index.html")
|
||||
async def index(request):
|
||||
"""Render the network dashboard as the home page."""
|
||||
return web.Response(
|
||||
text=env.get_template("index.html").render(),
|
||||
content_type="text/html",
|
||||
)
|
||||
"""
|
||||
Redirect root URL '/' to the page specified in CONFIG['site']['starting'].
|
||||
Defaults to '/map' if not set.
|
||||
"""
|
||||
# Get the starting page from config
|
||||
starting_url = CONFIG["site"].get("starting", "/map") # default to /map if not set
|
||||
raise web.HTTPFound(location=starting_url)
|
||||
|
||||
|
||||
# redirect for backwards compatibility
|
||||
@@ -232,6 +232,7 @@ async def redirect_packet_list(request):
|
||||
|
||||
|
||||
# Generic static HTML route
|
||||
@routes.get("/{page}")
|
||||
async def serve_page(request):
|
||||
"""Serve static HTML pages from meshview/static."""
|
||||
page = request.match_info["page"]
|
||||
@@ -274,7 +275,6 @@ async def net(request):
|
||||
|
||||
|
||||
@routes.get("/map")
|
||||
@routes.get("/map.html")
|
||||
async def map(request):
|
||||
template = env.get_template("map.html")
|
||||
return web.Response(text=template.render(), content_type="text/html")
|
||||
@@ -481,10 +481,6 @@ async def graph_traceroute(request):
|
||||
)
|
||||
|
||||
|
||||
# Register the static-page fallback after named pages so it cannot shadow them.
|
||||
routes.get("/{page}")(serve_page)
|
||||
|
||||
|
||||
async def run_server():
|
||||
"""Start the aiohttp web server after migrations are complete."""
|
||||
# Wait for database migrations to complete before starting web server
|
||||
|
||||
@@ -730,6 +730,7 @@ async def api_config(request):
|
||||
"language": get_str(site, "language", "en"),
|
||||
"title": get_str(site, "title", ""),
|
||||
"message": get_str(site, "message", ""),
|
||||
"starting": get_str(site, "starting", "/chat"),
|
||||
"nodes": get_bool(site, "nodes", True),
|
||||
"chat": get_bool(site, "chat", True),
|
||||
"everything": get_bool(site, "everything", True),
|
||||
@@ -738,7 +739,6 @@ async def api_config(request):
|
||||
"net": get_bool(site, "net", True),
|
||||
"map": get_bool(site, "map", True),
|
||||
"top": get_bool(site, "top", True),
|
||||
"api": get_bool(site, "api", True),
|
||||
"map_top_left_lat": get_float(site, "map_top_left_lat", 39.0),
|
||||
"map_top_left_lon": get_float(site, "map_top_left_lon", -123.0),
|
||||
"map_bottom_right_lat": get_float(site, "map_bottom_right_lat", 36.0),
|
||||
|
||||
+3
-2
@@ -31,6 +31,9 @@ title = Bay Area Mesh
|
||||
# A brief message shown on the homepage.
|
||||
message = Real time data from around the bay area and beyond.
|
||||
|
||||
# Starting URL when loading the index page.
|
||||
starting = /chat
|
||||
|
||||
# Enable or disable site features (as strings: "True" or "False").
|
||||
nodes = True
|
||||
conversations = True
|
||||
@@ -40,8 +43,6 @@ stats = True
|
||||
net = True
|
||||
map = True
|
||||
top = True
|
||||
# Show the API documentation link in the navigation bar (default: True).
|
||||
api = True
|
||||
|
||||
# Map boundaries (used for the map view).
|
||||
map_top_left_lat = 39
|
||||
|
||||
@@ -1,135 +0,0 @@
|
||||
// Build the static API reference from the canonical Markdown, without runtime dependencies.
|
||||
// Supports the headings, paragraphs, lists, links, rules, and fenced code used by this reference.
|
||||
import { readFileSync, writeFileSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const source = new URL('../docs/API_Documentation.md', import.meta.url);
|
||||
const output = new URL('../meshview/static/api.html', import.meta.url);
|
||||
const markdown = readFileSync(source, 'utf8');
|
||||
const themeStyles = readFileSync(new URL('../meshview/templates/theme-styles.html', import.meta.url), 'utf8');
|
||||
const escape = text => text.replace(/[&<>"']/g, char => ({
|
||||
'&':'&', '<':'<', '>':'>', '"':'"', "'":'''
|
||||
}[char]));
|
||||
const slug = text => text.toLowerCase().replace(/`/g, '').replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
|
||||
function inline(text) {
|
||||
const tokens = /`([^`]+)`|\[([^\]]+)\]\(([^)]+)\)|\*\*([^*]+)\*\*/g;
|
||||
let html = '', cursor = 0;
|
||||
for (const match of text.matchAll(tokens)) {
|
||||
html += escape(text.slice(cursor, match.index));
|
||||
if (match[1] !== undefined) html += `<code>${escape(match[1])}</code>`;
|
||||
else if (match[2] !== undefined && /^(#|\/|https?:\/\/)/.test(match[3])) {
|
||||
html += `<a href="${escape(match[3])}">${escape(match[2])}</a>`;
|
||||
} else if (match[4] !== undefined) html += `<strong>${escape(match[4])}</strong>`;
|
||||
else html += escape(match[0]);
|
||||
cursor = match.index + match[0].length;
|
||||
}
|
||||
return html + escape(text.slice(cursor));
|
||||
}
|
||||
|
||||
const endpoints = [];
|
||||
const blocks = [];
|
||||
const lines = markdown.split('\n');
|
||||
let sectionOpen = false;
|
||||
for (let i = 0; i < lines.length;) {
|
||||
const line = lines[i];
|
||||
if (!line.trim()) { i++; continue; }
|
||||
if (line.startsWith('```')) {
|
||||
const language = line.slice(3).trim(); const code = []; i++;
|
||||
while (i < lines.length && !lines[i].startsWith('```')) code.push(lines[i++]);
|
||||
if (i === lines.length) throw new Error('Unclosed code fence');
|
||||
if (language === 'json') JSON.parse(code.join('\n'));
|
||||
blocks.push(`<pre><code class="language-${escape(language)}">${escape(code.join('\n'))}</code></pre>`);
|
||||
i++; continue;
|
||||
}
|
||||
const heading = line.match(/^(#{1,3})\s+(.+)$/);
|
||||
if (heading) {
|
||||
if (sectionOpen) { blocks.push('</section>'); sectionOpen = false; }
|
||||
const level = heading[1].length; const text = heading[2];
|
||||
if (level === 3 && text.startsWith('GET ')) {
|
||||
const id = slug(text); endpoints.push({text:text.replace(/`/g, ''),id});
|
||||
blocks.push(`<section class="endpoint" id="${id}"><h3><span class="method">GET</span> ${inline(text.slice(4))}</h3>`);
|
||||
sectionOpen = true;
|
||||
} else blocks.push(`<h${level} id="${slug(text)}">${inline(text)}</h${level}>`);
|
||||
i++; continue;
|
||||
}
|
||||
if (/^---+$/.test(line)) { blocks.push('<hr>'); i++; continue; }
|
||||
if (/^- /.test(line)) {
|
||||
const items = [];
|
||||
while (i < lines.length && /^- /.test(lines[i])) {
|
||||
let item = lines[i++].slice(2);
|
||||
while (i < lines.length && /^\s+\S/.test(lines[i])) item += ` ${lines[i++].trim()}`;
|
||||
items.push(`<li>${inline(item)}</li>`);
|
||||
}
|
||||
blocks.push(`<ul>${items.join('')}</ul>`); continue;
|
||||
}
|
||||
const paragraph = [line]; i++;
|
||||
while (i < lines.length && lines[i].trim() && !/^(#{1,3} |```|- |---+$)/.test(lines[i])) paragraph.push(lines[i++]);
|
||||
blocks.push(`<p>${inline(paragraph.join(' '))}</p>`);
|
||||
}
|
||||
if (sectionOpen) blocks.push('</section>');
|
||||
const index = endpoints.map(({text,id}) => `<li><a href="#${id}">${escape(text)}</a></li>`).join('');
|
||||
writeFileSync(output, `<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Meshview API Reference</title>
|
||||
<script src="/static/theme.js"></script>
|
||||
<link rel="icon" type="image/svg+xml" href="/static/meshview-icon.svg">
|
||||
<style>
|
||||
:root { color-scheme:light; --primary:var(--mesh-primary); --border:var(--mesh-border); }
|
||||
* { box-sizing:border-box; }
|
||||
html { scroll-padding-top:80px; }
|
||||
body { margin:0; background:var(--mesh-page); color:var(--mesh-text); font:14px/1.7 system-ui,-apple-system,"Segoe UI",sans-serif; }
|
||||
a { color:var(--primary); }
|
||||
a:hover { color:var(--mesh-primary-dark); }
|
||||
header { background:var(--mesh-brand); color:white; position:sticky; top:0; z-index:2; box-shadow:0 2px 8px #174b2d18; }
|
||||
.header-inner { max-width:1180px; margin:auto; min-height:56px; display:flex; align-items:center; gap:12px; padding:8px 24px; }
|
||||
header img { width:32px; height:32px; }
|
||||
header a { color:white; text-decoration:none; }
|
||||
header a:hover { color:white; text-decoration:underline; }
|
||||
.brand { font-size:18px; font-weight:700; display:flex; align-items:center; gap:10px; }
|
||||
.home-link { margin-left:auto; font-size:13px; }
|
||||
main { max-width:1180px; margin:auto; padding:28px 24px 60px; min-width:0; }
|
||||
h1 { font-size:28px; margin:0 0 16px; } h2 { font-size:21px; margin:32px 0 14px; } h3 { font-size:17px; margin:0 0 16px; }
|
||||
p,li { overflow-wrap:anywhere; }
|
||||
code { font:12px/1.7 ui-monospace,Consolas,monospace; color:var(--mesh-primary); background:var(--mesh-soft); border-radius:4px; padding:2px 5px; overflow-wrap:anywhere; }
|
||||
pre { background:var(--mesh-stripe); border:1px solid var(--border); border-radius:7px; padding:16px; overflow:auto; }
|
||||
pre code { background:none; padding:0; white-space:pre; color:var(--mesh-text); }
|
||||
h3 code { font-size:15px; }
|
||||
.endpoint { background:var(--mesh-surface); border:1px solid var(--border); border-radius:9px; padding:24px; margin-bottom:22px; scroll-margin-top:12px; min-width:0; }
|
||||
.method { display:inline-block; background:var(--mesh-brand); color:white; font-size:11px; padding:3px 8px; border-radius:5px; margin-right:5px; }
|
||||
hr { border:0; border-top:1px solid var(--border); margin:24px 0; }
|
||||
.api-index { background:var(--mesh-surface); border:1px solid var(--border); border-radius:9px; padding:16px 20px; margin-bottom:24px; }
|
||||
.api-index summary { color:var(--primary); font-weight:600; cursor:pointer; }
|
||||
.api-index ul { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:8px 24px; padding-left:20px; }
|
||||
.api-index a { font:12px ui-monospace,monospace; }
|
||||
:focus-visible { outline:2px solid var(--primary); outline-offset:3px; }
|
||||
footer { border-top:1px solid var(--border); padding:20px 24px; text-align:center; color:var(--mesh-muted); font-size:12px; }
|
||||
@media(max-width:700px) { main { padding:20px 14px 40px; } .header-inner { padding:8px 14px; } h1 { font-size:24px; } h2 { font-size:19px; } h3 code { font-size:12px; } .endpoint { padding:16px; } .api-index ul { grid-template-columns:minmax(0,1fr); } }
|
||||
</style>
|
||||
${themeStyles}
|
||||
</head>
|
||||
<body>
|
||||
<header><div class="header-inner"><a class="brand" href="/"><img src="/static/meshview-icon.svg" alt="" width="32" height="32">Meshview</a><span>API reference</span><a class="home-link" href="/">Home ↗</a><button class="mesh-theme-toggle" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false">☾</button></div></header>
|
||||
<main>
|
||||
<details class="api-index"><summary>Browse all ${endpoints.length} endpoints</summary><nav aria-label="API endpoints"><ul>${index}</ul></nav></details>
|
||||
${blocks.join('\n')}
|
||||
</main>
|
||||
<footer>Source: docs/API_Documentation.md · Generated with node scripts/build-api-docs.mjs</footer>
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
console.log(`Built ${endpoints.length} endpoint sections: ${fileURLToPath(output)}`);
|
||||
|
||||
// The legacy chat reference and standalone maps use the same saved preference.
|
||||
for (const filename of ['api-chat.html','kiosk.html','heatmap.html']) {
|
||||
const path = new URL('../meshview/static/' + filename, import.meta.url);
|
||||
let html = readFileSync(path,'utf8');
|
||||
const themeBlock = '<!-- mesh-theme:start -->\n' + themeStyles + '\n<!-- mesh-theme:end -->';
|
||||
if (!html.includes('/static/theme.js')) html = html.replace('<style>','<script src="/static/theme.js"></script>\n<style>');
|
||||
if (html.includes('<!-- mesh-theme:start -->')) html = html.replace(/<!-- mesh-theme:start -->[\s\S]*?<!-- mesh-theme:end -->/,themeBlock);
|
||||
else html = html.replace('</head>',themeBlock + '\n</head>');
|
||||
if (!html.includes('data-theme-toggle')) html = html.replace('<body>','<body>\n<button class="mesh-theme-toggle" style="position:fixed;top:12px;right:12px;z-index:2000;background:#187346" type="button" data-theme-toggle aria-label="Switch to night mode" aria-pressed="false">☾</button>');
|
||||
writeFileSync(path,html);
|
||||
}
|
||||
@@ -36,8 +36,6 @@ def stage_meshtastic_package(proto_root, tmp_path):
|
||||
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;")
|
||||
# Custom options are qualified with the upstream package name too.
|
||||
text = text.replace("(meshtastic.", "(meshtastic.protobuf.")
|
||||
(staged_proto_root / proto.name).write_text(text, encoding="utf-8")
|
||||
|
||||
nanopb = tmp_path / "nanopb.proto"
|
||||
|
||||
Reference in new issue
Block a user