{"slug": "show-hn-netmon-self-hosted-lan-monitor-with-sarcastic-ai-reports-to-telegram", "title": "Show HN: Netmon – self-hosted LAN monitor with sarcastic AI reports to Telegram", "summary": "Netmon, a self-hosted local network monitor that runs hourly speed tests and LAN scans, sends sarcastic AI-generated reports to Telegram every four hours. The open-source Python tool, created by developer Role1776, stores metrics in a local SQLite database and uses an OpenAI-compatible API for commentary, ensuring 100% privacy by keeping all data local except for the reports delivered to Telegram.", "body_md": "**Self-hosted local network monitor with 24-hour speed charts & sarcastic AI commentary delivered straight to Telegram.**\n\nA lightweight local bot that runs a speed test on your network every hour, scans active devices on your LAN using `nmap`\n\n, and logs everything to a local SQLite database.\n\nEvery 4 hours, it delivers a **detailed report** complete with a 24-hour trend graph and a sarcastic, LLM-generated commentary on your network's behavior (*\"someone's hogging the bandwidth again\"*).\n\nNote\n\n**100% Private & Self-Hosted:** No external metric servers involved — everything runs locally on your machine or Raspberry Pi. Only text reports and graph images are dispatched to your Telegram chat.\n\nEvery hour (`SLEEP_TIME`\n\nin `main.py`\n\n, default 3600 seconds):\n\n**Speed Test:** Measures download/upload speeds, ping latency, ISP, and test server details using`speedtest-cli`\n\n.**LAN Scan:** Scans the local subnet using`nmap`\n\nARP scan to count active connected devices.**Local Storage:** Saves metrics & device tallies directly to a local`metrics.sql`\n\nSQLite database.**Status Alert:** Sends a concise status update to Telegram (*\"all good\"*or*\"line is dying\"*).**24h AI Report:** Every 4th cycle (every 4h), generates a**24-hour trend graph** via`matplotlib`\n\nalongside a sarcastic LLM analysis of network load and speed fluctuations.\n\n| Technology | Purpose |\n|---|---|\nPython 3.13+ (via `uv` ) |\nCore runtime |\nSQLite |\nLocal metrics persistence (`metrics.sql` ) |\n`speedtest-cli` |\nNetwork bandwidth and ping measurements |\n`nmap` |\nSubnet ARP scanning for device discovery |\n`matplotlib` |\n24-hour metrics visualization |\nOpenAI-compatible API |\nSarcastic report & trend analysis (cloud OpenAI or a local LLM) |\nTelegram API |\nAlert and graph report delivery |\n\n**OS:** macOS or Linux (`nmap --iflist`\n\nrequired; Windows not supported out of the box).— manages the Python version, virtualenv, and locked dependencies for you. No manual[uv](https://docs.astral.sh/uv/)`python3`\n\n/`venv`\n\n/`pip`\n\njuggling.**System Binaries:**`nmap`\n\nand`speedtest-cli`\n\ninstalled system-wide.**Passwordless**— device counting needs a real ARP scan (raw sockets), which requires root; see one-time setup below.`sudo`\n\nfor`nmap`\n\n**Tokens:** Telegram Bot Token, Telegram Chat ID, and an API key for your OpenAI-compatible provider (not needed if you point`AI_BASE_URL`\n\nat a local LLM server).\n\n**macOS (Homebrew):**\n\n```\nbrew install nmap speedtest-cli\n```\n\n**Linux (Debian/Ubuntu):**\n\n```\nsudo apt update && sudo apt install -y nmap speedtest-cli\n```\n\nDevice counting runs `nmap`\n\nas root for a real ARP scan — without it, host discovery silently falls back to ordinary TCP probing and undercounts devices that don't answer on common ports. Since the bot runs unattended, `sudo`\n\nneeds to work without a password prompt on every cycle:\n\n```\necho \"$(whoami) ALL=(root) NOPASSWD: $(command -v nmap)\" | sudo tee /etc/sudoers.d/netmon-nmap\nsudo chmod 440 /etc/sudoers.d/netmon-nmap\n```\n\nThis grants passwordless `sudo`\n\nonly for the `nmap`\n\nbinary — not your whole account.\n\nInstall [ uv](https://docs.astral.sh/uv/) if you don't have it yet:\n\n```\ncurl -LsSf https://astral.sh/uv/install.sh | sh\n```\n\nThen:\n\n```\ngit clone https://github.com/Role1776/netmon.git\ncd netmon\nuv sync\n```\n\n`uv sync`\n\ndownloads the pinned Python version (see `.python-version`\n\n) if you don't already have it, creates `.venv`\n\n, and installs the exact locked dependency versions from `uv.lock`\n\n. No system `python3`\n\n, no manual venv activation.\n\nCopy the template file and fill in your secrets:\n\n```\ncp .env.example .env\n```\n\n`.env`\n\nvariables:\n\n| Variable | Description |\n|---|---|\n`AI_API_KEY` |\nYour LLM provider API key (any string works for most local servers) |\n`AI_MODEL` |\nModel name (e.g. `gpt-4o-mini` , or a local model name — see below) |\n`AI_BASE_URL` |\nBase API URL (e.g., `https://api.openai.com/v1` , or your local server's URL) |\n`TG_BOT_TOKEN` |\nTelegram bot token from `@BotFather` |\n`TG_CHAT_ID` |\nYour Telegram Chat ID |\n`DB_PATH` |\nSQLite database file path (e.g. `metrics.sql` ) |\n\nTip\n\n**You're not locked into OpenAI.** `ai.py`\n\ntalks to any OpenAI-compatible endpoint, so a local inference server (e.g. [Ollama](https://ollama.com), LM Studio) works too — just point `AI_BASE_URL`\n\nat it. For report quality that holds up, use a model with **at least ~7B parameters**; a solid local pick is **Gemma 4 12B at 4-bit (QAT) quantization** (`gemma4:12b-it-qat`\n\nvia Ollama), which fits comfortably on 16GB of RAM.\n\n```\nuv run main.py\n```\n\n`uv run`\n\nalways uses this project's own `.venv`\n\nand pinned Python version, so it can't accidentally run against your system `python3`\n\n.\n\nTip\n\nRun the bot inside `tmux`\n\n/`screen`\n\nor set it up as a system service (`systemd`\n\n/`launchd`\n\n) to keep it running 24/7 in the background.\n\n```\nNetwork Status Update\nTime: 2026-07-21 14:00:00\nISP: MyISP | Server: New York\n\nDevices online: 7\nDownload: 145.2 Mbps\nUpload: 62.1 Mbps\nLatency: 14.8 ms\n\nTraffic used: 160.0 MB down / 70.0 MB up\n\nCurrent status: Good speed and low latency\n```\n\nEvery 4 hours, the bot sends a **24-hour matplotlib graph** accompanied by a sarcastic LLM-generated report:\n\n```\n<b>Network Speed Test Report (24h Analysis)</b>\n\nClient: <b>MyISP</b>\nServer: <b>New York</b>\n\n<b>Latest Test Metrics</b>\n<pre>\nDownload: 178.5 Mbps\nUpload: 45.2 Mbps\nPing: 23.1 ms\nDevices Online: 9\n</pre>\n\n<b>24-Hour Dynamics Analysis</b>\nOver the last 24 hours, the download speed averaged <code>140 Mbps</code>, but we saw a massive drop to <code>20 Mbps</code> at 8:00 PM right as device count jumped from <code>4</code> to <code>11 devices</code>. Clearly, someone's hogging the bandwidth or the ISP's mice were busy chewing on the fiber line again. Latency remained stable except for a brief spike during peak hours.\n\n<b>Data Transfer (Latest Test)</b>\n<pre>\nDownloaded: 160.0 MB\nUploaded: 70.0 MB\n</pre>\n\n<b>Conclusion</b>\nExpect periodic speed drops whenever local freeloaders stream 4K movies or the ISP potato infrastructure struggles.\nnetmon/\n├── assets/         # Logo & documentation media assets\n├── graphs/         # Generated 24h matplotlib graph images\n├── main.py         # Main execution loop & orchestrator\n├── runner.py       # Speedtest-cli and nmap scan execution & parsing\n├── sqlite.py       # SQLite database operations & schema management\n├── models.py       # Domain data models (NetworkMetric, SpeedTest)\n├── graphs.py       # Matplotlib graph rendering engine\n├── ai.py           # OpenAI API client & sarcastic text generator\n├── tg.py           # Telegram bot dispatch helper\n├── config.py       # Environment variable validation & config\n├── pyproject.toml  # Project metadata & dependencies\n├── uv.lock         # Locked, reproducible dependency versions\n└── LICENSE         # MIT License file\n```\n\nDistributed under the **MIT License**. See [ LICENSE](/Role1776/netmon/blob/main/LICENSE) for more details.", "url": "https://wpnews.pro/news/show-hn-netmon-self-hosted-lan-monitor-with-sarcastic-ai-reports-to-telegram", "canonical_source": "https://github.com/Role1776/netmon", "published_at": "2026-07-22 20:26:37+00:00", "updated_at": "2026-07-22 20:52:39.264898+00:00", "lang": "en", "topics": ["developer-tools", "artificial-intelligence", "ai-tools"], "entities": ["Netmon", "Role1776", "Telegram", "OpenAI", "SQLite", "nmap", "speedtest-cli", "matplotlib"], "alternates": {"html": "https://wpnews.pro/news/show-hn-netmon-self-hosted-lan-monitor-with-sarcastic-ai-reports-to-telegram", "markdown": "https://wpnews.pro/news/show-hn-netmon-self-hosted-lan-monitor-with-sarcastic-ai-reports-to-telegram.md", "text": "https://wpnews.pro/news/show-hn-netmon-self-hosted-lan-monitor-with-sarcastic-ai-reports-to-telegram.txt", "jsonld": "https://wpnews.pro/news/show-hn-netmon-self-hosted-lan-monitor-with-sarcastic-ai-reports-to-telegram.jsonld"}}