diff --git a/.gitignore b/.gitignore index 4181370..5587e17 100644 --- a/.gitignore +++ b/.gitignore @@ -145,6 +145,7 @@ website/ pytest.ini pymc-test/* config-pymc.ini +*.key # Docker data directory (user-specific config, databases, logs) # Ignore contents but keep directory structure diff --git a/config.ini.example b/config.ini.example index 4d154a6..9c9c99d 100644 --- a/config.ini.example +++ b/config.ini.example @@ -1036,7 +1036,7 @@ auto_start = false # Database path for web viewer data # Default: bot_data.db -db_path = bot_data.db +db_path = meshcore_bot.db # Additional hashtag channels to decode in the packet stream # The web viewer can decrypt GroupText messages from hashtag channels diff --git a/docs/DISCORD_BRIDGE.md b/docs/DISCORD_BRIDGE.md index 5a19835..451c052 100644 --- a/docs/DISCORD_BRIDGE.md +++ b/docs/DISCORD_BRIDGE.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Discord Bridge Service +--- + # Discord Bridge Service The Discord Bridge service posts MeshCore channel messages to Discord channels via webhooks. This is a **one-way, read-only bridge** - messages only flow from MeshCore to Discord. diff --git a/docs/FEEDS.md b/docs/FEEDS.md index 4b7c12f..d1d7cbe 100644 --- a/docs/FEEDS.md +++ b/docs/FEEDS.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Feed Management +--- + # Feed Management The Feed Management system allows the bot to subscribe to RSS feeds and REST APIs, automatically polling for new content and posting updates to specified mesh channels. diff --git a/docs/MAP_UPLOADER.md b/docs/MAP_UPLOADER.md index fd4b3da..b89dc2c 100644 --- a/docs/MAP_UPLOADER.md +++ b/docs/MAP_UPLOADER.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Map Uploader Service +--- + # Map Uploader Service Uploads node advertisements to [map.meshcore.dev](https://map.meshcore.dev) for network visualization. diff --git a/docs/PACKET_CAPTURE.md b/docs/PACKET_CAPTURE.md index 2e2dea1..b86818d 100644 --- a/docs/PACKET_CAPTURE.md +++ b/docs/PACKET_CAPTURE.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Packet Capture Service +--- + # Packet Capture Service Captures packets from the MeshCore network and publishes them to MQTT brokers. diff --git a/docs/PATH_COMMAND_CONFIG.md b/docs/PATH_COMMAND_CONFIG.md index 545706b..4a77484 100644 --- a/docs/PATH_COMMAND_CONFIG.md +++ b/docs/PATH_COMMAND_CONFIG.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Path Command Configuration +--- + # Path Command Configuration Guide This document explains all configuration parameters for the Path Command, which decodes hex path data to identify repeaters in message routing paths. diff --git a/docs/REPEATER_COMMANDS.md b/docs/REPEATER_COMMANDS.md index 7f3da5d..966e427 100644 --- a/docs/REPEATER_COMMANDS.md +++ b/docs/REPEATER_COMMANDS.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Repeater Management Commands +--- + # Repeater Management DM Commands This document provides comprehensive documentation for all repeater management commands available via direct message (DM) to the bot. diff --git a/docs/WEATHER_SERVICE.md b/docs/WEATHER_SERVICE.md index 71700a0..86bc242 100644 --- a/docs/WEATHER_SERVICE.md +++ b/docs/WEATHER_SERVICE.md @@ -1,3 +1,8 @@ +--- +layout: default +title: Weather Service +--- + # Weather Service Provides scheduled weather forecasts, weather alerts, and lightning detection. diff --git a/docs/_config.yml b/docs/_config.yml new file mode 100644 index 0000000..95defb9 --- /dev/null +++ b/docs/_config.yml @@ -0,0 +1,17 @@ +# GitHub Pages / Jekyll config for meshcore-bot documentation +title: meshcore-bot Documentation +description: Documentation for the MeshCore bot and its services +theme: jekyll-theme-cayman +markdown: kramdown + +# Set to your repo URL (used for "Project overview" links on index) +repository_url: https://github.com/agessaman/meshcore-bot +repository_branch: main + +# Apply default layout to all docs under docs/ +defaults: + - scope: + path: "" + type: pages + values: + layout: default diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..346abb4 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,29 @@ +--- +layout: default +title: meshcore-bot Documentation +--- + +# meshcore-bot Documentation + +Documentation for the MeshCore bot: setup, configuration, commands, and services. + +## Project overview + +- [README]({{ site.repository_url }}/blob/{{ site.repository_branch }}/README.md) – Getting started, installation, quick start +- [COMMANDS.md]({{ site.repository_url }}/blob/{{ site.repository_branch }}/COMMANDS.md) – Full command reference +- [DOCKER.md]({{ site.repository_url }}/blob/{{ site.repository_branch }}/DOCKER.md) – Docker deployment +- [SERVICE-INSTALLATION.md]({{ site.repository_url }}/blob/{{ site.repository_branch }}/SERVICE-INSTALLATION.md) – Systemd service setup +- [WEB_VIEWER.md]({{ site.repository_url }}/blob/{{ site.repository_branch }}/WEB_VIEWER.md) – Web viewer module + +## Guides (this site) + +| Document | Description | +|----------|-------------| +| [Path Command Configuration](PATH_COMMAND_CONFIG.html) | Path command presets and options | +| [Repeater Commands](REPEATER_COMMANDS.html) | Repeater management DM commands | +| [Feed Management](FEEDS.html) | RSS/REST feeds and posting to channels | +| [Weather Service](WEATHER_SERVICE.html) | Scheduled weather and alerts | +| [Discord Bridge](DISCORD_BRIDGE.html) | One-way bridge to Discord | +| [Map Uploader](MAP_UPLOADER.html) | Uploading to map.meshcore.dev | +| [Packet Capture](PACKET_CAPTURE.html) | Packet capture and MQTT | +| [Documentation site setup](DOCS_SITE.html) | How to enable and configure this GitHub Pages site | diff --git a/modules/web_viewer/templates/index.html b/modules/web_viewer/templates/index.html index da4b913..27a3c83 100644 --- a/modules/web_viewer/templates/index.html +++ b/modules/web_viewer/templates/index.html @@ -646,17 +646,24 @@ class ModernDashboard { formatUptime(uptimeSeconds) { const uptimeElement = document.getElementById('uptime'); - const hours = Math.floor(uptimeSeconds / 3600); + const totalMinutes = Math.floor(uptimeSeconds / 60); + const totalHours = Math.floor(uptimeSeconds / 3600); + const totalDays = Math.floor(uptimeSeconds / 86400); + const months = Math.floor(totalDays / 30); + const days = totalDays % 30; + const hours = Math.floor((uptimeSeconds % 86400) / 3600); const minutes = Math.floor((uptimeSeconds % 3600) / 60); - const seconds = uptimeSeconds % 60; - - if (hours > 0) { - uptimeElement.textContent = `${hours}h ${minutes}m`; - } else if (minutes > 0) { - uptimeElement.textContent = `${minutes}m ${seconds}s`; - } else { - uptimeElement.textContent = `${seconds}s`; + const seconds = Math.floor(uptimeSeconds % 60); + + const parts = []; + if (months > 0) parts.push(`${months}mo`); + if (days > 0) parts.push(`${days}d`); + if (hours > 0) parts.push(`${hours}h`); + if (minutes > 0) parts.push(`${minutes}m`); + if (parts.length === 0 || totalHours < 1) { + if (seconds > 0 || parts.length === 0) parts.push(`${seconds}s`); } + uptimeElement.textContent = parts.length > 0 ? parts.join(' ') : '0s'; } startLiveUptime() {