From e7f8aacc341131840237a27b979cb5b594d67e77 Mon Sep 17 00:00:00 2001 From: Yinyin Liu Date: Fri, 6 Feb 2026 12:57:12 +0100 Subject: [PATCH] Integrate AI on Alarm --- csharp/App/Backend/Controller.cs | 84 +- csharp/App/Backend/Program.cs | 2 + .../App/Backend/Resources/openAiConfig.json | 3 + .../Backend/Services/AlarmKnowledgeBase.cs | 1514 +++++++++++++++++ .../App/Backend/Services/DiagnosticService.cs | 188 ++ .../src/content/dashboards/Log/Log.tsx | 355 +++- .../src/interfaces/S3Types.tsx | 6 + 7 files changed, 2148 insertions(+), 4 deletions(-) create mode 100644 csharp/App/Backend/Resources/openAiConfig.json create mode 100644 csharp/App/Backend/Services/AlarmKnowledgeBase.cs create mode 100644 csharp/App/Backend/Services/DiagnosticService.cs diff --git a/csharp/App/Backend/Controller.cs b/csharp/App/Backend/Controller.cs index 41c7f70c6..86c87633d 100644 --- a/csharp/App/Backend/Controller.cs +++ b/csharp/App/Backend/Controller.cs @@ -5,6 +5,7 @@ using InnovEnergy.App.Backend.Database; using InnovEnergy.App.Backend.DataTypes; using InnovEnergy.App.Backend.DataTypes.Methods; using InnovEnergy.App.Backend.Relations; +using InnovEnergy.App.Backend.Services; using InnovEnergy.App.Backend.Websockets; using InnovEnergy.Lib.Utils; using Microsoft.AspNetCore.Mvc; @@ -736,7 +737,88 @@ public class Controller : ControllerBase ? Ok() : Unauthorized(); } - + + /// + /// Returns an AI-generated diagnosis for a single error/alarm description. + /// Responses are cached in memory — repeated calls for the same error code + /// do not hit OpenAI again. + /// + [HttpGet(nameof(DiagnoseError))] + public async Task> DiagnoseError(Int64 installationId, string errorDescription, Token authToken) + { + var user = Db.GetSession(authToken)?.User; + if (user == null) + return Unauthorized(); + + var installation = Db.GetInstallationById(installationId); + if (installation is null || !user.HasAccessTo(installation)) + return Unauthorized(); + + // AI diagnostics are scoped to SodistoreHome and SodiStoreMax only + if (installation.Product != (int)ProductType.SodioHome && + installation.Product != (int)ProductType.SodiStoreMax) + return BadRequest("AI diagnostics not available for this product."); + + if (!DiagnosticService.IsEnabled) + return StatusCode(503, "AI diagnostics not configured."); + + var result = await DiagnosticService.DiagnoseAsync(installationId, errorDescription); + + if (result is null) + return StatusCode(500, "Diagnosis failed – please try again later."); + + return result; + } + + /// + /// Test endpoint for AlarmKnowledgeBase - no authentication required. + /// Tests multiple Sinexcel and Growatt alarms to verify the knowledge base works. + /// Remove this endpoint in production if not needed. + /// + [HttpGet(nameof(TestAlarmKnowledgeBase))] + public ActionResult TestAlarmKnowledgeBase() + { + var testCases = new[] + { + // Sinexcel alarms + "Fan fault", + "Abnormal grid voltage", + "Battery 1not connected", + "Inverter power tube fault", + "Island protection", + // Growatt alarms + "Warning 300", + "Warning 500", + "Error 408", + "AFCI Fault", + // Unknown alarm (should return null - would call OpenAI) + "Some unknown alarm XYZ123" + }; + + var results = new List(); + foreach (var alarm in testCases) + { + var diagnosis = AlarmKnowledgeBase.TryGetDiagnosis(alarm); + results.Add(new + { + Alarm = alarm, + FoundInKnowledgeBase = diagnosis != null, + Explanation = diagnosis?.Explanation ?? "NOT FOUND - Would call OpenAI API", + CausesCount = diagnosis?.Causes.Count ?? 0, + NextStepsCount = diagnosis?.NextSteps.Count ?? 0 + }); + } + + return Ok(new + { + TestTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), + TotalTests = testCases.Length, + FoundInKnowledgeBase = results.Count(r => ((dynamic)r).FoundInKnowledgeBase), + WouldCallOpenAI = results.Count(r => !((dynamic)r).FoundInKnowledgeBase), + Results = results + }); + } + [HttpPut(nameof(UpdateFolder))] public ActionResult UpdateFolder([FromBody] Folder folder, Token authToken) { diff --git a/csharp/App/Backend/Program.cs b/csharp/App/Backend/Program.cs index 94f20f312..56208e0f1 100644 --- a/csharp/App/Backend/Program.cs +++ b/csharp/App/Backend/Program.cs @@ -2,6 +2,7 @@ using System.Diagnostics; using Flurl.Http; using Hellang.Middleware.ProblemDetails; using InnovEnergy.App.Backend.Database; +using InnovEnergy.App.Backend.Services; using InnovEnergy.App.Backend.Websockets; using InnovEnergy.App.Backend.DeleteOldData; using Microsoft.AspNetCore.HttpOverrides; @@ -24,6 +25,7 @@ public static class Program Watchdog.NotifyReady(); Db.Init(); + DiagnosticService.Initialize(); var builder = WebApplication.CreateBuilder(args); RabbitMqManager.InitializeEnvironment(); diff --git a/csharp/App/Backend/Resources/openAiConfig.json b/csharp/App/Backend/Resources/openAiConfig.json new file mode 100644 index 000000000..43338afc4 --- /dev/null +++ b/csharp/App/Backend/Resources/openAiConfig.json @@ -0,0 +1,3 @@ +{ + "ApiKey": "sk-your-openai-api-key-here" +} diff --git a/csharp/App/Backend/Services/AlarmKnowledgeBase.cs b/csharp/App/Backend/Services/AlarmKnowledgeBase.cs new file mode 100644 index 000000000..09507fc87 --- /dev/null +++ b/csharp/App/Backend/Services/AlarmKnowledgeBase.cs @@ -0,0 +1,1514 @@ +using System.Collections.Frozen; + +namespace InnovEnergy.App.Backend.Services; + +/// +/// Static knowledge base for Sinexcel and Growatt alarms. +/// Provides pre-defined diagnostics without requiring OpenAI API calls. +/// Data sourced from vendor alarm documentation. +/// +public static class AlarmKnowledgeBase +{ + /// + /// Tries to find a pre-defined diagnostic for the given alarm description. + /// Returns null if the alarm is not in the knowledge base. + /// + public static DiagnosticResponse? TryGetDiagnosis(string alarmDescription) + { + if (string.IsNullOrWhiteSpace(alarmDescription)) + return null; + + // Normalize the description for lookup + var normalized = alarmDescription.Trim(); + + // Try exact match first + if (SinexcelAlarms.TryGetValue(normalized, out var sinexcelDiag)) + return sinexcelDiag; + + if (GrowattAlarms.TryGetValue(normalized, out var growattDiag)) + return growattDiag; + + // Try case-insensitive match for Sinexcel (alarm names may vary in casing) + var lowerDesc = normalized.ToLowerInvariant(); + foreach (var kvp in SinexcelAlarms) + { + if (kvp.Key.ToLowerInvariant() == lowerDesc) + return kvp.Value; + } + + return null; + } + + // ── Sinexcel Alarms ────────────────────────────────────────────────────── + // Register addresses: 0x1048 - 0x10D5 + // Recovery types: AUTO (wait), MANUAL (fix and restart), SERVICE (contact service) + + private static readonly FrozenDictionary SinexcelAlarms = new Dictionary + { + // Grid-related alarms + ["Abnormal grid voltage"] = new() + { + Explanation = "The inverter has detected that the grid voltage is outside the acceptable operating range. This is an ERROR level condition requiring manual intervention.", + Causes = new[] { "Utility grid voltage fluctuation", "Poor grid connection", "Local transformer issues", "High load demand on grid" }, + NextSteps = new[] { "Check the grid voltage with a multimeter", "Verify grid connection wiring", "Fix the underlying cause", "Restart the inverter after the issue is resolved" } + }, + ["Abnormal grid frequency"] = new() + { + Explanation = "The inverter has detected that the grid frequency is outside the acceptable range (typically 50Hz or 60Hz +/- tolerance). This is an ERROR level condition.", + Causes = new[] { "Grid instability", "Generator frequency drift", "Local grid issues" }, + NextSteps = new[] { "Check grid frequency stability", "If using a generator, verify its frequency setting", "Fix the cause, then restart the inverter" } + }, + ["Inverted sequenceof grid voltage"] = new() + { + Explanation = "The phase sequence of the three-phase grid voltage is reversed. This is a WARNING level condition.", + Causes = new[] { "Incorrect wiring of grid phases (L1, L2, L3)", "Installation error" }, + NextSteps = new[] { "Power off the system safely", "Swap any two phase wires to correct the sequence", "Restart the inverter" } + }, + ["Grid voltage phase loss"] = new() + { + Explanation = "One or more phases of the three-phase grid connection are missing. This is an ERROR level condition.", + Causes = new[] { "Blown fuse on one phase", "Loose connection on a phase wire", "Grid-side breaker tripped", "Cable damage" }, + NextSteps = new[] { "Check all three phase connections", "Verify fuses and breakers", "Fix the missing phase connection", "Restart after repair" } + }, + ["Abnormal grid current"] = new() + { + Explanation = "The grid current is abnormal, which may indicate overcurrent or current imbalance. This is an ERROR level condition.", + Causes = new[] { "Grid-side short circuit", "Overloaded system", "Faulty current sensor", "Ground fault" }, + NextSteps = new[] { "Check for short circuits", "Reduce system load", "Verify current sensor operation", "Fix the cause, then restart" } + }, + + // Output-related alarms + ["Abnormal output voltage"] = new() + { + Explanation = "The inverter's output voltage is outside acceptable limits. This is an ERROR level condition.", + Causes = new[] { "Internal inverter fault", "Overload condition", "Grid voltage influence" }, + NextSteps = new[] { "Check connected load", "Verify inverter settings", "Fix the cause, then restart the inverter" } + }, + ["Abnormal output frequency"] = new() + { + Explanation = "The inverter's output frequency is abnormal. This is an ERROR level condition.", + Causes = new[] { "Internal control system fault", "Heavy load transients" }, + NextSteps = new[] { "Reduce load if possible", "Fix the cause, then restart the inverter" } + }, + ["Abnormalnullline"] = new() + { + Explanation = "The neutral line connection is abnormal. This is an ERROR level condition.", + Causes = new[] { "Loose or missing neutral wire", "Neutral wire damage", "Incorrect wiring" }, + NextSteps = new[] { "Power off safely", "Check neutral wire connection", "Fix wiring issues", "Restart after repair" } + }, + ["Abnormaloff-grid output voltage"] = new() + { + Explanation = "The off-grid (backup) output voltage is abnormal. This is an ERROR level condition.", + Causes = new[] { "Overload on backup output", "Internal inverter issue", "Battery voltage too low" }, + NextSteps = new[] { "Check backup load", "Verify battery state", "Fix the cause, then restart" } + }, + + // Temperature alarms + ["Excessivelyhigh ambient temperature"] = new() + { + Explanation = "The ambient temperature around the inverter is too high. This is a WARNING - the inverter may reduce output to protect itself.", + Causes = new[] { "Poor ventilation", "High environmental temperature", "Direct sunlight exposure", "Enclosure overheating" }, + NextSteps = new[] { "Improve ventilation around the inverter", "Provide shade if outdoors", "Consider adding cooling", "Restart after temperature drops" } + }, + ["Excessive radiator temperature"] = new() + { + Explanation = "The inverter's heat sink/radiator temperature is too high. This is a WARNING level condition.", + Causes = new[] { "Blocked air vents", "Fan failure", "High ambient temperature", "Excessive load" }, + NextSteps = new[] { "Clean air vents and filters", "Check fan operation", "Reduce load temporarily", "Fix the cause, then restart" } + }, + ["PCBover temperature"] = new() + { + Explanation = "The printed circuit board temperature is too high. This is a WARNING level condition.", + Causes = new[] { "Poor cooling", "High ambient temperature", "Excessive power output" }, + NextSteps = new[] { "Improve ventilation", "Check fan operation", "Allow cooling before restart" } + }, + ["DC converter over temperature"] = new() + { + Explanation = "The DC converter section is overheating. This is a WARNING level condition.", + Causes = new[] { "High charging/discharging current", "Poor cooling", "Ambient temperature too high" }, + NextSteps = new[] { "Reduce power flow", "Improve ventilation", "Fix the cause, then restart" } + }, + ["Inverter over temperaturealarm"] = new() + { + Explanation = "The inverter temperature is approaching dangerous levels. This is a WARNING.", + Causes = new[] { "Overload", "Poor ventilation", "Fan failure", "High ambient temperature" }, + NextSteps = new[] { "Reduce load", "Check cooling system", "Fix the cause, then restart" } + }, + ["Inverter over temperature"] = new() + { + Explanation = "The inverter has overheated. This is a WARNING level condition.", + Causes = new[] { "Sustained overload", "Cooling system failure", "Environmental conditions" }, + NextSteps = new[] { "Allow inverter to cool down", "Check fans and ventilation", "Fix the cause, then restart" } + }, + ["DC converter over temperaturealarm"] = new() + { + Explanation = "The DC converter temperature alarm is active. This is a WARNING.", + Causes = new[] { "High power throughput", "Inadequate cooling" }, + NextSteps = new[] { "Reduce power flow temporarily", "Check cooling", "Fix the cause, then restart" } + }, + + // Insulation and safety alarms + ["Insulation fault"] = new() + { + Explanation = "An insulation fault has been detected, indicating possible current leakage to ground. This is an ERROR level safety condition.", + Causes = new[] { "Damaged cable insulation", "Moisture ingress", "Component insulation breakdown", "Ground fault in PV array" }, + NextSteps = new[] { "Do not touch the system", "Power off safely", "Check all cable insulation", "Test insulation resistance", "Repair before restart" } + }, + ["Leakage protection fault"] = new() + { + Explanation = "The ground fault/leakage current protection has tripped. This is an ERROR level safety condition.", + Causes = new[] { "Ground fault in the system", "Damaged insulation", "Moisture in connections", "Faulty RCD/GFCI" }, + NextSteps = new[] { "Power off the system", "Check for ground faults", "Inspect cable insulation", "Fix the cause before restart" } + }, + ["Abnormal leakage self-check"] = new() + { + Explanation = "The leakage current self-check has failed. This is an ERROR level condition.", + Causes = new[] { "Self-check circuit fault", "Ground fault present", "Sensor malfunction" }, + NextSteps = new[] { "Power off safely", "Check system grounding", "Fix the cause, then restart" } + }, + ["Poorgrounding"] = new() + { + Explanation = "Poor grounding connection detected. This is a WARNING level safety condition.", + Causes = new[] { "Loose ground connection", "Corroded ground terminal", "High ground resistance", "Missing ground wire" }, + NextSteps = new[] { "Check all ground connections", "Clean corroded terminals", "Verify ground resistance", "Fix grounding, then restart" } + }, + + // Fan and cooling alarms + ["Fan fault"] = new() + { + Explanation = "The cooling fan has failed or is not operating correctly. This is an ERROR level condition that can lead to overheating.", + Causes = new[] { "Fan motor failure", "Fan blade obstruction", "Loose fan connector", "Control circuit fault" }, + NextSteps = new[] { "Check fan operation visually", "Remove any obstructions", "Check fan power connection", "Replace fan if faulty" } + }, + + // Power supply alarms + ["Auxiliary power fault"] = new() + { + Explanation = "The auxiliary power supply inside the inverter has failed. This is an ERROR level condition.", + Causes = new[] { "Internal power supply failure", "Input voltage issue", "Component failure" }, + NextSteps = new[] { "Power cycle the inverter", "If persistent, contact service technician" } + }, + + // Model and configuration alarms + ["Model capacity fault"] = new() + { + Explanation = "The inverter has detected a model/capacity configuration mismatch. This is an ERROR level condition.", + Causes = new[] { "Incorrect model configuration", "Firmware mismatch", "Hardware mismatch" }, + NextSteps = new[] { "Verify inverter model settings", "Check firmware version", "Fix configuration, then restart" } + }, + + // Lightning and surge protection + ["Abnormal lightning arrester"] = new() + { + Explanation = "The surge protection device (lightning arrester) has failed or triggered. This is an ERROR level condition.", + Causes = new[] { "Lightning strike damage", "Surge event", "SPD component failure" }, + NextSteps = new[] { "Check SPD indicator", "Replace SPD if triggered", "Fix the cause, then restart" } + }, + + // Island protection + ["Island protection"] = new() + { + Explanation = "Island protection is active - the inverter has disconnected from the grid to prevent back-feeding during a grid outage. This is an INFO level condition that typically auto-recovers.", + Causes = new[] { "Grid power outage", "Grid voltage/frequency outside limits", "Intentional grid disconnection" }, + NextSteps = new[] { "Wait for grid to stabilize", "The inverter will automatically reconnect when grid is normal", "Monitor until it clears" } + }, + + // Battery 1 alarms + ["Battery 1not connected"] = new() + { + Explanation = "Battery 1 is not detected or not connected. This is an ERROR level condition.", + Causes = new[] { "Battery disconnect switch open", "Loose battery cable", "Battery BMS shutdown", "Battery fuse blown" }, + NextSteps = new[] { "Check battery disconnect switch", "Verify battery cable connections", "Check battery BMS status", "Fix connection, then restart" } + }, + ["Battery 1over voltage"] = new() + { + Explanation = "Battery 1 voltage is too high. This is a WARNING level condition - charging will be limited.", + Causes = new[] { "Overcharging", "BMS malfunction", "Incorrect battery voltage setting", "Cell imbalance" }, + NextSteps = new[] { "Check battery SOC", "Verify charging settings", "Check BMS operation", "Fix the cause, then restart" } + }, + ["Battery 1under voltage"] = new() + { + Explanation = "Battery 1 voltage is too low. This is a WARNING level condition - discharging will be limited.", + Causes = new[] { "Battery deeply discharged", "Cell failure", "BMS cutoff", "High load drain" }, + NextSteps = new[] { "Allow battery to charge", "Check for excessive loads", "Verify battery health", "Fix the cause, then restart" } + }, + ["Battery 1discharge end"] = new() + { + Explanation = "Battery 1 has reached its discharge end point (minimum SOC). This is an INFO level condition that auto-recovers when charged.", + Causes = new[] { "Battery fully discharged to SOC limit", "High power consumption" }, + NextSteps = new[] { "Wait for battery to recharge from PV or grid", "Monitor until it clears" } + }, + ["Battery 1inverted"] = new() + { + Explanation = "Battery 1 polarity is reversed. This is a WARNING level condition - do not operate!", + Causes = new[] { "Battery cables connected in reverse", "Installation error" }, + NextSteps = new[] { "IMMEDIATELY power off the system", "Correct battery cable polarity", "Check for damage before restart" } + }, + ["Battery 1over current"] = new() + { + Explanation = "Battery 1 current exceeds safe limits. This is a WARNING level condition.", + Causes = new[] { "Excessive load", "Short circuit", "Inverter control issue" }, + NextSteps = new[] { "Reduce load", "Check for short circuits", "Fix the cause, then restart" } + }, + ["Battery 1overload timeout"] = new() + { + Explanation = "Battery 1 has been overloaded for too long. This is an ERROR level condition.", + Causes = new[] { "Sustained high load", "Undersized battery", "Battery degradation" }, + NextSteps = new[] { "Reduce system load", "Check battery capacity", "Fix the cause, then restart" } + }, + ["Battery 1soft start failure"] = new() + { + Explanation = "Battery 1 failed to soft-start properly. This is a WARNING level condition.", + Causes = new[] { "Pre-charge circuit fault", "Battery voltage mismatch", "Contactor issue" }, + NextSteps = new[] { "Check battery voltage", "Verify pre-charge circuit", "Fix the cause, then restart" } + }, + ["Battery 1power tube fault"] = new() + { + Explanation = "Battery 1 power electronics (IGBT/MOSFET) have failed. This is a PROTECTION level condition requiring service.", + Causes = new[] { "Power semiconductor failure", "Overcurrent damage", "Manufacturing defect" }, + NextSteps = new[] { "Do not restart the system", "Contact service technician", "Hardware repair required" } + }, + ["Battery 1charging sealingwave"] = new() + { + Explanation = "Battery 1 charging seal pulse detected. This is a WARNING indicating charging is being limited.", + Causes = new[] { "Battery requesting charge termination", "BMS protection active" }, + NextSteps = new[] { "Check battery BMS status", "Fix the cause, then restart" } + }, + ["Battery 1insufficient power"] = new() + { + Explanation = "Battery 1 cannot provide sufficient power for the load. This is an INFO level condition.", + Causes = new[] { "Low state of charge", "High load demand", "Battery capacity limitation" }, + NextSteps = new[] { "Wait for battery to recharge", "Reduce load if possible", "Monitor until it clears" } + }, + ["Battery 1backup prohibited"] = new() + { + Explanation = "Battery 1 is prohibited from providing backup power. This is a WARNING level condition.", + Causes = new[] { "BMS protection active", "Battery in maintenance mode", "SOC too low for backup" }, + NextSteps = new[] { "Check BMS settings", "Verify battery SOC", "Fix the cause, then restart" } + }, + + // Battery 2 alarms (similar to Battery 1) + ["Battery 2not connected"] = new() + { + Explanation = "Battery 2 is not detected or not connected. This is an ERROR level condition.", + Causes = new[] { "Battery disconnect switch open", "Loose battery cable", "Battery BMS shutdown", "Battery fuse blown" }, + NextSteps = new[] { "Check battery disconnect switch", "Verify battery cable connections", "Check battery BMS status", "Fix connection, then restart" } + }, + ["Battery 2over voltage"] = new() + { + Explanation = "Battery 2 voltage is too high. This is a WARNING level condition.", + Causes = new[] { "Overcharging", "BMS malfunction", "Incorrect voltage setting" }, + NextSteps = new[] { "Check battery SOC", "Verify charging settings", "Fix the cause, then restart" } + }, + ["Battery 2under voltage"] = new() + { + Explanation = "Battery 2 voltage is too low. This is a WARNING level condition.", + Causes = new[] { "Battery deeply discharged", "Cell failure", "BMS cutoff" }, + NextSteps = new[] { "Allow battery to charge", "Check battery health", "Fix the cause, then restart" } + }, + ["Battery 2discharge end"] = new() + { + Explanation = "Battery 2 has reached its discharge end point. This is an INFO level condition.", + Causes = new[] { "Battery fully discharged to SOC limit" }, + NextSteps = new[] { "Wait for battery to recharge", "Monitor until it clears" } + }, + ["Battery 2inverted"] = new() + { + Explanation = "Battery 2 polarity is reversed. This is a WARNING - do not operate!", + Causes = new[] { "Battery cables connected in reverse" }, + NextSteps = new[] { "IMMEDIATELY power off", "Correct battery polarity", "Check for damage" } + }, + ["Battery 2over current"] = new() + { + Explanation = "Battery 2 current exceeds safe limits. This is a WARNING level condition.", + Causes = new[] { "Excessive load", "Short circuit" }, + NextSteps = new[] { "Reduce load", "Check for short circuits", "Fix the cause, then restart" } + }, + ["Battery 2overload timeout"] = new() + { + Explanation = "Battery 2 has been overloaded for too long. This is an ERROR level condition.", + Causes = new[] { "Sustained high load", "Battery degradation" }, + NextSteps = new[] { "Reduce system load", "Fix the cause, then restart" } + }, + ["Battery 2soft start failure"] = new() + { + Explanation = "Battery 2 failed to soft-start properly. This is a WARNING level condition.", + Causes = new[] { "Pre-charge circuit fault", "Voltage mismatch" }, + NextSteps = new[] { "Check battery voltage", "Fix the cause, then restart" } + }, + ["Battery 2power tube fault"] = new() + { + Explanation = "Battery 2 power electronics have failed. This is a PROTECTION level condition.", + Causes = new[] { "Power semiconductor failure" }, + NextSteps = new[] { "Do not restart", "Contact service technician" } + }, + ["Battery 2insufficiency power"] = new() + { + Explanation = "Battery 2 cannot provide sufficient power. This is a WARNING level condition.", + Causes = new[] { "Low SOC", "High load demand" }, + NextSteps = new[] { "Wait for recharge", "Reduce load", "Fix the cause, then restart" } + }, + ["Battery 2charging sealingwave"] = new() + { + Explanation = "Battery 2 charging seal pulse detected. This is a WARNING.", + Causes = new[] { "Battery requesting charge termination" }, + NextSteps = new[] { "Check BMS status", "Fix the cause, then restart" } + }, + ["Battery 2backup prohibited"] = new() + { + Explanation = "Battery 2 is prohibited from providing backup power. This is a WARNING.", + Causes = new[] { "BMS protection active", "SOC too low" }, + NextSteps = new[] { "Check BMS settings", "Fix the cause, then restart" } + }, + + // Lithium battery specific alarms + ["Lithium battery 1 chargeforbidden"] = new() + { + Explanation = "Lithium battery 1 BMS has forbidden charging. This is a WARNING level condition.", + Causes = new[] { "Battery fully charged", "Temperature out of range", "BMS protection active", "Cell imbalance" }, + NextSteps = new[] { "Check battery temperature", "Verify BMS status", "Fix the cause, then restart" } + }, + ["Lithium battery 1 dischargeforbidden"] = new() + { + Explanation = "Lithium battery 1 BMS has forbidden discharging. This is a WARNING level condition.", + Causes = new[] { "Battery empty", "Temperature out of range", "BMS protection", "Low voltage protection" }, + NextSteps = new[] { "Allow battery to charge", "Check temperature", "Fix the cause, then restart" } + }, + ["Lithium battery 2 chargeforbidden"] = new() + { + Explanation = "Lithium battery 2 BMS has forbidden charging. This is a WARNING level condition.", + Causes = new[] { "Battery fully charged", "Temperature out of range", "BMS protection" }, + NextSteps = new[] { "Check battery status", "Fix the cause, then restart" } + }, + ["Lithium battery 2 dischargeforbidden"] = new() + { + Explanation = "Lithium battery 2 BMS has forbidden discharging. This is a WARNING level condition.", + Causes = new[] { "Battery empty", "Temperature out of range", "BMS protection" }, + NextSteps = new[] { "Allow battery to charge", "Fix the cause, then restart" } + }, + ["Lithium battery 1full"] = new() + { + Explanation = "Lithium battery 1 is fully charged. This is a WARNING indicating charging will stop.", + Causes = new[] { "Battery at 100% SOC", "Cell voltage at maximum" }, + NextSteps = new[] { "Normal condition if intentional", "Monitor battery health" } + }, + ["Lithium battery 1 dischargeend"] = new() + { + Explanation = "Lithium battery 1 has reached discharge end. This is a WARNING.", + Causes = new[] { "Battery at minimum SOC" }, + NextSteps = new[] { "Allow battery to recharge", "Fix the cause, then restart" } + }, + ["Lithium battery 2full"] = new() + { + Explanation = "Lithium battery 2 is fully charged. This is a WARNING.", + Causes = new[] { "Battery at 100% SOC" }, + NextSteps = new[] { "Normal condition if intentional" } + }, + ["Lithium battery 2 dischargeend"] = new() + { + Explanation = "Lithium battery 2 has reached discharge end. This is a WARNING.", + Causes = new[] { "Battery at minimum SOC" }, + NextSteps = new[] { "Allow battery to recharge" } + }, + ["Lead battery temperature abnormality"] = new() + { + Explanation = "Lead-acid battery temperature is abnormal. This is an ERROR level condition.", + Causes = new[] { "Overheating", "Temperature sensor fault", "Environmental temperature extreme" }, + NextSteps = new[] { "Check battery temperature", "Verify sensor", "Fix the cause, then restart" } + }, + ["Batteryaccessmethod error"] = new() + { + Explanation = "Battery access method configuration error. This is a WARNING.", + Causes = new[] { "Incorrect configuration", "Communication setup error" }, + NextSteps = new[] { "Check battery configuration", "Fix the cause, then restart" } + }, + + // PV 1 alarms + ["PV 1notaccessed"] = new() + { + Explanation = "PV string 1 is not detected or accessible. This is a WARNING level condition.", + Causes = new[] { "PV disconnector open", "Cable damage", "PV module fault", "No sunlight" }, + NextSteps = new[] { "Check PV disconnector", "Verify PV cable connections", "Check for shading", "Fix the cause, then restart" } + }, + ["PV 1over voltage"] = new() + { + Explanation = "PV string 1 voltage exceeds maximum input voltage. This is a WARNING - PV input will be limited.", + Causes = new[] { "Too many PV modules in series", "Low temperature increasing voltage", "Design error" }, + NextSteps = new[] { "Check PV string configuration", "Verify Voc at low temperature", "Reduce modules if needed" } + }, + ["AbnormalPV 1current sharing"] = new() + { + Explanation = "PV string 1 current sharing is abnormal. This is an ERROR level condition.", + Causes = new[] { "Mismatched PV modules", "Partial shading", "Module fault" }, + NextSteps = new[] { "Check for shading", "Verify module matching", "Fix the cause, then restart" } + }, + ["PV 1power tube fault"] = new() + { + Explanation = "PV 1 DC converter power electronics have failed. This is a PROTECTION level condition.", + Causes = new[] { "IGBT/MOSFET failure", "Overcurrent damage" }, + NextSteps = new[] { "Do not restart", "Contact service technician" } + }, + ["PV 1soft startfailure"] = new() + { + Explanation = "PV 1 failed to soft-start properly. This is a WARNING level condition.", + Causes = new[] { "Pre-charge circuit fault", "Voltage mismatch" }, + NextSteps = new[] { "Check PV voltage", "Fix the cause, then restart" } + }, + ["PV 1overload timeout"] = new() + { + Explanation = "PV 1 has been overloaded for too long. This is an ERROR level condition.", + Causes = new[] { "Excessive PV power", "DC converter limitation" }, + NextSteps = new[] { "Check PV sizing", "Fix the cause, then restart" } + }, + ["PV 1insufficient power"] = new() + { + Explanation = "PV string 1 is not providing enough power. This is an INFO level condition.", + Causes = new[] { "Low irradiance", "Shading", "Cloud cover", "Evening/morning" }, + NextSteps = new[] { "Wait for better sunlight conditions", "Check for shading", "Monitor until it clears" } + }, + ["Photovoltaic 1 over current"] = new() + { + Explanation = "PV string 1 current exceeds limits. This is a WARNING level condition.", + Causes = new[] { "PV array oversized", "Ground fault", "Short circuit" }, + NextSteps = new[] { "Check PV configuration", "Look for ground faults", "Fix the cause, then restart" } + }, + + // PV 2 alarms + ["PV 2notaccessed"] = new() + { + Explanation = "PV string 2 is not detected or accessible. This is a WARNING level condition.", + Causes = new[] { "PV disconnector open", "Cable damage", "No sunlight" }, + NextSteps = new[] { "Check PV disconnector", "Verify connections", "Fix the cause, then restart" } + }, + ["PV 2over voltage"] = new() + { + Explanation = "PV string 2 voltage exceeds maximum. This is a WARNING level condition.", + Causes = new[] { "Too many PV modules in series", "Low temperature" }, + NextSteps = new[] { "Check PV configuration", "Reduce modules if needed" } + }, + ["AbnormalPV 2current sharing"] = new() + { + Explanation = "PV string 2 current sharing is abnormal. This is an ERROR level condition.", + Causes = new[] { "Mismatched modules", "Partial shading" }, + NextSteps = new[] { "Check for shading", "Fix the cause, then restart" } + }, + ["PV 2power tube fault"] = new() + { + Explanation = "PV 2 power electronics have failed. This is a PROTECTION level condition.", + Causes = new[] { "Power semiconductor failure" }, + NextSteps = new[] { "Do not restart", "Contact service technician" } + }, + ["PV 2soft startfailure"] = new() + { + Explanation = "PV 2 failed to soft-start. This is a WARNING level condition.", + Causes = new[] { "Pre-charge fault", "Voltage mismatch" }, + NextSteps = new[] { "Check PV voltage", "Fix the cause, then restart" } + }, + ["PV 2overload timeout"] = new() + { + Explanation = "PV 2 has been overloaded for too long. This is an ERROR level condition.", + Causes = new[] { "Excessive PV power" }, + NextSteps = new[] { "Check PV sizing", "Fix the cause, then restart" } + }, + ["PV 2insufficient power"] = new() + { + Explanation = "PV string 2 is not providing enough power. This is an INFO level condition.", + Causes = new[] { "Low irradiance", "Shading" }, + NextSteps = new[] { "Wait for better conditions", "Monitor until it clears" } + }, + ["Photovoltaic 2 over current"] = new() + { + Explanation = "PV string 2 current exceeds limits. This is a WARNING level condition.", + Causes = new[] { "PV oversized", "Ground fault" }, + NextSteps = new[] { "Check PV configuration", "Fix the cause, then restart" } + }, + + // PV 3 alarms + ["PV 3not connected"] = new() + { + Explanation = "PV string 3 is not connected. This is an ERROR level condition.", + Causes = new[] { "PV disconnector open", "Cable issue" }, + NextSteps = new[] { "Check connections", "Fix the cause, then restart" } + }, + ["PV 3over voltage"] = new() + { + Explanation = "PV string 3 voltage exceeds maximum. This is a WARNING.", + Causes = new[] { "Too many modules in series" }, + NextSteps = new[] { "Check PV configuration" } + }, + ["PV 3average current anomaly"] = new() + { + Explanation = "PV string 3 current is abnormal. This is a WARNING.", + Causes = new[] { "Module mismatch", "Shading" }, + NextSteps = new[] { "Check modules", "Fix the cause, then restart" } + }, + ["PV 3power tube failure"] = new() + { + Explanation = "PV 3 power electronics failed. This is a PROTECTION level condition.", + Causes = new[] { "Hardware failure" }, + NextSteps = new[] { "Do not restart", "Contact service" } + }, + ["PV 3soft startfailure"] = new() + { + Explanation = "PV 3 soft start failed. This is a WARNING.", + Causes = new[] { "Pre-charge fault" }, + NextSteps = new[] { "Fix the cause, then restart" } + }, + ["PV 3overload timeout"] = new() + { + Explanation = "PV 3 overloaded too long. This is an ERROR.", + Causes = new[] { "Excessive power" }, + NextSteps = new[] { "Fix the cause, then restart" } + }, + ["PV 3reverse connection"] = new() + { + Explanation = "PV string 3 is connected with reversed polarity. This is a PROTECTION level condition.", + Causes = new[] { "Installation error", "Wrong cable connection" }, + NextSteps = new[] { "Do not restart", "Contact service to correct wiring" } + }, + ["Photovoltaic 3 over current"] = new() + { + Explanation = "PV string 3 current exceeds limits. This is a WARNING.", + Causes = new[] { "PV oversized", "Fault condition" }, + NextSteps = new[] { "Check configuration", "Fix the cause, then restart" } + }, + + // PV 4 alarms + ["PV 4not connected"] = new() + { + Explanation = "PV string 4 is not connected. This is an ERROR.", + Causes = new[] { "Disconnector open", "Cable issue" }, + NextSteps = new[] { "Check connections", "Fix the cause, then restart" } + }, + ["PV 4over voltage"] = new() + { + Explanation = "PV string 4 voltage exceeds maximum. This is a WARNING.", + Causes = new[] { "Too many modules" }, + NextSteps = new[] { "Check configuration" } + }, + ["PV 4average current anomaly"] = new() + { + Explanation = "PV string 4 current abnormal. This is a WARNING.", + Causes = new[] { "Module mismatch" }, + NextSteps = new[] { "Check modules" } + }, + ["PV 4power tube Failure"] = new() + { + Explanation = "PV 4 power electronics failed. This is a PROTECTION level condition.", + Causes = new[] { "Hardware failure" }, + NextSteps = new[] { "Do not restart", "Contact service" } + }, + ["PV 4soft startfailure"] = new() + { + Explanation = "PV 4 soft start failed. This is a WARNING.", + Causes = new[] { "Pre-charge fault" }, + NextSteps = new[] { "Fix the cause, then restart" } + }, + ["PV 4overload timeout"] = new() + { + Explanation = "PV 4 overloaded too long. This is an ERROR.", + Causes = new[] { "Excessive power" }, + NextSteps = new[] { "Fix the cause, then restart" } + }, + ["PV 4reverse connection"] = new() + { + Explanation = "PV string 4 polarity reversed. This is a PROTECTION condition.", + Causes = new[] { "Wrong wiring" }, + NextSteps = new[] { "Do not restart", "Contact service" } + }, + ["Photovoltaic 4 over current"] = new() + { + Explanation = "PV string 4 current exceeds limits. This is a WARNING.", + Causes = new[] { "PV oversized" }, + NextSteps = new[] { "Check configuration" } + }, + ["Insufficient photovoltaic power"] = new() + { + Explanation = "Not enough PV power available. This is a WARNING.", + Causes = new[] { "Low irradiance", "Evening/cloudy" }, + NextSteps = new[] { "Wait for better conditions", "Fix the cause, then restart" } + }, + + // DC Bus alarms + ["DC busover voltage"] = new() + { + Explanation = "The DC bus voltage is too high. This is a WARNING level condition.", + Causes = new[] { "Excessive charging power", "Regenerative load", "Control fault" }, + NextSteps = new[] { "Check power balance", "Fix the cause, then restart" } + }, + ["DC busunder voltage"] = new() + { + Explanation = "The DC bus voltage is too low. This is a WARNING level condition.", + Causes = new[] { "Excessive load", "Power supply issue", "Battery depletion" }, + NextSteps = new[] { "Reduce load", "Check power sources", "Fix the cause, then restart" } + }, + ["DC bus voltage unbalance"] = new() + { + Explanation = "The DC bus voltage is unbalanced. This is an ERROR level condition.", + Causes = new[] { "Capacitor failure", "Control issue", "Asymmetric loading" }, + NextSteps = new[] { "Check capacitor bank", "Fix the cause, then restart" } + }, + ["Busslow over voltage"] = new() + { + Explanation = "DC bus slow over-voltage detected. This is a WARNING.", + Causes = new[] { "Gradual voltage rise", "Charging imbalance" }, + NextSteps = new[] { "Check charging control", "Fix the cause, then restart" } + }, + ["Hardware bus over voltage"] = new() + { + Explanation = "Hardware-level bus over-voltage protection tripped. This is a PROTECTION level condition.", + Causes = new[] { "Severe overvoltage event", "Component failure" }, + NextSteps = new[] { "Do not restart", "Contact service technician" } + }, + ["Bus soft startfailure"] = new() + { + Explanation = "DC bus failed to soft-start. This is a WARNING.", + Causes = new[] { "Pre-charge fault", "Capacitor issue" }, + NextSteps = new[] { "Check pre-charge circuit", "Fix the cause, then restart" } + }, + + // Inverter power tube and hardware faults + ["Inverter power tube fault"] = new() + { + Explanation = "The main inverter power electronics (IGBT/MOSFET) have failed. This is a PROTECTION level condition requiring professional service.", + Causes = new[] { "Power semiconductor failure", "Overcurrent damage", "Short circuit damage", "Thermal damage" }, + NextSteps = new[] { "Do not attempt to restart", "Contact service technician", "Hardware repair/replacement required" } + }, + ["Hardware over current"] = new() + { + Explanation = "Hardware overcurrent protection has tripped. This is a PROTECTION level condition.", + Causes = new[] { "Short circuit", "Severe overload", "Component failure" }, + NextSteps = new[] { "Do not restart", "Contact service technician" } + }, + ["DC converter over voltage"] = new() + { + Explanation = "DC converter voltage too high. This is a WARNING.", + Causes = new[] { "Input overvoltage", "Control issue" }, + NextSteps = new[] { "Check input voltage", "Fix the cause, then restart" } + }, + ["DC converter hardware over voltage"] = new() + { + Explanation = "DC converter hardware overvoltage protection. This is a PROTECTION condition.", + Causes = new[] { "Severe overvoltage" }, + NextSteps = new[] { "Do not restart", "Contact service" } + }, + ["DC converter over current"] = new() + { + Explanation = "DC converter current too high. This is a WARNING.", + Causes = new[] { "Overload", "Short circuit" }, + NextSteps = new[] { "Reduce load", "Fix the cause, then restart" } + }, + ["DC converter hardware over current"] = new() + { + Explanation = "DC converter hardware overcurrent protection. This is a PROTECTION condition.", + Causes = new[] { "Severe overcurrent" }, + NextSteps = new[] { "Do not restart", "Contact service" } + }, + ["DC converter resonator over current"] = new() + { + Explanation = "DC converter resonator overcurrent. This is a WARNING.", + Causes = new[] { "Resonance condition", "Control issue" }, + NextSteps = new[] { "Fix the cause, then restart" } + }, + + // Overload alarms + ["System output overload"] = new() + { + Explanation = "The total system output is overloaded. This is an ERROR level condition.", + Causes = new[] { "Too many loads connected", "Load exceeds inverter capacity", "Short circuit in load" }, + NextSteps = new[] { "Disconnect some loads", "Check for short circuits", "Fix the cause, then restart" } + }, + ["Inverter overload"] = new() + { + Explanation = "The inverter is overloaded. This is an ERROR level condition.", + Causes = new[] { "Load exceeds rated power", "Inrush current from motors", "Short circuit" }, + NextSteps = new[] { "Reduce connected load", "Check load power rating", "Fix the cause, then restart" } + }, + ["Inverter overload timeout"] = new() + { + Explanation = "The inverter has been overloaded for too long. This is an ERROR level condition.", + Causes = new[] { "Sustained overload condition", "Undersized inverter for load" }, + NextSteps = new[] { "Permanently reduce load", "Consider larger inverter", "Fix the cause, then restart" } + }, + ["Load power overload"] = new() + { + Explanation = "Load power exceeds system capacity. This is an ERROR.", + Causes = new[] { "Excessive load" }, + NextSteps = new[] { "Reduce load", "Fix the cause, then restart" } + }, + ["Balancedcircuit overload timeout"] = new() + { + Explanation = "Balanced circuit overloaded too long. This is an ERROR.", + Causes = new[] { "Unbalanced loading", "Phase overload" }, + NextSteps = new[] { "Balance loads", "Fix the cause, then restart" } + }, + + // Soft start failures + ["Inverter soft start failure"] = new() + { + Explanation = "The inverter failed during soft-start sequence. This is a WARNING level condition.", + Causes = new[] { "Pre-charge resistor fault", "Contactor failure", "DC bus capacitor issue", "Control board fault" }, + NextSteps = new[] { "Power cycle the system", "Check DC bus voltage", "If persistent, contact service", "Fix the cause, then restart" } + }, + + // DSP and firmware alarms + ["DSP 1para meter setting fault"] = new() + { + Explanation = "DSP 1 parameter configuration error. This is an ERROR level condition.", + Causes = new[] { "Incorrect parameter setting", "Firmware corruption", "Configuration mismatch" }, + NextSteps = new[] { "Check parameter settings", "Reset to defaults if needed", "Fix the cause, then restart" } + }, + ["DSP 2para meter setting fault"] = new() + { + Explanation = "DSP 2 parameter configuration error. This is an ERROR level condition.", + Causes = new[] { "Incorrect parameter setting", "Firmware corruption" }, + NextSteps = new[] { "Check parameter settings", "Fix the cause, then restart" } + }, + ["DSPversion compatibility fault"] = new() + { + Explanation = "DSP firmware version is incompatible. This is an ERROR level condition.", + Causes = new[] { "Firmware mismatch between components", "Incomplete firmware update" }, + NextSteps = new[] { "Update firmware to compatible version", "Contact support if needed" } + }, + ["CPLDversion compatibility fault"] = new() + { + Explanation = "CPLD version is incompatible. This is an ERROR level condition.", + Causes = new[] { "Firmware mismatch", "Incomplete update" }, + NextSteps = new[] { "Update firmware", "Fix the cause, then restart" } + }, + ["CPLD communication fault"] = new() + { + Explanation = "Communication with CPLD failed. This is an ERROR level condition.", + Causes = new[] { "Internal communication bus fault", "CPLD failure" }, + NextSteps = new[] { "Power cycle the system", "If persistent, contact service" } + }, + ["DSP communication fault"] = new() + { + Explanation = "Communication with DSP failed. This is an ERROR level condition.", + Causes = new[] { "Internal communication bus fault", "DSP failure" }, + NextSteps = new[] { "Power cycle the system", "If persistent, contact service" } + }, + + // Output DC component alarms + ["Output voltageDC overlimit"] = new() + { + Explanation = "DC component in output voltage exceeds limit. This is a WARNING.", + Causes = new[] { "Control drift", "Sensor offset", "Hardware issue" }, + NextSteps = new[] { "Restart the inverter", "If persistent, contact service" } + }, + ["Output currentDC overlimit"] = new() + { + Explanation = "DC component in output current exceeds limit. This is a WARNING.", + Causes = new[] { "Control issue", "Sensor fault" }, + NextSteps = new[] { "Restart the inverter", "Fix the cause, then restart" } + }, + + // Relay alarms + ["Relayself-checkfails"] = new() + { + Explanation = "Relay self-check has failed. This is an ERROR level condition.", + Causes = new[] { "Relay contact fault", "Relay driver fault", "Welded contacts" }, + NextSteps = new[] { "Check relay operation", "Fix the cause, then restart" } + }, + ["Inverter relayopen"] = new() + { + Explanation = "Inverter relay is unexpectedly open. This is an ERROR.", + Causes = new[] { "Relay driver fault", "Protection trip" }, + NextSteps = new[] { "Check protection status", "Fix the cause, then restart" } + }, + ["Inverter relayshort circuit"] = new() + { + Explanation = "Inverter relay has a short circuit (welded contacts). This is a PROTECTION condition.", + Causes = new[] { "Welded relay contacts", "Relay failure" }, + NextSteps = new[] { "Do not restart", "Contact service to replace relay" } + }, + ["Opencircuitof power grid relay"] = new() + { + Explanation = "Grid relay is unexpectedly open. This is an ERROR.", + Causes = new[] { "Relay fault", "Protection active" }, + NextSteps = new[] { "Check relay", "Fix the cause, then restart" } + }, + ["Shortcircuitof power grid relay"] = new() + { + Explanation = "Grid relay has welded contacts. This is an ERROR.", + Causes = new[] { "Relay failure" }, + NextSteps = new[] { "Contact service", "Fix the cause, then restart" } + }, + ["generator Relayopencircuit"] = new() + { + Explanation = "Generator relay is open. This is an ERROR.", + Causes = new[] { "Relay fault" }, + NextSteps = new[] { "Check relay", "Fix the cause, then restart" } + }, + ["generator Relayshortcircuit"] = new() + { + Explanation = "Generator relay has welded. This is an ERROR.", + Causes = new[] { "Relay failure" }, + NextSteps = new[] { "Contact service", "Fix the cause, then restart" } + }, + + // Abnormal inverter + ["Abnormal inverter"] = new() + { + Explanation = "General inverter abnormality detected. This is an ERROR level condition.", + Causes = new[] { "Various internal faults", "Control system issue" }, + NextSteps = new[] { "Power cycle the inverter", "Check for other specific alarms", "Fix the cause, then restart" } + }, + + // Parallel operation alarms + ["Parallel communicationalarm"] = new() + { + Explanation = "Communication between parallel inverters has failed. This is an ERROR level condition.", + Causes = new[] { "Communication cable fault", "Parallel interface failure", "Settings mismatch" }, + NextSteps = new[] { "Check parallel communication cables", "Verify settings match", "Fix the cause, then restart" } + }, + ["Parallelmodule missing"] = new() + { + Explanation = "A parallel module is missing from the system. This is a WARNING.", + Causes = new[] { "Module offline", "Communication loss", "Power failure on module" }, + NextSteps = new[] { "Check all parallel modules", "Fix the cause, then restart" } + }, + ["Duplicatemachine numbersforparallel modules"] = new() + { + Explanation = "Two parallel modules have the same ID number. This is a WARNING.", + Causes = new[] { "Configuration error", "Duplicate addressing" }, + NextSteps = new[] { "Assign unique IDs to each module", "Fix the cause, then restart" } + }, + ["Para meterconflictin parallelmodule"] = new() + { + Explanation = "Parameter conflict between parallel modules. This is a WARNING.", + Causes = new[] { "Mismatched settings between units" }, + NextSteps = new[] { "Synchronize settings across all units", "Fix the cause, then restart" } + }, + + // System derating + ["Systemderating"] = new() + { + Explanation = "The system is operating at reduced power (derating). This is a WARNING.", + Causes = new[] { "High temperature", "Voltage out of range", "Component limitation" }, + NextSteps = new[] { "Check temperature and ventilation", "Identify derating cause", "Fix the cause, then restart" } + }, + + // PV access method + ["PVaccessmethod erroralarm"] = new() + { + Explanation = "PV access configuration error. This is a WARNING.", + Causes = new[] { "Incorrect PV configuration", "Wiring mismatch" }, + NextSteps = new[] { "Check PV configuration settings", "Fix the cause, then restart" } + }, + + // Reserved alarms + ["Reservedalarms 4"] = new() + { + Explanation = "Reserved alarm 4 is active. This is a WARNING level condition.", + Causes = new[] { "Undocumented condition" }, + NextSteps = new[] { "Monitor the system", "Contact support if issue persists" } + }, + ["Reservedalarms 5"] = new() + { + Explanation = "Reserved alarm 5 is active. This is a WARNING level condition.", + Causes = new[] { "Undocumented condition" }, + NextSteps = new[] { "Monitor the system", "Contact support if issue persists" } + }, + + // Meter alarms + ["Reverse meter connection"] = new() + { + Explanation = "The energy meter is connected in reverse. This is a PROTECTION level condition.", + Causes = new[] { "Meter CT installed backwards", "Meter wiring reversed" }, + NextSteps = new[] { "Do not rely on meter readings", "Contact service to correct meter installation" } + }, + + // Seal pulse + ["InverterSealPulse"] = new() + { + Explanation = "Inverter seal pulse active. This is a WARNING indicating output limiting.", + Causes = new[] { "Protection active", "Output limiting" }, + NextSteps = new[] { "Check system status", "Fix the cause, then restart" } + }, + + // Diesel generator alarms + ["Abnormal diesel generator voltage"] = new() + { + Explanation = "Diesel generator voltage is abnormal. This is an ERROR.", + Causes = new[] { "Generator voltage out of range", "AVR fault" }, + NextSteps = new[] { "Check generator voltage setting", "Fix the cause, then restart" } + }, + ["Abnormal diesel generator frequency"] = new() + { + Explanation = "Diesel generator frequency is abnormal. This is an ERROR.", + Causes = new[] { "Generator speed issue", "Governor fault" }, + NextSteps = new[] { "Check generator frequency", "Fix the cause, then restart" } + }, + ["Diesel generator voltage reverse sequence"] = new() + { + Explanation = "Generator phase sequence is reversed. This is a PROTECTION condition.", + Causes = new[] { "Wrong phase wiring" }, + NextSteps = new[] { "Do not restart", "Contact service to correct wiring" } + }, + ["Diesel generator voltageoutof phase"] = new() + { + Explanation = "Generator voltage is out of phase with grid. This is an ERROR.", + Causes = new[] { "Sync issue", "Phase angle mismatch" }, + NextSteps = new[] { "Check synchronization", "Fix the cause, then restart" } + }, + ["Generator overload"] = new() + { + Explanation = "The generator is overloaded. This is an ERROR.", + Causes = new[] { "Load exceeds generator capacity" }, + NextSteps = new[] { "Reduce load", "Fix the cause, then restart" } + }, + }.ToFrozenDictionary(); + + // ── Growatt Alarms ─────────────────────────────────────────────────────── + // Format: "Warning XXX" or "Error XXX" or descriptive text + + private static readonly FrozenDictionary GrowattAlarms = new Dictionary + { + // Warnings (200-series: PV/String) + ["Warning 200"] = new() + { + Explanation = "String fault detected. One or more PV strings may have issues affecting power generation.", + Causes = new[] { "PV panel fault", "String wiring issue", "Connector problem", "Module degradation" }, + NextSteps = new[] { "Check if PV panels are normal after shutdown", "Inspect string connections", "Look for damaged cables" } + }, + ["Warning 201"] = new() + { + Explanation = "PV string/PID quick-connect terminals are abnormal.", + Causes = new[] { "Loose terminal connections", "Damaged quick-connect", "Corrosion on terminals" }, + NextSteps = new[] { "Check wiring of string terminals after shutdown", "Clean and secure connections" } + }, + ["Warning 203"] = new() + { + Explanation = "PV1 or PV2 string is short-circuited.", + Causes = new[] { "Cable damage causing short", "Connector failure", "Module junction box fault" }, + NextSteps = new[] { "Check if PV1 or PV2 is short-circuited", "Inspect cables for damage", "Test string isolation" } + }, + ["Warning 208"] = new() + { + Explanation = "DC fuse has blown, interrupting PV input.", + Causes = new[] { "Overcurrent in DC circuit", "Short circuit", "Fuse fatigue" }, + NextSteps = new[] { "Power off the system", "Check the fuse", "Identify and fix overcurrent cause before replacing fuse" } + }, + ["Warning 209"] = new() + { + Explanation = "DC input voltage exceeds the upper threshold - potential damage risk.", + Causes = new[] { "Too many PV modules in series", "Cold temperature increasing Voc", "System design error" }, + NextSteps = new[] { "Turn off DC switch immediately", "Check DC voltage", "Reconfigure string if needed" } + }, + ["Warning 219"] = new() + { + Explanation = "PID (Potential Induced Degradation) function is abnormal.", + Causes = new[] { "PID module fault", "Configuration issue" }, + NextSteps = new[] { "Restart the inverter", "Check PID settings" } + }, + ["Warning 220"] = new() + { + Explanation = "A PV string is disconnected.", + Causes = new[] { "DC disconnector open", "Cable disconnection", "Connector failure" }, + NextSteps = new[] { "Check if PV string is properly connected", "Verify DC switches" } + }, + ["Warning 221"] = new() + { + Explanation = "PV string currents are unbalanced, indicating potential issues.", + Causes = new[] { "Shading on some modules", "Module mismatch", "Partial string failure", "Soiling" }, + NextSteps = new[] { "Check if PV panels of the corresponding string are normal", "Look for shading", "Clean panels" } + }, + + // Warnings (300-series: Grid/AC) + ["Warning 300"] = new() + { + Explanation = "No utility grid connection detected or grid power failure.", + Causes = new[] { "Grid outage", "AC breaker tripped", "Grid cable disconnected", "Utility maintenance" }, + NextSteps = new[] { "Check if grid is down", "Verify AC breaker status", "Check grid cable connections" } + }, + ["Warning 301"] = new() + { + Explanation = "Grid voltage is outside the permissible operating range.", + Causes = new[] { "Grid voltage too high or too low", "Local grid issues", "Transformer tap setting" }, + NextSteps = new[] { "Check if grid voltage is within specified range", "Contact utility if persistent" } + }, + ["Warning 302"] = new() + { + Explanation = "Grid frequency is outside the permissible operating range.", + Causes = new[] { "Grid frequency unstable", "Generator frequency drift", "Grid disturbance" }, + NextSteps = new[] { "Check if grid frequency is within specified range", "Wait for grid to stabilize" } + }, + ["Warning 303"] = new() + { + Explanation = "The system is experiencing an overload condition.", + Causes = new[] { "Connected load exceeds capacity", "Inrush current from appliances", "Short circuit in load" }, + NextSteps = new[] { "Reduce load connected to EPS output terminal", "Check for faulty appliances" } + }, + ["Warning 308"] = new() + { + Explanation = "Energy meter communication is lost.", + Causes = new[] { "Meter offline", "Communication cable fault", "Meter power loss" }, + NextSteps = new[] { "Check if meter is properly connected", "Verify communication cable", "Check meter power" } + }, + ["Warning 309"] = new() + { + Explanation = "Energy meter L and N lines are reversed.", + Causes = new[] { "Meter wiring error", "Installation mistake" }, + NextSteps = new[] { "Check if L line and N line of meter are reversely connected", "Correct wiring" } + }, + ["Warning 310"] = new() + { + Explanation = "Abnormal voltage detected between neutral (N) and protective earth (PE).", + Causes = new[] { "Poor PE connection", "N-PE short somewhere in installation", "Ground fault" }, + NextSteps = new[] { "Check if PE cable is reliably connected after shutdown", "Verify grounding system" } + }, + ["Warning 311"] = new() + { + Explanation = "Phase sequence error detected. The system will auto-adjust.", + Causes = new[] { "Three-phase wiring in wrong order" }, + NextSteps = new[] { "No operation required", "The PCS will automatically adjust phase sequence" } + }, + + // Warnings (400-series: System/Internal) + ["Warning 400"] = new() + { + Explanation = "Cooling fan failure detected - risk of overheating.", + Causes = new[] { "Fan motor failure", "Fan blocked", "Fan connector loose", "Fan control fault" }, + NextSteps = new[] { "Check if fan is properly connected after shutdown", "Remove obstructions", "Replace fan if faulty" } + }, + ["Warning 401"] = new() + { + Explanation = "Energy meter is reporting abnormal readings.", + Causes = new[] { "Meter malfunction", "Configuration error", "Communication issue" }, + NextSteps = new[] { "Check if meter is turned on", "Verify meter configuration" } + }, + ["Warning 402"] = new() + { + Explanation = "Communication with PV optimizer is abnormal.", + Causes = new[] { "Optimizer offline", "Communication interference", "Optimizer fault" }, + NextSteps = new[] { "Check if optimizer is turned on", "Verify communication wiring" } + }, + ["Warning 407"] = new() + { + Explanation = "System temperature is too high - power may be limited.", + Causes = new[] { "Poor ventilation", "High ambient temperature", "Fan failure", "Excessive load" }, + NextSteps = new[] { "Restart the inverter", "If fault persists, improve cooling", "Contact manufacturer if unresolved" } + }, + ["Warning 408"] = new() + { + Explanation = "NTC temperature sensor is broken or disconnected.", + Causes = new[] { "Sensor failure", "Sensor cable damaged", "Connector issue" }, + NextSteps = new[] { "Restart the inverter", "If persistent, sensor may need replacement" } + }, + ["Warning 411"] = new() + { + Explanation = "Synchronization signal is abnormal (for parallel systems).", + Causes = new[] { "Sync cable fault", "Sync interface failure", "Configuration mismatch" }, + NextSteps = new[] { "Check if sync cable is abnormal", "Verify connections" } + }, + ["Warning 412"] = new() + { + Explanation = "Grid-connection startup requirements are not met.", + Causes = new[] { "Grid voltage/frequency out of range", "Incorrect startup voltage configuration" }, + NextSteps = new[] { "Check if grid voltage is within specified range", "Check grid-connection startup voltage configuration" } + }, + + // Warnings (500-series: Battery) + ["Warning 500"] = new() + { + Explanation = "Inverter cannot communicate with the battery BMS.", + Causes = new[] { "BMS offline", "Communication cable fault", "Protocol mismatch", "Battery in sleep mode" }, + NextSteps = new[] { "Check if battery is turned on", "Verify RS485 communication cable", "Wake up battery if in sleep mode" } + }, + ["Warning 501"] = new() + { + Explanation = "Battery is disconnected from the system.", + Causes = new[] { "Battery breaker off", "Cable disconnected", "BMS shutdown", "Battery fault" }, + NextSteps = new[] { "Check if battery is properly connected", "Verify battery breaker", "Check BMS status" } + }, + ["Warning 502"] = new() + { + Explanation = "Battery voltage is too high.", + Causes = new[] { "Overcharging", "BMS fault", "Cell imbalance", "Voltage setting error" }, + NextSteps = new[] { "Check if battery voltage is within permissible range", "Verify charging settings" } + }, + ["Warning 503"] = new() + { + Explanation = "Battery voltage is too low.", + Causes = new[] { "Battery deeply discharged", "Cell failure", "High load drain", "BMS cutoff" }, + NextSteps = new[] { "Check if battery voltage is within permissible range", "Allow battery to charge" } + }, + ["Warning 504"] = new() + { + Explanation = "Battery positive and negative terminals are reversed.", + Causes = new[] { "Installation error", "Wrong cable connection" }, + NextSteps = new[] { "Check if positive and negative terminals of battery are reversely connected", "CORRECT IMMEDIATELY - risk of damage" } + }, + ["Warning 505"] = new() + { + Explanation = "Lead-acid battery temperature sensor is disconnected.", + Causes = new[] { "Sensor not installed", "Sensor cable fault", "Sensor failure" }, + NextSteps = new[] { "Check if temperature sensor of lead-acid battery is installed", "Verify connections" } + }, + ["Warning 506"] = new() + { + Explanation = "Battery temperature is outside the safe operating range.", + Causes = new[] { "High ambient temperature", "Poor battery ventilation", "Battery overheating", "Cold environment" }, + NextSteps = new[] { "Check if ambient temperature of battery is within specified range", "Improve battery cooling/heating" } + }, + ["Warning 507"] = new() + { + Explanation = "Battery BMS has reported a fault preventing charging and discharging.", + Causes = new[] { "BMS internal fault", "Cell protection triggered", "Communication error" }, + NextSteps = new[] { "Figure out the cause according to BMS error code", "Check battery status display" } + }, + ["Warning 508"] = new() + { + Explanation = "Lithium battery overload protection has activated.", + Causes = new[] { "Load power exceeds battery discharge rating", "High inrush current" }, + NextSteps = new[] { "Check if power of load exceeds BAT rated discharge power", "Reduce load" } + }, + ["Warning 509"] = new() + { + Explanation = "BMS communication is abnormal.", + Causes = new[] { "Communication timeout", "Protocol error", "Cable fault" }, + NextSteps = new[] { "Restart the inverter", "Check BMS communication cable" } + }, + ["Warning 510"] = new() + { + Explanation = "Battery surge protection device (SPD) function is abnormal.", + Causes = new[] { "SPD triggered", "SPD failure", "Lightning damage" }, + NextSteps = new[] { "Check BAT SPD after powering off device", "Replace SPD if triggered" } + }, + + // Warnings (600-series: Off-grid/EPS) + ["Warning 600"] = new() + { + Explanation = "Output DC component bias is abnormal.", + Causes = new[] { "Sensor drift", "Control issue", "Hardware fault" }, + NextSteps = new[] { "Restart the inverter", "If fault persists, contact manufacturer" } + }, + ["Warning 601"] = new() + { + Explanation = "DC component in output voltage is too high.", + Causes = new[] { "Control drift", "Sensor fault", "Transformer issue" }, + NextSteps = new[] { "Restart the inverter", "Check output for DC offset" } + }, + ["Warning 602"] = new() + { + Explanation = "Off-grid/EPS output voltage is too low.", + Causes = new[] { "Overload", "Battery voltage low", "Inverter limitation" }, + NextSteps = new[] { "Restart the inverter", "Reduce load", "If fault persists, contact manufacturer" } + }, + ["Warning 603"] = new() + { + Explanation = "Off-grid/EPS output voltage is too high.", + Causes = new[] { "Control fault", "Voltage regulation issue" }, + NextSteps = new[] { "Restart the inverter", "If fault persists, contact manufacturer" } + }, + ["Warning 604"] = new() + { + Explanation = "Off-grid output current overcurrent detected.", + Causes = new[] { "Load exceeds specification", "Short circuit in load", "Inrush current" }, + NextSteps = new[] { "Check if load is within specification", "Look for short circuits" } + }, + ["Warning 605"] = new() + { + Explanation = "Off-grid DC bus voltage is too low.", + Causes = new[] { "Battery depleted", "High load demand", "Power electronics issue" }, + NextSteps = new[] { "Check if load power exceeds upper limit", "Allow battery to charge" } + }, + ["Warning 606"] = new() + { + Explanation = "Off-grid output is overloaded.", + Causes = new[] { "Load exceeds EPS capacity", "Too many appliances on backup" }, + NextSteps = new[] { "Check if load is within specification", "Reduce backup load" } + }, + ["Warning 609"] = new() + { + Explanation = "Phase balancing circuit is abnormal.", + Causes = new[] { "Balance circuit fault", "Control issue" }, + NextSteps = new[] { "Restart the inverter", "Check phase balance" } + }, + + // Errors (Protection-level faults) + ["Error 309"] = new() + { + Explanation = "Grid Rate of Change of Frequency (ROCOF) is abnormal - anti-islanding protection.", + Causes = new[] { "Grid instability", "Generator operation nearby", "Grid fault" }, + NextSteps = new[] { "Check grid frequency", "Restart the inverter", "Wait for grid to stabilize" } + }, + ["Error 311"] = new() + { + Explanation = "Export limitation fail-safe has triggered.", + Causes = new[] { "CT disconnected", "Meter communication lost", "Feedback loop failure" }, + NextSteps = new[] { "After shutdown, check connection of CT and meter", "Verify export limit settings" } + }, + ["Error 400"] = new() + { + Explanation = "DCI (DC Injection) bias is abnormal - safety protection.", + Causes = new[] { "DC injection into grid", "Sensor fault", "Transformer issue" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 402"] = new() + { + Explanation = "High DC component detected in output current.", + Causes = new[] { "Output filter issue", "Control fault", "Transformer saturation" }, + NextSteps = new[] { "Restart the inverter", "Check output connections" } + }, + ["Error 404"] = new() + { + Explanation = "DC bus voltage sampling is abnormal.", + Causes = new[] { "Voltage sensor fault", "ADC error", "Hardware issue" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 405"] = new() + { + Explanation = "Internal relay fault detected.", + Causes = new[] { "Relay failure", "Contact welding", "Driver circuit fault" }, + NextSteps = new[] { "Restart the inverter", "If persistent, relay replacement needed" } + }, + ["Error 408"] = new() + { + Explanation = "System over-temperature - shutdown for protection.", + Causes = new[] { "Cooling failure", "High ambient temperature", "Blocked ventilation", "Overload" }, + NextSteps = new[] { "After shutdown, check temperature", "Restart after temperature is within acceptable range" } + }, + ["Error 409"] = new() + { + Explanation = "DC bus voltage is abnormal.", + Causes = new[] { "Power electronics fault", "Capacitor issue", "Control failure" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 411"] = new() + { + Explanation = "Internal communication failure between control boards.", + Causes = new[] { "Communication board fault", "Cable loose", "EMI interference" }, + NextSteps = new[] { "Check wiring of communication board after shutdown", "Restart inverter" } + }, + ["Error 412"] = new() + { + Explanation = "Temperature sensor is disconnected.", + Causes = new[] { "Sensor failure", "Cable fault", "Connector issue" }, + NextSteps = new[] { "Check wiring of communication board after shutdown", "Replace sensor if faulty" } + }, + ["Error 413"] = new() + { + Explanation = "IGBT gate drive fault detected.", + Causes = new[] { "Driver circuit failure", "IGBT fault", "Power supply issue" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires professional service" } + }, + ["Error 414"] = new() + { + Explanation = "EEPROM read/write error.", + Causes = new[] { "Memory chip fault", "Data corruption", "Hardware failure" }, + NextSteps = new[] { "Restart the inverter", "Factory reset may be required" } + }, + ["Error 415"] = new() + { + Explanation = "Auxiliary power supply is abnormal.", + Causes = new[] { "Internal power supply failure", "Component fault" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 416"] = new() + { + Explanation = "DC/AC overcurrent protection has triggered.", + Causes = new[] { "Short circuit", "Severe overload", "Power electronics fault" }, + NextSteps = new[] { "Restart the inverter", "Check for short circuits", "Reduce load" } + }, + ["Error 417"] = new() + { + Explanation = "Communication protocol mismatch between components.", + Causes = new[] { "Firmware version mismatch", "Configuration error" }, + NextSteps = new[] { "Restart the inverter", "Update firmware if needed" } + }, + ["Error 418"] = new() + { + Explanation = "DSP and COM board firmware versions are mismatched.", + Causes = new[] { "Incomplete firmware update", "Wrong firmware loaded" }, + NextSteps = new[] { "Restart the inverter", "Perform complete firmware update" } + }, + ["Error 419"] = new() + { + Explanation = "DSP software and hardware versions are mismatched.", + Causes = new[] { "Hardware replacement with incompatible firmware" }, + NextSteps = new[] { "Restart the inverter", "Contact support for firmware update" } + }, + ["Error 421"] = new() + { + Explanation = "CPLD (programmable logic) is abnormal.", + Causes = new[] { "CPLD failure", "Firmware corruption" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 422"] = new() + { + Explanation = "Redundancy sampling values are inconsistent.", + Causes = new[] { "Sensor mismatch", "Calibration error", "Hardware fault" }, + NextSteps = new[] { "Restart the inverter", "May require recalibration" } + }, + ["Error 423"] = new() + { + Explanation = "PWM pass-through signal failure.", + Causes = new[] { "Control board fault", "Signal path issue" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 425"] = new() + { + Explanation = "AFCI (Arc Fault Circuit Interrupter) self-test failed.", + Causes = new[] { "AFCI module fault", "Self-test circuit issue" }, + NextSteps = new[] { "Restart the inverter", "AFCI may need replacement" } + }, + ["Error 426"] = new() + { + Explanation = "PV current sampling is abnormal.", + Causes = new[] { "Current sensor fault", "ADC error" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 427"] = new() + { + Explanation = "AC current sampling is abnormal.", + Causes = new[] { "CT fault", "Sensor failure", "ADC error" }, + NextSteps = new[] { "Restart the inverter", "Check CT connections" } + }, + ["Error 429"] = new() + { + Explanation = "DC bus soft-boot (pre-charge) failed.", + Causes = new[] { "Pre-charge circuit fault", "Capacitor issue", "Relay fault" }, + NextSteps = new[] { "Restart the inverter", "If persistent, requires service" } + }, + ["Error 430"] = new() + { + Explanation = "EPO (Emergency Power Off) fault triggered.", + Causes = new[] { "EPO button pressed", "EPO circuit activated", "Safety system trigger" }, + NextSteps = new[] { "Restart the inverter", "Check EPO circuit if unintentional" } + }, + ["Error 431"] = new() + { + Explanation = "Monitoring chip BOOT verification failed.", + Causes = new[] { "Firmware corruption", "Chip failure" }, + NextSteps = new[] { "Restart the inverter", "May require firmware reload" } + }, + + // Battery Errors + ["Error 500"] = new() + { + Explanation = "BMS failed to communicate with the inverter.", + Causes = new[] { "RS485 cable fault", "BMS offline", "Protocol mismatch" }, + NextSteps = new[] { "Check connection of RS485 cable between inverter and battery" } + }, + ["Error 501"] = new() + { + Explanation = "BMS reports that battery cannot charge or discharge.", + Causes = new[] { "BMS internal fault", "Protection triggered", "Cell issue" }, + NextSteps = new[] { "Figure out the fault based on BMS error code", "Check battery status" } + }, + ["Error 503"] = new() + { + Explanation = "Battery voltage exceeds upper threshold.", + Causes = new[] { "Overcharging", "BMS fault", "Cell failure" }, + NextSteps = new[] { "Check battery voltage", "If within permissible range, restart inverter" } + }, + ["Error 504"] = new() + { + Explanation = "Battery temperature is outside safe charging/discharging range.", + Causes = new[] { "Battery too hot", "Battery too cold", "Sensor fault" }, + NextSteps = new[] { "Check temperature of the battery", "Improve battery environment" } + }, + ["Error 506"] = new() + { + Explanation = "Battery is open-circuited (not connected).", + Causes = new[] { "Battery cable disconnected", "Fuse blown", "BMS cutoff" }, + NextSteps = new[] { "Check wiring of battery terminals", "Verify fuses" } + }, + ["Error 507"] = new() + { + Explanation = "Battery overload protection has triggered.", + Causes = new[] { "Load exceeds battery discharge rating" }, + NextSteps = new[] { "Check if power of load exceeds battery rated discharge power", "Reduce load" } + }, + ["Error 508"] = new() + { + Explanation = "Secondary DC bus voltage is abnormal.", + Causes = new[] { "Power electronics fault", "Control issue" }, + NextSteps = new[] { "Restart the inverter" } + }, + ["Error 509"] = new() + { + Explanation = "Battery charge overcurrent protection (OCP) triggered.", + Causes = new[] { "PV oversized for battery", "Charge current setting too high" }, + NextSteps = new[] { "Check if PV voltage is oversized", "Reduce charge current setting" } + }, + ["Error 510"] = new() + { + Explanation = "Battery discharge overcurrent protection (OCP) triggered.", + Causes = new[] { "Load too high", "Discharge current setting wrong" }, + NextSteps = new[] { "Check if battery discharge current configuration is proper", "Reduce load" } + }, + ["Error 511"] = new() + { + Explanation = "Battery soft-start failed.", + Causes = new[] { "Pre-charge circuit fault", "Battery voltage mismatch" }, + NextSteps = new[] { "Restart the inverter", "Check battery voltage" } + }, + + // Off-grid Errors + ["Error 601"] = new() + { + Explanation = "Off-grid DC bus voltage is too low.", + Causes = new[] { "Battery depleted", "High load", "Power electronics issue" }, + NextSteps = new[] { "Check if battery is working properly or has capacity loss" } + }, + ["Error 602"] = new() + { + Explanation = "Abnormal voltage detected at off-grid terminal.", + Causes = new[] { "External voltage present", "Wiring fault", "Backfeed" }, + NextSteps = new[] { "Check if a voltage is present at AC port", "Verify wiring" } + }, + ["Error 603"] = new() + { + Explanation = "Off-grid soft-start failed.", + Causes = new[] { "Pre-charge failure", "Load too heavy at startup" }, + NextSteps = new[] { "Restart the inverter", "Reduce initial load" } + }, + ["Error 604"] = new() + { + Explanation = "Off-grid output voltage is abnormal.", + Causes = new[] { "Control fault", "Hardware issue" }, + NextSteps = new[] { "Restart the inverter" } + }, + ["Error 605"] = new() + { + Explanation = "Balanced circuit self-test failed.", + Causes = new[] { "Balance circuit fault" }, + NextSteps = new[] { "Restart the inverter" } + }, + ["Error 606"] = new() + { + Explanation = "High DC component in output voltage.", + Causes = new[] { "Control drift", "Transformer issue" }, + NextSteps = new[] { "Restart the inverter" } + }, + ["Error 608"] = new() + { + Explanation = "Off-grid parallel communication signal is abnormal.", + Causes = new[] { "Parallel cable fault", "Configuration mismatch" }, + NextSteps = new[] { "Check if communication cables are properly connected" } + }, + + // Special fault codes + ["AFCI Fault"] = new() + { + Explanation = "An arc fault has been detected in the PV system - fire risk protection activated.", + Causes = new[] { "Loose connection causing arcing", "Damaged cable insulation", "Connector fault", "Module junction box issue" }, + NextSteps = new[] { "After shutdown, check connection of PV string", "Inspect all connectors", "Look for damaged insulation" } + }, + ["GFCI High"] = new() + { + Explanation = "Excessively high ground fault/leakage current detected.", + Causes = new[] { "Ground fault in PV array", "Insulation breakdown", "Moisture ingress", "Cable damage" }, + NextSteps = new[] { "Restart the inverter", "If persistent, check PV array insulation" } + }, + ["PV Voltage High"] = new() + { + Explanation = "DC input voltage exceeds the maximum safe limit.", + Causes = new[] { "Too many PV modules in series", "Cold temperature increasing Voc" }, + NextSteps = new[] { "Disconnect DC switch immediately", "Check voltage", "Reconfigure strings if needed" } + }, + }.ToFrozenDictionary(); +} diff --git a/csharp/App/Backend/Services/DiagnosticService.cs b/csharp/App/Backend/Services/DiagnosticService.cs new file mode 100644 index 000000000..ef9f0b22e --- /dev/null +++ b/csharp/App/Backend/Services/DiagnosticService.cs @@ -0,0 +1,188 @@ +using System.Collections.Concurrent; +using Flurl.Http; +using InnovEnergy.App.Backend.Database; +using InnovEnergy.App.Backend.DataTypes; +using Newtonsoft.Json; + +namespace InnovEnergy.App.Backend.Services; + +/// +/// Calls OpenAI to generate plain-English diagnostics for errors/warnings. +/// Caches responses in-memory keyed by error description so the same +/// error code is only sent to the API once. +/// +public static class DiagnosticService +{ + private static string _apiKey = ""; + + /// In-memory cache: errorDescription → parsed response. + private static readonly ConcurrentDictionary Cache = new(); + + // ── initialisation ────────────────────────────────────────────── + + public static void Initialize() + { + var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Resources", "openAiConfig.json"); + + if (!File.Exists(configPath)) + { + // Fallback: look relative to the working directory (useful in dev) + configPath = Path.Combine("Resources", "openAiConfig.json"); + } + + if (!File.Exists(configPath)) + { + Console.Error.WriteLine("[DiagnosticService] openAiConfig.json not found – AI diagnostics disabled."); + return; + } + + var json = File.ReadAllText(configPath); + var config = JsonConvert.DeserializeObject(json); + + if (config is null || string.IsNullOrWhiteSpace(config.ApiKey)) + { + Console.Error.WriteLine("[DiagnosticService] ApiKey is empty – AI diagnostics disabled."); + return; + } + + _apiKey = config.ApiKey; + Console.WriteLine("[DiagnosticService] initialised."); + } + + public static bool IsEnabled => !string.IsNullOrEmpty(_apiKey); + + // ── public entry-point ────────────────────────────────────────── + + /// + /// Returns a diagnosis for . + /// First checks the static AlarmKnowledgeBase for known Sinexcel/Growatt alarms. + /// Falls back to in-memory cache, then calls OpenAI only for unknown alarms. + /// + public static async Task DiagnoseAsync(Int64 installationId, string errorDescription) + { + // 1. Check the static knowledge base first (no API call needed) + var knownDiagnosis = AlarmKnowledgeBase.TryGetDiagnosis(errorDescription); + if (knownDiagnosis is not null) + { + Console.WriteLine($"[DiagnosticService] Found diagnosis in knowledge base for: {errorDescription}"); + return knownDiagnosis; + } + + // 2. If AI is not enabled, we can't proceed further + if (!IsEnabled) return null; + + // 3. Check in-memory cache for previously fetched AI diagnoses + if (Cache.TryGetValue(errorDescription, out var cached)) + return cached; + + // 4. Gather context from the DB for AI prompt + var installation = Db.GetInstallationById(installationId); + if (installation is null) return null; + + var productName = ((ProductType)installation.Product).ToString(); + + var recentDescriptions = Db.Errors + .Where(e => e.InstallationId == installationId) + .OrderByDescending(e => e.Date + " " + e.Time) // Date/Time stored as strings in DB + .Select(e => e.Description) + .Distinct() // deduplicate — same error repeated adds no signal + .Take(5) + .ToList(); + + // 5. Build prompt and call OpenAI API (only for unknown alarms) + Console.WriteLine($"[DiagnosticService] Calling OpenAI for unknown alarm: {errorDescription}"); + var prompt = BuildPrompt(errorDescription, productName, recentDescriptions); + var response = await CallOpenAiAsync(prompt); + + if (response is null) return null; + + // 6. Store in cache for future requests + Cache.TryAdd(errorDescription, response); + return response; + } + + // ── prompt ────────────────────────────────────────────────────── + + private static string BuildPrompt(string errorDescription, string productName, List recentErrors) + { + var recentList = recentErrors.Count > 0 + ? string.Join(", ", recentErrors) + : "none"; + + return $@"You are a technician for Innovenergy {productName} battery energy storage systems. +These are lithium-ion BESS units with a BMS, PV inverter, and grid inverter. + +Error: {errorDescription} +Other recent errors: {recentList} + +Explain in plain English for a homeowner. List likely causes and next steps. +Reply with ONLY valid JSON, no markdown: +{{""explanation"":""2-3 sentences"",""causes"":[""...""],""nextSteps"":[""...""]}} +"; + } + + // ── OpenAI HTTP call ──────────────────────────────────────────── + + private static readonly string OpenAiUrl = "https://api.openai.com/v1/chat/completions"; + + private static async Task CallOpenAiAsync(string userPrompt) + { + try + { + var requestBody = new + { + model = "gpt-4o-mini", // cost-efficient, fast; swap to "gpt-4" if quality needs tuning + messages = new[] + { + new { role = "user", content = userPrompt } + }, + max_tokens = 400, + temperature = 0.2 // low temperature for factual consistency + }; + + var responseText = await OpenAiUrl + .SetHeader("Authorization", $"Bearer {_apiKey}") + .SetHeader("Content-Type", "application/json") + .PostJsonAsync(requestBody) + .ReceiveString(); + + // parse OpenAI envelope + var envelope = JsonConvert.DeserializeObject(responseText); + var content = (string?) envelope?.choices?[0]?.message?.content; + + if (string.IsNullOrWhiteSpace(content)) + { + Console.Error.WriteLine("[DiagnosticService] OpenAI returned empty content."); + return null; + } + + // parse the JSON the model produced + var diagnostic = JsonConvert.DeserializeObject(content); + return diagnostic; + } + catch (FlurlHttpException httpEx) + { + Console.Error.WriteLine($"[DiagnosticService] HTTP error {httpEx.Response?.StatusCode}: {await httpEx.Response?.GetStringAsync()}"); + return null; + } + catch (Exception ex) + { + Console.Error.WriteLine($"[DiagnosticService] {ex.Message}"); + return null; + } + } +} + +// ── config / response models ──────────────────────────────────────────────── + +public class OpenAiConfig +{ + public string ApiKey { get; set; } = ""; +} + +public class DiagnosticResponse +{ + public string Explanation { get; set; } = ""; + public IReadOnlyList Causes { get; set; } = Array.Empty(); + public IReadOnlyList NextSteps { get; set; } = Array.Empty(); +} diff --git a/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx b/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx index 9ef2ffa7e..a6ac90f1a 100644 --- a/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx +++ b/typescript/frontend-marios2/src/content/dashboards/Log/Log.tsx @@ -1,7 +1,9 @@ import React, { useContext, useEffect, useState } from 'react'; import { Alert, + Box, Card, + CircularProgress, Container, Divider, Grid, @@ -17,7 +19,7 @@ import { AxiosError, AxiosResponse } from 'axios/index'; import routes from '../../../Resources/routes.json'; import { useNavigate } from 'react-router-dom'; import { TokenContext } from '../../../contexts/tokenContext'; -import { ErrorMessage } from '../../../interfaces/S3Types'; +import { ErrorMessage, DiagnosticResponse } from '../../../interfaces/S3Types'; import Button from '@mui/material/Button'; import FormControlLabel from '@mui/material/FormControlLabel'; import Checkbox from '@mui/material/Checkbox'; @@ -45,6 +47,11 @@ function Log(props: LogProps) { const tokencontext = useContext(TokenContext); const { removeToken } = tokencontext; + const [diagnosis, setDiagnosis] = useState(null); + const [diagnosisLoading, setDiagnosisLoading] = useState(false); + const [diagnosisExpanded, setDiagnosisExpanded] = useState(false); + const [diagnosedError, setDiagnosedError] = useState(''); + useEffect(() => { axiosConfig .get(`/GetAllErrorsForInstallation?id=${props.id}`) @@ -71,6 +78,34 @@ function Log(props: LogProps) { }); }, [updateCount]); + // fetch AI diagnosis for the first unseen error (or warning if no unseen errors) + useEffect(() => { + const target = errors.find(e => !e.seen) || warnings.find(w => !w.seen); + + if (!target) { + setDiagnosis(null); + setDiagnosedError(''); + return; + } + + // already have a diagnosis for this exact description — skip + if (target.description === diagnosedError && diagnosis) return; + + setDiagnosisLoading(true); + axiosConfig + .get(`/DiagnoseError?installationId=${props.id}&errorDescription=${encodeURIComponent(target.description)}`) + .then((res: AxiosResponse) => { + setDiagnosis(res.data); + setDiagnosedError(target.description); + }) + .catch(() => { + setDiagnosis(null); + }) + .finally(() => { + setDiagnosisLoading(false); + }); + }, [errors, warnings]); + const handleErrorButtonPressed = () => { setErrorButtonPressed(!errorButtonPressed); }; @@ -108,6 +143,7 @@ function Log(props: LogProps) { }; const warningDescriptionMap: { [key: string]: string } = { + // BMS warnings "TaM1": "TaM1: BMS temperature high", "TbM1": "TbM1: Battery temperature high", "VBm1": "VBm1: Bus voltage low", @@ -124,10 +160,131 @@ function Log(props: LogProps) { "MPMM": "MPMM: Midpoint wiring problem", "TCdi": "TCdi: Temperature difference between strings high", "LMPW": "LMPW: String voltages unbalance warning", - "TOCW": "TOCW: Top of Charge requested" + "TOCW": "TOCW: Top of Charge requested", + + // Sinexcel warnings (WARNING/INFO severity) + "Inverted sequenceof grid voltage": "Grid phase sequence reversed", + "Excessivelyhigh ambient temperature": "Ambient temperature too high", + "Excessive radiator temperature": "Radiator/heatsink temperature high", + "Island protection": "Island protection active (auto-recovers)", + "Battery 1over voltage": "Battery 1 voltage too high", + "Battery 1under voltage": "Battery 1 voltage too low", + "Battery 1discharge end": "Battery 1 discharge complete (auto-recovers)", + "Battery 1inverted": "Battery 1 polarity reversed!", + "Battery 2over voltage": "Battery 2 voltage too high", + "Battery 2under voltage": "Battery 2 voltage too low", + "Battery 2discharge end": "Battery 2 discharge complete (auto-recovers)", + "Battery 2inverted": "Battery 2 polarity reversed!", + "PV 1notaccessed": "PV string 1 not accessible", + "PV 1over voltage": "PV string 1 voltage too high", + "PV 2notaccessed": "PV string 2 not accessible", + "PV 2over voltage": "PV string 2 voltage too high", + "DC busover voltage": "DC bus voltage too high", + "DC busunder voltage": "DC bus voltage too low", + "Inverter soft start failure": "Inverter soft-start failed", + "Battery 1soft start failure": "Battery 1 soft-start failed", + "Battery 2soft start failure": "Battery 2 soft-start failed", + "Output voltageDC overlimit": "DC component in output voltage high", + "Output currentDC overlimit": "DC component in output current high", + "Poorgrounding": "Poor ground connection detected", + "PV 1soft startfailure": "PV 1 soft-start failed", + "PV 2soft startfailure": "PV 2 soft-start failed", + "PCBover temperature": "PCB temperature too high", + "DC converter over temperature": "DC converter temperature high", + "Busslow over voltage": "Slow bus over-voltage", + "DC converter over voltage": "DC converter voltage high", + "DC converter over current": "DC converter current high", + "DC converter resonator over current": "DC converter resonator overcurrent", + "PV 1insufficient power": "PV 1 power insufficient (auto-recovers)", + "PV 2insufficient power": "PV 2 power insufficient (auto-recovers)", + "Battery 1insufficient power": "Battery 1 power insufficient (auto-recovers)", + "Battery 2insufficiency power": "Battery 2 power insufficient", + "Lithium battery 1 chargeforbidden": "Lithium battery 1 charging forbidden", + "Lithium battery 1 dischargeforbidden": "Lithium battery 1 discharging forbidden", + "Lithium battery 2 chargeforbidden": "Lithium battery 2 charging forbidden", + "Lithium battery 2 dischargeforbidden": "Lithium battery 2 discharging forbidden", + "Lithium battery 1full": "Lithium battery 1 fully charged", + "Lithium battery 1 dischargeend": "Lithium battery 1 discharge end", + "Lithium battery 2full": "Lithium battery 2 fully charged", + "Lithium battery 2 dischargeend": "Lithium battery 2 discharge end", + "Inverter over temperaturealarm": "Inverter over-temperature alarm", + "Inverter over temperature": "Inverter temperature high", + "DC converter over temperaturealarm": "DC converter over-temperature alarm", + "Systemderating": "System power derating active", + "PVaccessmethod erroralarm": "PV access method error", + "Parallelmodule missing": "Parallel module missing", + "Duplicatemachine numbersforparallel modules": "Duplicate parallel module IDs", + "Para meterconflictin parallelmodule": "Parameter conflict in parallel modules", + "Reservedalarms 4": "Reserved alarm 4", + "InverterSealPulse": "Inverter seal pulse active", + "PV 3over voltage": "PV 3 voltage too high", + "PV 3average current anomaly": "PV 3 current anomaly", + "PV 4over voltage": "PV 4 voltage too high", + "PV 4average current anomaly": "PV 4 current anomaly", + "PV 3soft startfailure": "PV 3 soft-start failed", + "PV 4soft startfailure": "PV 4 soft-start failed", + "Batteryaccessmethod error": "Battery access method error", + "Reservedalarms 5": "Reserved alarm 5", + "Battery 1backup prohibited": "Battery 1 backup prohibited", + "Battery 2backup prohibited": "Battery 2 backup prohibited", + "Bus soft startfailure": "Bus soft-start failed", + "Insufficient photovoltaic power": "Insufficient PV power", + "Photovoltaic 1 over current": "PV 1 overcurrent", + "Photovoltaic 2 over current": "PV 2 overcurrent", + "Photovoltaic 3 over current": "PV 3 overcurrent", + "Photovoltaic 4 over current": "PV 4 overcurrent", + "Battery 1over current": "Battery 1 overcurrent", + "Battery 2over current": "Battery 2 overcurrent", + "Battery 1charging sealingwave": "Battery 1 charge limiting", + "Battery 2charging sealingwave": "Battery 2 charge limiting", + + // Growatt warnings + "Warning 200": "String fault", + "Warning 201": "PV string/PID terminals abnormal", + "Warning 203": "PV1 or PV2 short circuited", + "Warning 208": "DC fuse blown", + "Warning 209": "DC input voltage too high", + "Warning 219": "PID function abnormal", + "Warning 220": "PV string disconnected", + "Warning 221": "PV string current unbalanced", + "Warning 300": "No grid connection / grid power failure", + "Warning 301": "Grid voltage out of range", + "Warning 302": "Grid frequency out of range", + "Warning 303": "System overload", + "Warning 308": "Meter disconnected", + "Warning 309": "Meter L/N reversed", + "Warning 310": "N-PE voltage abnormal", + "Warning 311": "Phase sequence error (auto-adjusts)", + "Warning 400": "Fan failure", + "Warning 401": "Meter abnormal", + "Warning 402": "Optimizer communication abnormal", + "Warning 407": "Over-temperature", + "Warning 408": "NTC temperature sensor broken", + "Warning 411": "Sync signal abnormal", + "Warning 412": "Grid connection requirements not met", + "Warning 500": "Inverter-battery communication failed", + "Warning 501": "Battery disconnected", + "Warning 502": "Battery voltage too high", + "Warning 503": "Battery voltage too low", + "Warning 504": "Battery terminals reversed", + "Warning 505": "Lead-acid battery temp sensor disconnected", + "Warning 506": "Battery temperature out of range", + "Warning 507": "BMS fault: charging/discharging failed", + "Warning 508": "Lithium battery overload protection", + "Warning 509": "BMS communication abnormal", + "Warning 510": "BAT SPD function abnormal", + "Warning 600": "Output DC component bias abnormal", + "Warning 601": "High DC in output voltage", + "Warning 602": "Off-grid output voltage too low", + "Warning 603": "Off-grid output voltage too high", + "Warning 604": "Off-grid output overcurrent", + "Warning 605": "Off-grid bus voltage too low", + "Warning 606": "Off-grid output overload", + "Warning 609": "Balanced circuit abnormal" }; const errorDescriptionMap: { [key: string]: string } = { + // BMS errors "Tam": "Tam: Recoverable, BMS temperature too low", "TaM2": "TaM2: Recoverable, BMS temperature too high", "Tbm": "Tbm: Recoverable, Battery temperature too low", @@ -153,12 +310,204 @@ function Log(props: LogProps) { "HTFS": "HTFS: Recoverable, Unrecoverable: Heater Fuse Blown", "DATA": "DATA: Recoverable, Unrecoverable: Parameters out of range", "LMPA": "LMPA: Unrecoverable, String voltages unbalance alarm", - "HEBT": "HEBT: Recoverable, oss of heartbeat" + "HEBT": "HEBT: Recoverable, oss of heartbeat", + + // Sinexcel errors (ERROR severity - require manual intervention) + "Abnormal grid voltage": "Grid voltage abnormal", + "Abnormal grid frequency": "Grid frequency abnormal", + "Grid voltage phase loss": "Grid phase loss detected", + "Abnormal output voltage": "Output voltage abnormal", + "Abnormal output frequency": "Output frequency abnormal", + "Abnormalnullline": "Null/neutral line abnormal", + "Insulation fault": "Insulation fault detected", + "Leakage protection fault": "Leakage/ground fault protection tripped", + "Auxiliary power fault": "Auxiliary power supply fault", + "Fan fault": "Cooling fan fault", + "Model capacity fault": "Model/capacity configuration fault", + "Abnormal lightning arrester": "Surge protection device abnormal", + "Battery 1not connected": "Battery 1 not connected", + "Battery 2not connected": "Battery 2 not connected", + "AbnormalPV 1current sharing": "PV 1 current sharing abnormal", + "AbnormalPV 2current sharing": "PV 2 current sharing abnormal", + "DC bus voltage unbalance": "DC bus voltage unbalance", + "System output overload": "System output overloaded", + "Inverter overload": "Inverter overloaded", + "Inverter overload timeout": "Inverter overload timeout", + "Battery 1overload timeout": "Battery 1 overload timeout", + "Battery 2overload timeout": "Battery 2 overload timeout", + "DSP 1para meter setting fault": "DSP 1 parameter setting fault", + "DSP 2para meter setting fault": "DSP 2 parameter setting fault", + "DSPversion compatibility fault": "DSP version compatibility fault", + "CPLDversion compatibility fault": "CPLD version compatibility fault", + "CPLD communication fault": "CPLD communication fault", + "DSP communication fault": "DSP communication fault", + "Relayself-checkfails": "Relay self-check failed", + "Abnormal inverter": "Abnormal inverter condition", + "Balancedcircuit overload timeout": "Balance circuit overload timeout", + "PV 1overload timeout": "PV 1 overload timeout", + "PV 2overload timeout": "PV 2 overload timeout", + "Abnormaloff-grid output voltage": "Off-grid output voltage abnormal", + "Parallel communicationalarm": "Parallel communication alarm", + "Inverter relayopen": "Inverter relay open", + "PV 3not connected": "PV 3 not connected", + "PV 4not connected": "PV 4 not connected", + "PV 3overload timeout": "PV 3 overload timeout", + "PV 4overload timeout": "PV 4 overload timeout", + "Abnormal diesel generator voltage": "Diesel generator voltage abnormal", + "Abnormal diesel generator frequency": "Diesel generator frequency abnormal", + "Diesel generator voltageoutof phase": "Diesel generator out of phase", + "Lead battery temperature abnormality": "Lead battery temperature abnormal", + "Abnormal grid current": "Grid current abnormal", + "Generator overload": "Generator overloaded", + "Opencircuitof power grid relay": "Grid relay open circuit", + "Shortcircuitof power grid relay": "Grid relay short circuit", + "generator Relayopencircuit": "Generator relay open circuit", + "generator Relayshortcircuit": "Generator relay short circuit", + "Load power overload": "Load power overload", + "Abnormal leakage self-check": "Leakage self-check abnormal", + + // Sinexcel PROTECTION errors (require service - do not restart) + "PV 1power tube fault": "PV 1 power tube fault - Contact Service", + "PV 2power tube fault": "PV 2 power tube fault - Contact Service", + "Battery 1power tube fault": "Battery 1 power tube fault - Contact Service", + "Battery 2power tube fault": "Battery 2 power tube fault - Contact Service", + "Inverter power tube fault": "Inverter power tube fault - Contact Service", + "Hardware bus over voltage": "Hardware bus overvoltage - Contact Service", + "Hardware over current": "Hardware overcurrent - Contact Service", + "DC converter hardware over voltage": "DC converter hardware overvoltage - Contact Service", + "DC converter hardware over current": "DC converter hardware overcurrent - Contact Service", + "Inverter relayshort circuit": "Inverter relay short circuit - Contact Service", + "Reverse meter connection": "Meter connected in reverse - Contact Service", + "PV 3power tube failure": "PV 3 power tube failure - Contact Service", + "PV 4power tube Failure": "PV 4 power tube failure - Contact Service", + "PV 3reverse connection": "PV 3 reverse connection - Contact Service", + "PV 4reverse connection": "PV 4 reverse connection - Contact Service", + "Diesel generator voltage reverse sequence": "Generator phase reversed - Contact Service", + + // Growatt errors (PROTECTION severity) + "Error 309": "Grid ROCOF abnormal", + "Error 311": "Export limitation fail-safe", + "Error 400": "DCI bias abnormal", + "Error 402": "High DC in output current", + "Error 404": "Bus voltage sampling abnormal", + "Error 405": "Relay fault", + "Error 408": "Over-temperature protection", + "Error 409": "Bus voltage abnormal", + "Error 411": "Internal communication failure", + "Error 412": "Temperature sensor disconnected", + "Error 413": "IGBT drive fault", + "Error 414": "EEPROM error", + "Error 415": "Auxiliary power supply abnormal", + "Error 416": "DC/AC overcurrent protection", + "Error 417": "Communication protocol mismatch", + "Error 418": "DSP/COM firmware mismatch", + "Error 419": "DSP software/hardware mismatch", + "Error 421": "CPLD abnormal", + "Error 422": "Redundancy sampling inconsistent", + "Error 423": "PWM pass-through signal failure", + "Error 425": "AFCI self-test failure", + "Error 426": "PV current sampling abnormal", + "Error 427": "AC current sampling abnormal", + "Error 429": "BUS soft-boot failure", + "Error 430": "EPO fault", + "Error 431": "Monitoring chip BOOT verification failed", + "Error 500": "BMS-inverter communication failed", + "Error 501": "BMS: battery charge/discharge failed", + "Error 503": "Battery voltage exceeds threshold", + "Error 504": "Battery temperature out of range", + "Error 506": "Battery open-circuited", + "Error 507": "Battery overload protection", + "Error 508": "BUS2 voltage abnormal", + "Error 509": "BAT charge overcurrent protection", + "Error 510": "BAT discharge overcurrent protection", + "Error 511": "BAT soft start failed", + "Error 601": "Off-grid bus voltage low", + "Error 602": "Abnormal voltage at off-grid terminal", + "Error 603": "Off-grid soft start failed", + "Error 604": "Off-grid output voltage abnormal", + "Error 605": "Balanced circuit self-test failed", + "Error 606": "High DC in output voltage", + "Error 608": "Off-grid parallel signal abnormal", + "AFCI Fault": "Arc fault detected - Check PV connections", + "GFCI High": "High leakage current detected", + "PV Voltage High": "DC input voltage exceeds limit" }; return ( + + {/* AI Diagnosis banner — shown when loading or a diagnosis is available */} + {(diagnosisLoading || diagnosis) && ( + + + + + {/* loading state */} + {diagnosisLoading && ( + + + + + + + )} + + {/* diagnosis result */} + {diagnosis && !diagnosisLoading && ( + <> + + + + + + {diagnosedError} + + + + + {diagnosis.explanation} + + + + + {diagnosisExpanded && ( + + + + +
    + {diagnosis.causes.map((cause, i) => ( +
  • {cause}
  • + ))} +
+ + + + +
    + {diagnosis.nextSteps.map((step, i) => ( +
  1. {step}
  2. + ))} +
+
+ )} + + )} +
+
+
+ )} +