698 Commits

Author SHA1 Message Date
agessaman d4eba9ad11 fix(scheduler): stagger scheduled sends and skip global rate limit
Scheduled cron jobs now pass the cron key into the send path, apply a
deterministic [0, N) second delay from scheduled_message_max_stagger_seconds
(default 1.5), and call send_channel_message with skip_user_rate_limit=True
so simultaneous jobs are not dropped by rate_limit_seconds. Per-channel and
bot_tx limits still apply. Document the new Bot key in config.ini.example;
tests assert kwargs, skip flag, and stagger behavior.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-13 11:18:25 -07:00
agessaman bcd61fe805 fix(mesh_graph): optimize pending updates flushing logic to prevent deadlock
- Simplified the flushing mechanism for pending updates in the MeshGraph class by introducing a `flush_needed` flag to reduce redundant calls to `_flush_pending_updates_sync()`.
2026-05-13 07:54:09 -07:00
agessaman 39e6128778 fix(feed_manager, scheduler): improve message processing and concurrency handling
- Enhanced the FeedManager to prevent coroutine pileup by checking the lock status before acquiring it, allowing for more efficient message processing.
- Introduced a persistent dictionary to track the last send time for each feed, ensuring send intervals are respected without blocking.
- Updated the MessageScheduler to fire-and-forget the message processing, improving responsiveness and logging errors without blocking the main thread.
2026-05-12 19:38:47 -07:00
agessaman 70b2256752 feat(test): Test_Command response_format with piped path filters
Add format_piped_template (pathbytes_min, prefix_if_nonempty), utils
bytes-per-hop helpers, and [Test_Command] format priority over Keywords.
2026-05-12 19:30:42 -07:00
agessaman 13f22e4d7b feat(path_command): add reply prefix and minimum path bytes configuration
- Introduced `reply_prefix` to prepend a customizable string to path command replies, supporting placeholders for dynamic content.
- Added `minimum_path_bytes` setting to control the resolution of repeater names based on the number of bytes per hop, enhancing path command behavior.
- Updated relevant documentation and translations to reflect these new configuration options.
- Implemented unit tests to ensure correct functionality of the new features.
2026-05-12 17:23:22 -07:00
agessaman 5879838d8b feat(command_manager): Fix flood scope on keyword and RandomLine channel replies
Route process_message keyword/RandomLine sends through send_response so
reply_scope reaches set_flood_scope; add optional command_id to
send_response for transmission tracking.
2026-05-10 19:20:22 -07:00
agessaman 4d35e103a2 refactor(scheduler): enhance scheduled message configuration and parsing
- Updated the scheduled message format in `config.ini.example` to support 5-field cron expressions and preset aliases, replacing the deprecated HHMM format.
- Improved the `MessageScheduler` class to parse and validate new schedule formats, logging warnings for deprecated usage.
- Adjusted the `ScheduleCommand` to display scheduled messages with their respective cron or preset labels.
- Added unit tests to ensure correct parsing and handling of various schedule formats, including legacy HHMM and cron expressions.
2026-05-05 14:12:02 -07:00
agessaman 6d496934d9 refactor(advert_parsing): improve flag handling in message and map uploader services
- Replaced the use of AdvertFlags enum for flag parsing with bitwise operations to handle invalid values correctly.
- Updated the parsing logic in both MessageHandler and MapUploaderService to use boolean flags for better clarity and performance.
- Adjusted error logging to use warnings instead of errors for parsing issues, enhancing the logging strategy.
- Added unit tests to ensure correct parsing behavior for edge cases with invalid flag values.
2026-05-04 15:45:38 -07:00
agessaman dfa5dc2e01 feat(services): add Discord/Telegram outbound helpers and repeater discovery alerts
Add bridge_outbound posting, BaseServicePlugin.send_external_notifications,
and RepeaterPrefixCollision discovery vs collision routing with silence_mesh_output.
2026-05-02 21:50:03 -07:00
agessaman 2183f8e246 refactor(message_handler): standardize string quotes and improve code readability
- Updated string quotes from single to double quotes for consistency across the MessageHandler class.
- Enhanced formatting of method parameters for better readability.
- Minor adjustments to logging statements for clarity.
2026-05-01 21:32:54 -07:00
agessaman 263c73c2e2 feat(packet_capture): enhance MQTT packet publishing controls and path length decoding
- Added configuration options `mqtt_skip_unparseable_packets` and `advert_require_valid_signature` to control MQTT publishing behavior based on packet validity.
- Updated `decode_path_len_byte` function to return `None` for reserved size codes, improving path length validation.
- Implemented logic in `PacketCaptureService` to skip publishing unparseable packets and ADVERT packets with invalid signatures.
- Introduced `verify_meshcore_advert_ed25519` function for signature verification of ADVERT packets, with corresponding unit tests to ensure functionality.
- Enhanced documentation to reflect new configuration options and their effects on packet processing.
2026-05-01 21:32:40 -07:00
agessaman 5a484d1db2 feat(web_viewer): add channel_name validation and update feed functionality
- Implemented validation for the `channel_name` field to ensure it is not empty when updating feeds, raising a ValueError if validation fails.
- Added test cases to verify that updates to `channel_name` persist correctly and that attempts to set an empty `channel_name` are rejected with an appropriate error response.
2026-04-25 21:34:17 -07:00
agessaman d000e9858e fix(repeater_manager): update purging log insertion to include public_key and name
- Modified the SQL insert statement in the RepeaterManager class to include `public_key` and `name` fields, ensuring compatibility with the new schema.
- Updated corresponding test cases to reflect changes in the database operation, maintaining the integrity of the purging log functionality.
2026-04-25 21:25:43 -07:00
agessaman d34ad24e9b feat(weather): add default city configuration for wx commands
- Introduced a new configuration option `default_city` in `config.ini.example` for fallback city names when no location is provided.
- Updated `wx_command.py` and `wx_international.py` to utilize the `default_city` for location disambiguation, enhancing user experience when companion location is unavailable.
- Improved logging to reflect the use of default city or bot location as fallback options.
2026-04-25 21:15:51 -07:00
Adam Gessaman 0a758147e1 Merge pull request #163 from Robowarrior834/dev
feature Update: Added Map full screen and Menu Settings
2026-04-25 21:03:59 -07:00
agessaman ad4de524f8 merge(dev): resolve scheduler conflict in PR #163
Merge latest dev into the PR branch and keep both DateTrigger and EventType imports so scheduler changes remain compatible and conflict-free.

Made-with: Cursor
2026-04-25 21:03:36 -07:00
agessaman bcb3f48f02 fix(web_viewer): restore mesh export and clean scheduler imports
Prevent exportView runtime failure by restoring the download anchor setup and move radio param imports to module scope so Ruff passes on the PR changes.

Made-with: Cursor
2026-04-25 21:01:14 -07:00
agessaman 0f3ecea42e refactor(darc_mowas_service): improve imports and type hints
- Replaced direct imports of `pytz` with dynamic imports for better compatibility.
- Updated type hints for server and loop attributes in the DARC MoWaS service.
- Enhanced XML handling by specifying `xml.dom.minidom.Element` in method signatures.
- Improved message processing logic to handle missing channels and ensure valid area descriptions.
- Refactored `_child_text` function to accept both `Document` and `Element` types for better flexibility.
- Adjusted unit tests to reflect changes in the DARC MoWaS service structure.
2026-04-25 20:37:47 -07:00
Adam Gessaman a5f3cb008a Merge pull request #165 from fmoessbauer/fm/darc-mowas-api
feat: add implementation of the DARC MoWaS gateway
2026-04-25 20:29:34 -07:00
agessaman 6d80ad03da feat(trace_command): enhance path parsing for multibyte nodes and update documentation
- Updated the TraceCommand class to support parsing of 1-byte, 2-byte, and 3-byte hex node paths.
- Improved the _extract_path_from_message and _parse_path_arg methods to handle multibyte node formats and enforce consistent length checks.
- Enhanced help text and usage examples to reflect new path formats.
- Added unit tests for multibyte path parsing and reciprocal path building to ensure correct functionality.
2026-04-25 20:28:41 -07:00
agessaman 2e7c56207a fix(message_handler): improve public key retrieval logic
- Updated the logic for retrieving the sender's public key in the MessageHandler class to ensure it defaults to sender_id when pubkey_prefix is not available.
- Enhanced the condition to check for sender_id presence before accessing contacts, improving robustness in public key resolution.
2026-04-25 19:59:16 -07:00
agessaman a60b35f567 docs: update README and command reference with new features and services
- Removed caution section from README to streamline information.
- Added new services to README: Earthquake Service, Repeater Prefix Collision Service, and MQTT Weather Relay.
- Expanded command reference documentation with new commands: `version`, `status`, `aurora`, `magic8`, `catfact`, `reload`, `channelpause`, `channelresume`, `greeter`, `announcements`, and `schedule`.
- Updated getting started guide to reflect changes in Python version requirement and installation instructions.
- Enhanced service plugins documentation to include new services and clarify existing ones.
2026-04-25 19:21:23 -07:00
agessaman dbc07880ee docs(README): add caution section regarding bot installation and mesh congestion
- Introduced a cautionary note in the README to advise users on the potential issues of adding multiple bots to a mesh network.
- Highlighted the risks of congestion and double responses when running more than one bot on a single channel.
- Suggested best practices for managing bots, including the use of regions or hop limits.
2026-04-25 19:11:27 -07:00
agessaman 63592bdd65 feat(commands, config): implement path byte length requirements for commands
- Added configuration options to specify minimum path byte length requirements for the path, test, and multitest commands.
- Introduced methods to enforce these requirements and handle failure responses.
- Updated the packet capture service to correctly calculate packet hashes using the raw wire byte length.
- Enhanced unit tests to verify the correct behavior of the new path byte length logic.
2026-04-25 09:05:17 -07:00
Felix Moessbauer 63fcd26f7c feat(darc_mowas_service): retry messages that are not acked
For alert messages it is imporant to be sure they are received by the
network. For that, we implement a retry logic that waits for at least
one ack from a repeater and re-sends the message chunk if non is
received within a retry timeout.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-04-24 16:16:44 +02:00
Felix Moessbauer ffd93edd96 feat: add implementation of the DARC MoWaS gateway
We implement support for the DARC MoWaS service that distributes
emergency messages from the German BBK via the "Warnmultiplikator"
interface to Meshcore channels. This service is push-based and receives
alerts on /api/alert, which are then formatted similar to cell-broadcast
messages (without modification of the text) and re-distributed on
Meshcore.

Signed-off-by: Felix Moessbauer <felix.moessbauer@gmail.com>
2026-04-24 16:16:43 +02:00
agessaman 5f40c45f07 feat(PacketCapture): align RX/RAW correlation with meshcore-packet-capture
Deduplicate RAW_DATA against RX_LOG_DATA hex, cache RF metadata by packet
prefix, extend RAW payload extraction, fix payload_len for multi-byte paths.
2026-04-21 19:26:09 -07:00
agessaman 2962d2a21a Update .gitignore to exclude node_modules and coverage files
- Added node_modules/ to ignore list to prevent tracking of Node.js dependencies.
- Included coverage.json to ignore coverage report files, streamlining the repository.
2026-04-21 18:22:20 -07:00
agessaman 23cdce03e8 feat(db_migrations, message_handler, repeater_manager): enhance purging log functionality
- Added a new migration to include a 'details' column in the 'purging_log' table for improved logging of actions.
- Refactored the `log_purging_action` method in `RepeaterManager` to handle both new and legacy schemas, ensuring compatibility with the updated database structure.
- Updated `MessageHandler` to utilize the new logging method, replacing direct database updates with a unified logging approach.
- Added tests to verify the presence of the new column and the correct functionality of the logging mechanism across different scenarios.
2026-04-21 17:04:51 -07:00
agessaman 8e71a11bd1 feat(command_manager): enhance DM recipient resolution with public key prefix lookup
- Updated `send_dm` method to first attempt contact resolution by name, and if that fails, fallback to resolving by public key prefix.
- Improved logging to indicate the method of recipient resolution used.
- Added tests to verify the new recipient resolution logic, ensuring correct behavior when looking up contacts by public key prefix and handling failures appropriately.
2026-04-21 10:07:40 -07:00
Robowarrior834 e5e84f9171 Fixed map full screen exit on ios 2026-04-21 09:45:16 -04:00
Robowarrior834 c69ae9ac29 Fixed full screen map exit on mobile 2026-04-21 09:44:26 -04:00
agessaman 0e5daadd04 feat(config, message_handler, repeater_manager, scheduler): implement device mode for auto-managing contacts
- Enhanced configuration options for `auto_manage_contacts` to support 'device' mode, allowing firmware to handle companion auto-addition and favourite hygiene.
- Updated `MessageHandler` to track new companions based on the `auto_manage_contacts` setting, with distinct behaviors for 'false', 'device', and 'bot' modes.
- Introduced scheduled jobs in `MessageScheduler` for device mode to manage firmware preferences and favourite keys with specified delays.
- Modified `RepeaterManager` to skip companion auto-purge in device mode, ensuring firmware manages contact slots effectively.
- Added tests to validate new behaviors and configurations, ensuring robust handling of contact management across different modes.
2026-04-20 21:26:17 -07:00
Robowarrior834 217a30f8d7 Added Fullscreen Map and Radio settings. 2026-04-20 16:24:40 -04:00
agessaman f061df391e revert: back out #80 find_recent_rf_data changes due to regression 2026-04-18 11:14:34 -07:00
agessaman 879a86bd80 fix(message_handler): keep #80 correlation strictly observation-level
Simplifies find_recent_rf_data so the sample it returns is always a single
wire observation — snr, rssi, raw_hex, and routing_info all belong to the
same decoded copy. The #80 fix stays intact via the two earlier invariants:
unmatched correlation_key returns None (no fallback to an unrelated recent
packet), and the no-key DM path is constrained to a narrow
rf_fallback_window.

An earlier iteration tried to enrich routing_info with the longest observed
same-packet_hash forward, but that would have left message_stats rows with
hops sourced from the matched observation while path was a different
forward's — an internal skew visible in the web viewer and !path output.
The enrichment is documented in TODO.md as a v0.9.1+ option-C follow-up
that must also sync message.hops for consistency.

Regression tests in tests/test_message_handler.py::TestFindRecentRfData
cover: return-None on unmatched key, narrow-fallback-window rejection of
stale samples, and the no-cross-wiring assertion for same-packet_hash
forwards.

Made-with: Cursor
2026-04-17 14:37:21 -07:00
agessaman bf6bc14de7 release(v0.9.0): readiness — silent-subscribe tests, py310, RF correlation fix
- Rewrite test_subscribe_packets/messages_emits_status_ack to match the
  silent subscription UX from 1ee84f2.
- Reconcile Python version: requires-python>=3.10, ruff target py310, CI
  matrix adds 3.13, pyupgrade UP0xx ignored pending a separate typing-rewrite
  PR; fix two B905 zip(strict=...) lints.
- Issue #80 fix in find_recent_rf_data: return None when correlation_key is
  provided but unmatched; prefer the longest observed path among samples
  sharing a packet_hash; narrow the no-key fallback to a configurable
  rf_fallback_window (default 2s).
- Issue #161: lower shipped max_response_hops default 10 -> 7.
- Add CHANGELOG.md, restructure BUGS.md around a ## v0.9.0 Fixed Bugs
  table, prune crossed-out duplicate outstanding rows, and add a
  Deferred-from-v0.9.0 triage section to TODO.md.
- Untrack coverage.json and add it to .gitignore.

Made-with: Cursor
2026-04-17 13:53:13 -07:00
agessaman 1ee84f22ff refactor(web_viewer): silence subscription status messages in BotDataViewer
Removed emit statements for subscription status messages in the BotDataViewer class to keep connection feedback silent, as the navbar indicator already reflects socket state. This change enhances user experience by reducing unnecessary notifications while maintaining existing functionality.
2026-04-16 20:53:20 -07:00
agessaman 4677a238ac feat(message_handler): enhance message handling with type hints and new data structure
Added a new PendingMessageEntry TypedDict to improve the structure of pending messages. Updated type hints throughout the MessageHandler class for better clarity and consistency, including the initialization method and message processing functions. This refactor enhances code readability and maintainability without altering existing functionality. Additionally, included the new message_handler module in the pyproject.toml for better module organization.
2026-04-16 20:43:19 -07:00
agessaman 86e27153f2 refactor(packet_capture_service): update type hints for consistency and clarity
Revised type hints in the PacketCaptureService class to use lowercase 'list' and 'dict' instead of 'List' and 'Dict', enhancing code readability and consistency with Python's typing conventions. Adjusted optional parameters to use the new union syntax for better clarity. No functional changes were made.
2026-04-16 20:27:32 -07:00
agessaman b5cce55604 feat(config): add configurable timeouts for web viewer integration
Introduced optional timeout settings in the configuration for various web viewer operations, including edge and node post timeouts, SQLite connection timeout, and requeue timeout. Updated the web viewer integration to utilize these settings, enhancing flexibility and reliability. Added commands to inspect the resolved configuration with sensitive keys redacted, and updated documentation accordingly.
2026-04-16 19:56:47 -07:00
agessaman 329905dd08 feat(core, scheduler): implement timeout handling for advert sending
Added asyncio timeout handling for sending startup and interval-based adverts, improving reliability by recording failures on timeout. Updated relevant tests to ensure coverage for timeout scenarios and increment failure counts appropriately. Introduced a new Radio Reliability panel in the web viewer for monitoring radio status.
2026-04-16 19:29:28 -07:00
agessaman 7b0124208f fix(scheduler): handle RuntimeError on threadsafe future.result
Log loop-teardown RuntimeError at warning for scheduled sends, feed
queue wait, and repeater cleanup_database; keep interval advert on
broad Exception since send_advert failures use RuntimeError.
2026-04-16 19:18:11 -07:00
agessaman ad09e8ba8a fix(web_viewer): update config item retrieval to prevent interpolation issues
Modified the config item retrieval in BotDataViewer to use raw=True, ensuring that literal '%' characters in configuration values are not subject to interpolation. Additionally, removed the breadcrumb navigation from the admin configuration template for a cleaner UI. Added a test to verify that '%' in values does not cause server errors.
2026-04-16 19:09:23 -07:00
agessaman 550a15e0d2 feat(web_viewer): bound packet_stream queue and requeue on flush failure
Add Web_Viewer.packet_stream_write_queue_max (default 1000), timed put
with flush retry on Full, flush lock, and re-queue rows after failed
batch insert. Document deferred PR #147 items. Reduce pytest cov
verbosity to term-only. Extend BotIntegration queue tests.
2026-04-16 19:02:33 -07:00
agessaman 75be386e08 refactor: remove redundant CSS styles from API Explorer template
Eliminated unnecessary CSS rules for the first column in the API Explorer table, streamlining the stylesheet and improving maintainability. This change enhances the clarity of the code without affecting the visual layout.
2026-04-16 18:46:16 -07:00
agessaman e04cc587cb test: add tests for admin config page loading and password redaction
Introduced a new test class, TestAdminConfig, to verify the loading of the admin configuration page and ensure sensitive information like passwords is redacted in the response. This enhances test coverage for the admin configuration functionality.
2026-04-16 18:41:27 -07:00
Stacy Olivas fbaf7b50d6 fix: replace duplicate version logic with resolve_runtime_version delegate for #149 (web viewer UX)
After rebasing onto upstream/dev, app.py contained an inline
_get_version_info() duplicating logic already centralized in
modules/version_info.py. Replace with a 5-line delegate to
resolve_runtime_version(), removing the now-unnecessary import subprocess.

Also refreshes tests/fixtures/mqtt_packets.json with current live MQTT
fixture timestamps.

Behavioral note: in a bare dev clone with no .version_info and no
MESHCORE_BOT_VERSION env var, the footer now shows the pyproject.toml
version (v0.1.0) instead of branch·commit·date. Production deployments
are unaffected.

Do not merge until #149 is merged.
2026-04-16 18:37:47 -07:00
Stacy Olivas d7cf0d5d2b fix: add per-test timeout to pytest.ini to prevent CI hangs
pytest.ini takes precedence over pyproject.toml [tool.pytest.ini_options]
so the timeout = 30 setting there was silently ignored. Add timeout = 30
and timeout_method = thread directly to pytest.ini so blocking tests are
killed after 30 s in CI.
2026-04-16 18:35:48 -07:00
Stacy Olivas 2a80f76432 sync: use explicit CGN network check in validate_external_url (from PR #140)
Replace is_global fallback with canonical _CGN_NETWORK constant check to
stay consistent with PR #140's approach across all post-140 branches.
2026-04-16 18:35:48 -07:00