Skip to content

BrAtUkA/knoxhybrid-monitor

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KNOXHYBRID Monitor

KNOXHYBRID Monitor

A lightweight Windows system-tray app for real-time solar inverter monitoring
via the ShineMonitor / Eybond cloud API.

Tauri v2  ·  Rust + HTML  ·  ~3 MB RAM  ·  Runs 24/7

Dashboard

Download →

Supported Companies

The app supports any solar monitoring portal built on the ShineMonitor / Eybond cloud backend. Adding a new company can be a one-line code change. Contributions welcome!

Company Status
Knox ✅ Included
Your company? Open an issue →

See Adding a new company below for the 5-minute guide.   Contributing →

Features

  • Tiny footprint at ~3-6 MB RAM and near-zero CPU. Won't impact your games or work.
    Task Manager showing 0% CPU, 2.9 MB RAM
  • Lives in the system tray. No window unless you open one. Designed for 24/7 machines.
  • Real-time dashboard with stat cards, animated energy flow diagram, and 22+ live readings refreshed every 5 minutes.
  • Power outage alerts the moment your inverter switches to battery. Choose between a detailed popup or a compact toast.
  • Restoration alerts when grid power returns, showing how long the outage lasted.
  • History browser with a calendar date picker, per-reading timeline with LINE/BATTERY badges, outage count, peak power, and duration stats.
  • Smart polling that syncs with the hardware's 5-minute data collector interval. No wasted API calls.
  • Encrypted credentials on disk using AES-256-GCM, keyed to the machine hostname.

Screenshots

Login

Login window

Dashboard & Live Readings

Dashboard - Live Readings

Stat cards (mode, grid, battery, load, solar), energy flow diagram, and 22+ live sensor readings.


Data History

Data History

Pick any date → scrollable reading timeline with LINE/BATTERY badges.
Stats bar shows average power, peak, load %, outage count, total duration, and longest outage.


Power averages breakdown

Power breakdown by time of day, overall averages, peak wattage, and load percentages.


Power Outage Alerts

Popup Toast
Outage popup Outage toast

Shows battery %, load, grid voltage, outage time, and data delay.
"Don't Remind" mutes re-alerts until power restores.


Power Restored Alerts

Popup Toast
Restored popup Restored toast

Shows outage duration, battery state, and timestamps.


Tray Icon States

Line Mode (green) Battery Mode (red)
Tray - line mode Tray - battery mode

The tray icon changes color based on inverter status: green when on grid, red when on battery.


Quick Start

Pre-built installer

Download the latest .exe installer or .msi from Releases and run it. The app starts minimized to the system tray.

Build from source

Prerequisites:

  • Rust 1.70+ (stable)
  • Tauri CLI v2: cargo install tauri-cli --version "^2"
  • Windows 10/11 (WebView2 is bundled)
git clone https://github.com/BrAtUkA/knoxhybrid-monitor.git
cd knoxhybrid-monitor
cargo tauri build

The compiled binary lands in src-tauri/target/release/knoxhybrid-monitor.exe.
Installers (.msi and .exe) are in src-tauri/target/release/bundle/.

Usage

  1. Launch the app. It appears as a tray icon in the system tray.
  2. Login on first run. Select your company, enter credentials, and sign in.
  3. Dashboard: right-click the tray icon → Dashboard.
  4. Alerts are automatic on outage. Configure style and behavior from the tray menu.
  5. History: Dashboard → History tab → pick any date.

Tray menu

Option Description
Dashboard Open the monitoring dashboard
Pause Alerts Mute alerts for 30 / 60 / 120 min
Resume Alerts Un-pause alerts early
Alert Style Switch between popup and toast
Restored Popup Toggle the "power restored" notification
Test Alert Simulate an outage → restore cycle
Quit Exit the application

How It Works

The app is designed to keep the CPU asleep as much as possible. Instead of continuous polling, it calculates exactly when the next data point will arrive and sleeps until then. Between updates, the process does nothing and sits at 0% CPU and ~3 MB RAM.

flowchart TD
    START["App Launch"] --> AUTH["Wait for login"]
    AUTH --> INIT["Load cached device chain\nAuthenticate with API"]
    INIT --> STEP1

    subgraph STEP1_BOX["Step 1: Poll"]
        STEP1["Lock poll mutex"] --> QS["get_quick_status()"]
        QS --> SMART{"Data stale?\n(age > 300s)"}
        SMART -- "Yes" --> TTL30["Cache TTL = 30s\n(check API sooner)"]
        SMART -- "No" --> TTL240["Cache TTL = 240s\n(serve from cache)"]
        TTL30 --> PARSE["Parse readings + timestamp"]
        TTL240 --> PARSE
        PARSE --> ALERT["process_alerts()"]
        ALERT --> ICON["Update tray icon"]
        ICON --> UNLOCK["Unlock mutex"]
    end

    UNLOCK --> CACHE_LIVE["Pre-build live data\nfor instant dashboard open"]
    CACHE_LIVE --> ERR{"API error?"}

    ERR -- "Yes" --> BACKOFF["Exponential backoff\n30s → 60s → 120s → 240s → 300s max"]
    BACKOFF --> SLEEP_ERR["Sleep backoff duration"]
    SLEEP_ERR --> STEP1

    ERR -- "No" --> FRESH{"New data?\n(timestamp changed)"}
    FRESH -- "No (same data)" --> RETRY_LOOP
    FRESH -- "Yes" --> CALC["wait = 300s − data age"]

    CALC --> WAIT{"wait > 0?"}
    WAIT -- "Yes" --> SLEEP_MAIN["Sleep ~250-290s\n(CPU idle)"]
    WAIT -- "No (overdue)" --> RETRY_LOOP
    SLEEP_MAIN --> RETRY_LOOP

    subgraph RETRY_BOX["Step 2: Retry until new data (max 20 × 30s)"]
        RETRY_LOOP["iteration = 0"] --> SLEEP30["Sleep 30s"]
        SLEEP30 --> POLL_RETRY["Lock → poll → alerts → icon → unlock"]
        POLL_RETRY --> NEW{"Timestamp changed?"}
        NEW -- "Yes" --> FOUND["Cache new data\nBreak"]
        NEW -- "No" --> INC["iteration++"]
        INC --> MAX{"iteration < 20?"}
        MAX -- "Yes" --> SLEEP30
        MAX -- "No (10 min)" --> TIMEOUT["Give up, restart loop"]
    end

    FOUND --> STEP1
    TIMEOUT --> STEP1

    style START fill:#22c55e,color:#fff
    style BACKOFF fill:#ef4444,color:#fff
    style FOUND fill:#22c55e,color:#fff
    style TIMEOUT fill:#f59e0b,color:#fff
    style SLEEP_MAIN fill:#1e3a5f,color:#8bb8e8
    style SLEEP30 fill:#1e3a5f,color:#8bb8e8
    style SLEEP_ERR fill:#1e3a5f,color:#8bb8e8
Loading
  1. Authenticates against the ShineMonitor cloud API, using the same protocol as the official mobile app.

  2. Resolves the device chain once (plant → data collector → inverter), then caches it on disk for 6 hours. No repeat lookups.

  3. Polls and then sleeps. After getting fresh data, the app calculates exactly when the hardware will report next (300s interval minus data age) and sleeps the entire duration. No busy loops, no timers firing.

  4. Uses adaptive cache TTLs. When data is fresh, API responses are cached 240s in-memory. When data is overdue, the TTL drops to 30s to catch updates faster. Either way, redundant network calls are avoided.

  5. Retries efficiently. If the expected data doesn't arrive on time, it checks every 30s for up to 10 minutes, then resets. Errors use exponential backoff (30s → 300s) so a down API doesn't burn cycles.

  6. Pre-builds dashboard data after each poll so opening the dashboard is instant from cache. No API call needed.

  7. All sleep, no spin. The process spends 95%+ of its time in tokio::time::sleep. The OS doesn't even schedule it, so CPU stays at 0% and RAM at ~3 MB.

Configuration

All user data is stored in %APPDATA%\com.knoxhybrid.monitor\:

File Contents
credentials.json AES-256-GCM encrypted login credentials
preferences.json Alert style, popup toggles, UI preferences
static_cache.json Cached device chain (6h TTL)

Project Structure

KNOXX_tauri/
├── ui/                        # Frontend (HTML/CSS/JS)
│   ├── index.html             # Dashboard
│   ├── login.html             # Login window
│   ├── alert.html             # Alert popup/toast
│   ├── lucide.min.js          # Icons (bundled)
│   └── fonts/                 # Inter font (bundled)
├── src-tauri/                 # Rust backend
│   ├── src/
│   │   ├── api.rs             # API client, auth, caching, encryption
│   │   ├── tray.rs            # Tray icon, menu, polling, alerts
│   │   ├── commands.rs        # IPC commands
│   │   ├── lib.rs             # App setup, startup, window events
│   │   └── main.rs            # Entry point
│   ├── capabilities/          # Tauri permission config
│   ├── icons/                 # App icons
│   ├── tauri.conf.json        # Tauri config
│   └── Cargo.toml             # Rust dependencies
├── imgs/                      # Screenshots
└── .gitignore

Tech Stack

Component Technology
Framework Tauri v2
Backend Rust 2021 edition
Frontend Vanilla HTML / CSS / JS
HTTP reqwest (rustls-tls)
Icons Lucide (bundled)
Font Inter (bundled)
Encryption AES-256-GCM via aes-gcm

Adding a new company

Any company using the ShineMonitor / Eybond platform can be added. Each has a company_key and app_id:

  1. Open src-tauri/src/api.rscompany_lookup() function
  2. Add one line:
    "your-slug" => Some(("COMPANY_KEY", "APP_ID")),
  3. Add the slug to the COMPANY_SLUGS array
  4. Add an <option> in ui/login.html inside the company dropdown
  5. Rebuild, and the new company appears in the login screen

Don't know your company's key/app_id? Open an issue and we'll help figure it out.

Contributing

Want to add your company? See Adding a new company above. It's a one-line change and a great first PR.

Found a bug or have an idea? Open an issue and let's talk about it.

Want to submit code?

  1. Fork the repo
  2. Create a feature branch (git checkout -b feature/my-change)
  3. Commit your changes
  4. Open a Pull Request

License

MIT. See LICENSE for details.


BrAtUkA

About

Lightweight Rust Windows system-tray app for real-time Knox solar inverter monitoring || live dashboard || outage alerts || data history.... Supports any ShineMonitor/Eybond company. Tauri v2, ~3 MB RAM, runs 24/7.

Topics

Resources

License

Stars

Watchers

Forks

Contributors