Skip to content

Commit 16046bb

Browse files
feat: v2.1 — AI intelligence, RGB reliability, visual polish, zero warnings
AI & Intelligence: - AEDi knowledge engine: directed search with 27 entries, quick-ping navigation - Game Mode detector: 100+ games, GPU load correlation, thermal profiling - System Health Scorer: 0-100 score with A+ through Critical grades - Google Profile sync: upload/download fan profiles via Google Drive RGB Reliability: - Auto-start semaphore prevents double concurrent bootstrap - Watchdog lifecycle: proper CancellationToken, no orphan loops - Cleaner status messaging during auto-start and reconnect - Test RGB button: cycles R/G/B/White on all devices - Proper disposal of watchdog, lock, and cancellation tokens Build & Quality: - Zero warnings: CA1416 platform guards, CS8602 null check - AutoUpdateService: correct repo name (FANZi) and version (2.1.0) - NumericUpDown FormatString fix for degree symbol - Fixed build.ps1 PowerShell escaping issues Visual Enhancements: - Card hover transitions (border brush, shadow glow) - Button press states for primary/danger/success variants - Tab hover transitions with background shift - Profile tab hover animations - Enhanced hero panel gradient and glow - AEDi sidebar header glow effect - RGB preview orb stronger glow - Anomaly alert with red glow shadow - Version strings unified to v2.1
1 parent 262a3ec commit 16046bb

26 files changed

Lines changed: 2549 additions & 101 deletions

build.ps1

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ $PublishBase = "$PSScriptRoot\publish"
1515

1616
Write-Host ""
1717
Write-Host " ╔══════════════════════════════════════════╗" -ForegroundColor Blue
18-
Write-Host " ║ FANZI v2.0 — Build System ║" -ForegroundColor Blue
19-
Write-Host " ║ Ionity Global (Pty) Ltd ║" -ForegroundColor DarkGray
18+
Write-Host " ║ FANZI v2.1 — Build System ║" -ForegroundColor Blue
19+
Write-Host " ║ Ionity Global Pty Ltd " -ForegroundColor DarkGray
2020
Write-Host " ╚══════════════════════════════════════════╝" -ForegroundColor Blue
2121
Write-Host ""
2222

@@ -55,7 +55,7 @@ function Publish-Runtime {
5555
$exe = Get-ChildItem "$outDir\Fanzi.FanControl*" | Where-Object { $_.Extension -in ".exe", "" } | Select-Object -First 1
5656
if ($exe) {
5757
$sizeMB = [math]::Round($exe.Length / 1MB, 1)
58-
Write-Host "[DONE] $Rid -> $($exe.Name) ($sizeMB MB)" -ForegroundColor Green
58+
Write-Host "[DONE] $Rid -> $($exe.Name) - $sizeMB MB" -ForegroundColor Green
5959
}
6060
}
6161

@@ -90,14 +90,14 @@ if ($Installer) {
9090
$installerExe = Get-ChildItem "$installerOut\FANZI-Installer*" | Select-Object -First 1
9191
if ($installerExe) {
9292
$sizeMB = [math]::Round($installerExe.Length / 1MB, 1)
93-
Write-Host "[DONE] Installer -> $($installerExe.Name) ($sizeMB MB)" -ForegroundColor Green
93+
Write-Host "[DONE] Installer -> $($installerExe.Name) - $sizeMB MB" -ForegroundColor Green
9494
}
9595

9696
Write-Host ""
97-
Write-Host " Installer output: $installerOut\" -ForegroundColor Yellow
97+
Write-Host " Installer output: $installerOut" -ForegroundColor Yellow
9898
}
9999

100100
Write-Host ""
101101
Write-Host " Build complete!" -ForegroundColor Green
102-
Write-Host " Output: $PublishBase\" -ForegroundColor Gray
102+
Write-Host " Output: $PublishBase" -ForegroundColor Gray
103103
Write-Host ""
Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace Fanzi.FanControl.AI;
6+
7+
/// <summary>
8+
/// AEDi — Antwerp Ecosystems Designs Ionity — Knowledge-Base Search &amp; Ping Engine.
9+
/// Not a chatbot. A directed search AI that maps user queries to application sections,
10+
/// provides instant guidance, and navigates the user to exactly where they need to be.
11+
/// </summary>
12+
public sealed class AediKnowledgeEngine
13+
{
14+
private readonly List<AediEntry> _entries = new();
15+
16+
public IReadOnlyList<AediEntry> Entries => _entries;
17+
18+
public AediKnowledgeEngine()
19+
{
20+
BuildKnowledgeBase();
21+
}
22+
23+
public IReadOnlyList<AediSearchResult> Search(string query)
24+
{
25+
if (string.IsNullOrWhiteSpace(query))
26+
return Array.Empty<AediSearchResult>();
27+
28+
string q = query.ToLowerInvariant().Trim();
29+
string[] terms = q.Split(' ', StringSplitOptions.RemoveEmptyEntries);
30+
31+
var results = new List<AediSearchResult>();
32+
33+
foreach (var entry in _entries)
34+
{
35+
int score = 0;
36+
37+
// Exact title match
38+
if (entry.Title.ToLowerInvariant().Contains(q))
39+
score += 50;
40+
41+
// Keyword matches
42+
foreach (var keyword in entry.Keywords)
43+
{
44+
if (keyword.Contains(q)) score += 30;
45+
foreach (var term in terms)
46+
{
47+
if (keyword.Contains(term)) score += 10;
48+
if (term.Contains(keyword)) score += 5;
49+
}
50+
}
51+
52+
// Description match
53+
if (entry.Description.ToLowerInvariant().Contains(q))
54+
score += 20;
55+
foreach (var term in terms)
56+
{
57+
if (entry.Description.ToLowerInvariant().Contains(term))
58+
score += 5;
59+
}
60+
61+
// Section match
62+
if (entry.Section.ToLowerInvariant().Contains(q))
63+
score += 15;
64+
65+
if (score > 0)
66+
results.Add(new AediSearchResult(entry, score));
67+
}
68+
69+
return results.OrderByDescending(r => r.Score).Take(8).ToList();
70+
}
71+
72+
public AediSearchResult? Ping(string quickCommand)
73+
{
74+
string cmd = quickCommand.ToLowerInvariant().Trim();
75+
76+
// Direct navigation commands
77+
var direct = cmd switch
78+
{
79+
"dashboard" or "home" or "main" => "Dashboard",
80+
"fans" or "fan" or "speed" or "rpm" => "Fans",
81+
"sensors" or "temp" or "temperature" or "cpu" or "gpu" => "Sensors",
82+
"rgb" or "light" or "color" or "led" => "RGB Control",
83+
"tasks" or "process" or "kill" or "end task" or "task manager" => "Tasks",
84+
"network" or "net" or "bandwidth" or "download" or "upload" or "port" => "Network",
85+
"power" or "watt" or "energy" or "drive" => "Power",
86+
"clean" or "cleaner" or "cache" or "temp" or "ram" or "dns" => "System Cleaner",
87+
"alert" or "warning" or "email" or "notify" => "Alerts",
88+
"settings" or "config" or "option" => "Settings",
89+
"health" or "score" or "grade" => "Dashboard",
90+
"game" or "gaming" => "Dashboard",
91+
"overlay" or "mini" or "small" => "Overlay",
92+
"about" or "ionity" or "aedi" or "who" => "About",
93+
"help" or "?" or "how" => "Help",
94+
_ => null
95+
};
96+
97+
if (direct is not null)
98+
{
99+
var entry = _entries.FirstOrDefault(e => e.Section == direct);
100+
if (entry is not null)
101+
return new AediSearchResult(entry, 100);
102+
}
103+
104+
return null;
105+
}
106+
107+
private void BuildKnowledgeBase()
108+
{
109+
// Dashboard
110+
_entries.Add(new AediEntry("Dashboard", "Main overview",
111+
"System health score, CPU/GPU temperatures, fan speeds, AI status, game mode detection",
112+
new[] { "dashboard", "home", "overview", "main", "health", "score", "game", "gaming", "status", "temp", "cpu", "gpu", "fan" },
113+
0,
114+
"Navigate to Dashboard"));
115+
116+
_entries.Add(new AediEntry("Health Score", "IO-nity System Health",
117+
"Real-time 0-100 health grade (A+ to Critical). Analyzes thermal efficiency, dust buildup, fan health, stability.",
118+
new[] { "health", "score", "grade", "a+", "critical", "efficiency", "dust", "stability" },
119+
0,
120+
"Check health score on Dashboard"));
121+
122+
_entries.Add(new AediEntry("Game Mode", "Auto game detection",
123+
"Detects 100+ games automatically. Suggests optimal fan profiles and RGB presets for gaming.",
124+
new[] { "game", "gaming", "fortnite", "valorant", "csgo", "game mode", "fps", "competitive" },
125+
0,
126+
"Game Mode on Dashboard"));
127+
128+
// Fans
129+
_entries.Add(new AediEntry("Fan Control", "Manual & AI fan speed",
130+
"Set fan speeds per channel. AI auto-fan with 9 presets: Silent, Balanced, Performance, Gaming, Streaming, Workstation, Overclock, Zero-RPM, Linear.",
131+
new[] { "fan", "fans", "speed", "rpm", "pwm", "control", "manual", "auto", "preset", "silent", "balanced", "performance", "curve" },
132+
1,
133+
"Go to Fans tab"));
134+
135+
_entries.Add(new AediEntry("Fan Curves", "Temperature-to-speed mapping",
136+
"Custom fan curves with temperature points. Presets for different use cases. AI learns your thermal profile.",
137+
new[] { "curve", "fan curve", "temperature", "points", "custom", "preset", "thermal" },
138+
1, "Fan Curves in Fans tab"));
139+
140+
_entries.Add(new AediEntry("AEDi AI Engine", "Antwerp Ecosystems Designs Ionity",
141+
"The AEDi AI engine powers thermal prediction, anomaly detection, acoustic smoothing, game detection, and health scoring. Built by Ionity Global.",
142+
new[] { "aedi", "ai", "engine", "ionity", "antwerp", "ecosystems", "designs", "intelligence", "prediction", "anomaly" },
143+
0, "AEDi status on Dashboard"));
144+
145+
// Sensors
146+
_entries.Add(new AediEntry("Sensors", "Hardware sensor readings",
147+
"CPU package/avg/hotspot temps, GPU temps, voltages, clocks, power draw, per-core readings. All from LibreHardwareMonitor.",
148+
new[] { "sensor", "sensors", "temperature", "temp", "voltage", "clock", "power", "watt", "core", "package", "hotspot", "cpu", "gpu" },
149+
2, "Go to Sensors tab"));
150+
151+
// RGB
152+
_entries.Add(new AediEntry("RGB Control", "Lighting effects & themes",
153+
"9 effects: Static, Pulse, Rainbow, ColorWave, TemperatureReactive, CpuLoadReactive, Performance, Strobe, DualColorFlash. 12 theme presets. Per-zone control.",
154+
new[] { "rgb", "light", "lighting", "color", "colour", "led", "effect", "theme", "pulse", "rainbow", "wave", "strobe", "zone", "openrgb" },
155+
3, "Go to RGB Control tab"));
156+
157+
_entries.Add(new AediEntry("OpenRGB", "RGB server integration",
158+
"FANZi auto-starts OpenRGB server on launch. Connects to port 6742. Auto-downloads if not installed. Watchdog auto-reconnects.",
159+
new[] { "openrgb", "rgb server", "sdk", "port 6742", "connect", "device", "auto start" },
160+
3, "RGB server status in RGB tab"));
161+
162+
_entries.Add(new AediEntry("RGB Themes", "Preset lighting themes",
163+
"Ocean, Inferno, Glacier, Neon, Nature, Sunset, Spectrum, Blood Moon, Arctic, Temp Reactive, Performance, Strobe.",
164+
new[] { "theme", "preset", "ocean", "inferno", "glacier", "neon", "nature", "sunset", "spectrum", "blood moon", "arctic" },
165+
3, "Theme presets in RGB tab"));
166+
167+
// Tasks
168+
_entries.Add(new AediEntry("Task Manager", "Process management",
169+
"View all processes with CPU%, memory, threads, handles. Multi-select and End Task. Filter by name. Kill process trees.",
170+
new[] { "task", "tasks", "process", "processes", "kill", "end task", "cpu", "memory", "ram", "multi select", "filter" },
171+
4, "Go to Tasks tab"));
172+
173+
_entries.Add(new AediEntry("End Task", "Kill processes",
174+
"Select one or multiple processes and click End Task to kill them. Supports process tree killing. Select All / Select None buttons.",
175+
new[] { "end task", "kill", "terminate", "close", "stop", "process", "multi select", "select all" },
176+
4, "End Task in Tasks tab"));
177+
178+
// Network
179+
_entries.Add(new AediEntry("Network Manager", "Bandwidth & port monitoring",
180+
"Per-adapter throughput, TOP downloaders/uploaders, process groups, port scanner, speed limits. NetLimiter-style bandwidth control.",
181+
new[] { "network", "net", "bandwidth", "download", "upload", "speed", "port", "scanner", "limit", "throttle", "netlimiter", "adapter" },
182+
5, "Go to Network tab"));
183+
184+
_entries.Add(new AediEntry("Port Scanner", "Scan TCP ports",
185+
"Scan any host:port range. Shows open/closed/filtered status with process ownership. Close ports by killing owning process.",
186+
new[] { "port", "ports", "scan", "scanner", "tcp", "open", "closed", "filtered", "listening", "close port" },
187+
5, "Port Scanner in Network tab"));
188+
189+
_entries.Add(new AediEntry("Speed Limit", "Bandwidth throttling",
190+
"Apply download/upload speed limits per process or process group. Uses Windows QoS policies. Requires admin.",
191+
new[] { "speed limit", "bandwidth", "throttle", "limit", "download limit", "upload limit", "qos", "kbps" },
192+
5, "Speed Limits in Network tab"));
193+
194+
_entries.Add(new AediEntry("Process Groups", "Grouped bandwidth control",
195+
"Premade groups: Browsers, Gaming, Streaming, Downloads, Communication. Create custom groups. Apply limits to entire group at once.",
196+
new[] { "group", "groups", "browsers", "gaming", "streaming", "downloads", "communication", "custom group", "process group" },
197+
5, "Process Groups in Network tab"));
198+
199+
// Power
200+
_entries.Add(new AediEntry("Power Monitor", "Energy & drive monitoring",
201+
"Per-component power draw (CPU, GPU, RAM, PSU). Drive info with size/free/format. Quick-launch Device Manager, Disk Management.",
202+
new[] { "power", "watt", "energy", "draw", "component", "drive", "disk", "storage", "device manager" },
203+
6, "Go to Power tab"));
204+
205+
// System Cleaner
206+
_entries.Add(new AediEntry("System Cleaner", "Cache & temp file cleanup",
207+
"RAM trim, DNS flush, TEMP cleaner, cache flusher, browser caches, Windows Update cache, recycle bin, prefetch. 20+ clean targets.",
208+
new[] { "clean", "cleaner", "cache", "temp", "ram", "dns", "flush", "recycle", "prefetch", "browser", "junk", "free space" },
209+
7, "Go to System Cleaner tab"));
210+
211+
_entries.Add(new AediEntry("RAM Cleaner", "Memory trim",
212+
"Trims all process working sets to free physical RAM. Uses EmptyWorkingSet API. Instant memory recovery.",
213+
new[] { "ram", "memory", "trim", "clean", "free", "working set", "physical memory" },
214+
7, "RAM Cleaner in System Cleaner"));
215+
216+
_entries.Add(new AediEntry("DNS Cleaner", "Flush DNS cache",
217+
"Flushes the Windows DNS resolver cache. Fixes stale DNS entries and connectivity issues.",
218+
new[] { "dns", "flush", "cache", "resolver", "network", "connectivity" },
219+
7, "DNS Flush in System Cleaner"));
220+
221+
_entries.Add(new AediEntry("Temp Cleaner", "Temporary file removal",
222+
"Cleans user temp, Windows temp, prefetch, browser caches (Chrome, Edge, Firefox, Brave), app caches (Teams, Discord, Spotify, NVIDIA).",
223+
new[] { "temp", "temporary", "clean", "prefetch", "browser cache", "chrome", "edge", "firefox", "teams", "discord" },
224+
7, "Temp Cleaner in System Cleaner"));
225+
226+
_entries.Add(new AediEntry("Deep Cleaner", "Registry & startup manager",
227+
"Installed programs uninstaller, startup entry manager, registry orphan scanner, privacy wipe, disk analyzer, duplicate file finder.",
228+
new[] { "deep", "registry", "startup", "uninstall", "programs", "privacy", "disk analyzer", "duplicate", "orphan" },
229+
7, "Deep Cleaner in System Cleaner"));
230+
231+
// Alerts
232+
_entries.Add(new AediEntry("Email Alerts", "Thermal notification emails",
233+
"SMTP email alerts when CPU temperature exceeds threshold. Configure SMTP host, port, credentials. Test email button. 10-minute cooldown.",
234+
new[] { "email", "alert", "notification", "smtp", "warning", "thermal", "threshold", "gmail", "outlook" },
235+
8, "Go to Alerts tab"));
236+
237+
// Settings
238+
_entries.Add(new AediEntry("Settings", "Application configuration",
239+
"Start with Windows, minimize to tray, close to tray, polling interval, AI auto-fan, anomaly detection, overlay transparency, tab visibility.",
240+
new[] { "settings", "config", "startup", "tray", "polling", "overlay", "transparent", "tab", "visibility" },
241+
9, "Go to Settings tab"));
242+
243+
_entries.Add(new AediEntry("Overlay", "Mini transparent overlay",
244+
"Always-on-top mini window showing CPU temp, GPU temp, fan speed, load. Draggable. Toggle transparency on/off in Settings.",
245+
new[] { "overlay", "mini", "small", "transparent", "opacity", "always on top", "floating", "widget" },
246+
9, "Overlay settings in Settings tab"));
247+
248+
// About
249+
_entries.Add(new AediEntry("About FANZi IO-nity", "Ionity Global",
250+
"FANZi IO-nity by Ionity Global (Pty) Ltd. AI Thermal Intelligence powered by AEDi (Antwerp Ecosystems Designs Ionity). www.ionity.co.za",
251+
new[] { "about", "ionity", "aedi", "antwerp", "ecosystems", "designs", "website", "www", "pty", "ltd", "johan", "van antwerp" },
252+
9, "About — www.ionity.co.za"));
253+
254+
// Help
255+
_entries.Add(new AediEntry("Getting Started", "Quick start guide",
256+
"1) Run as Administrator. 2) Dashboard shows health + temps. 3) Fans tab for speed control. 4) RGB tab for lighting. 5) Settings for preferences.",
257+
new[] { "help", "start", "getting started", "how to", "guide", "begin", "first", "admin", "administrator" },
258+
0, "Dashboard — Getting Started"));
259+
260+
_entries.Add(new AediEntry("Administrator", "Why admin is needed",
261+
"LibreHardwareMonitor requires ring-0 kernel driver access to read CPU/GPU temperature sensors. Run FANZi as Administrator for full functionality.",
262+
new[] { "admin", "administrator", "elevated", "permission", "ring 0", "kernel", "driver", "access denied" },
263+
0, "Run as Administrator"));
264+
}
265+
}
266+
267+
public sealed class AediEntry
268+
{
269+
public string Title { get; }
270+
public string Section { get; }
271+
public string Description { get; }
272+
public string[] Keywords { get; }
273+
public int TabIndex { get; }
274+
public string Action { get; }
275+
276+
public AediEntry(string title, string section, string description, string[] keywords, int tabIndex, string action)
277+
{
278+
Title = title;
279+
Section = section;
280+
Description = description;
281+
Keywords = keywords;
282+
TabIndex = tabIndex;
283+
Action = action;
284+
}
285+
}
286+
287+
public sealed record AediSearchResult(AediEntry Entry, int Score)
288+
{
289+
public string DisplayTitle => Entry.Title;
290+
public string DisplaySection => Entry.Section;
291+
public string DisplayDescription => Entry.Description;
292+
public string DisplayAction => Entry.Action;
293+
public int TargetTab => Entry.TabIndex;
294+
}

0 commit comments

Comments
 (0)