restructure sodistore home Information tab
This commit is contained in:
parent
897f3137f5
commit
730f337502
|
|
@ -49,7 +49,10 @@ public class Installation : TreeNode
|
|||
public int BatteryClusterNumber { get; set; } = 0;
|
||||
public int BatteryNumber { get; set; } = 0;
|
||||
public string BatterySerialNumbers { get; set; } = "";
|
||||
|
||||
public string PvStringsPerInverter { get; set; } = "";
|
||||
public string InstallationModel { get; set; } = "";
|
||||
public string ExternalEms { get; set; } = "No";
|
||||
|
||||
[Ignore]
|
||||
public String OrderNumbers { get; set; }
|
||||
public String VrmLink { get; set; } = "";
|
||||
|
|
|
|||
|
|
@ -130,6 +130,11 @@ public static partial class Db
|
|||
fileConnection.CreateTable<TicketAiDiagnosis>();
|
||||
fileConnection.CreateTable<TicketTimelineEvent>();
|
||||
|
||||
// Migrate new columns: set defaults for existing rows where NULL or empty
|
||||
fileConnection.Execute("UPDATE Installation SET ExternalEms = 'No' WHERE ExternalEms IS NULL OR ExternalEms = ''");
|
||||
fileConnection.Execute("UPDATE Installation SET InstallationModel = '' WHERE InstallationModel IS NULL");
|
||||
fileConnection.Execute("UPDATE Installation SET PvStringsPerInverter = '' WHERE PvStringsPerInverter IS NULL");
|
||||
|
||||
return fileConnection;
|
||||
//return CopyDbToMemory(fileConnection);
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,112 @@
|
|||
// [inverter][cluster] = batteryCount
|
||||
export type PresetConfig = number[][];
|
||||
|
||||
// 3D array: [inverter][cluster][batteryIndex] = serialNumber
|
||||
export type BatterySnTree = string[][][];
|
||||
|
||||
export const INSTALLATION_PRESETS: Record<string, PresetConfig> = {
|
||||
'sodistore home 9': [[1, 1]],
|
||||
'sodistore home 18': [[2, 2]],
|
||||
'sodistore home 27': [[2, 2], [1, 1]],
|
||||
'sodistore home 36': [[2, 2], [2, 2]],
|
||||
};
|
||||
|
||||
export const buildEmptyTree = (preset: PresetConfig): BatterySnTree => {
|
||||
return preset.map((inv) =>
|
||||
inv.map((batteryCount) => Array.from({ length: batteryCount }, () => ''))
|
||||
);
|
||||
};
|
||||
|
||||
export const parseBatterySnTree = (
|
||||
raw: string,
|
||||
preset: PresetConfig
|
||||
): BatterySnTree => {
|
||||
if (!raw || raw.trim() === '') {
|
||||
return buildEmptyTree(preset);
|
||||
}
|
||||
|
||||
const isStructured = raw.includes('/') || raw.includes('|');
|
||||
|
||||
if (isStructured) {
|
||||
const inverters = raw.split('/');
|
||||
return preset.map((invPreset, invIdx) => {
|
||||
const clusterStr = inverters[invIdx] || '';
|
||||
const clusters = clusterStr ? clusterStr.split('|') : [];
|
||||
return invPreset.map((batteryCount, clIdx) => {
|
||||
const batteries = clusters[clIdx]
|
||||
? clusters[clIdx].split(',').map((s) => s.trim())
|
||||
: [];
|
||||
return Array.from({ length: batteryCount }, (_, i) => batteries[i] || '');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Legacy flat format: distribute by preset layout
|
||||
const allSns = raw
|
||||
.split(',')
|
||||
.map((s) => s.trim())
|
||||
.filter((s) => s !== '');
|
||||
let idx = 0;
|
||||
return preset.map((inv) =>
|
||||
inv.map((batteryCount) =>
|
||||
Array.from({ length: batteryCount }, () => allSns[idx++] || '')
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export const serializeBatterySnTree = (tree: BatterySnTree): string => {
|
||||
return tree
|
||||
.map((inv) => inv.map((cluster) => cluster.join(',')).join('|'))
|
||||
.join('/');
|
||||
};
|
||||
|
||||
export const remapTree = (
|
||||
oldTree: BatterySnTree,
|
||||
newPreset: PresetConfig
|
||||
): BatterySnTree => {
|
||||
return newPreset.map((inv, invIdx) =>
|
||||
inv.map((batteryCount, clIdx) =>
|
||||
Array.from(
|
||||
{ length: batteryCount },
|
||||
(_, batIdx) => oldTree[invIdx]?.[clIdx]?.[batIdx] || ''
|
||||
)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
export const computeFlatValues = (
|
||||
preset: PresetConfig,
|
||||
tree: BatterySnTree
|
||||
) => {
|
||||
const totalBatteries = preset.flat().reduce((a, b) => a + b, 0);
|
||||
const totalClusters = preset.reduce((sum, inv) => sum + inv.length, 0);
|
||||
return {
|
||||
batteryNumber: totalBatteries,
|
||||
batteryClusterNumber: totalClusters,
|
||||
batterySerialNumbers: serializeBatterySnTree(tree),
|
||||
};
|
||||
};
|
||||
|
||||
export const wouldLoseData = (
|
||||
oldTree: BatterySnTree,
|
||||
newPreset: PresetConfig
|
||||
): boolean => {
|
||||
for (let invIdx = 0; invIdx < oldTree.length; invIdx++) {
|
||||
for (let clIdx = 0; clIdx < (oldTree[invIdx] || []).length; clIdx++) {
|
||||
for (
|
||||
let batIdx = 0;
|
||||
batIdx < (oldTree[invIdx][clIdx] || []).length;
|
||||
batIdx++
|
||||
) {
|
||||
const sn = oldTree[invIdx][clIdx][batIdx];
|
||||
if (sn && sn.trim() !== '') {
|
||||
if (invIdx >= newPreset.length) return true;
|
||||
if (clIdx >= (newPreset[invIdx] || []).length) return true;
|
||||
const newBatCount = newPreset[invIdx]?.[clIdx] ?? 0;
|
||||
if (batIdx >= newBatCount) return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
|
@ -17,6 +17,7 @@ import { Close as CloseIcon } from '@mui/icons-material';
|
|||
import { I_Installation } from 'src/interfaces/InstallationTypes';
|
||||
import { InstallationsContext } from 'src/contexts/InstallationsContextProvider';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
import { INSTALLATION_PRESETS } from '../Information/installationSetupUtils';
|
||||
|
||||
interface SodistorehomeInstallationFormPros {
|
||||
cancel: () => void;
|
||||
|
|
@ -33,8 +34,10 @@ function SodistorehomeInstallationForm(props: SodistorehomeInstallationFormPros)
|
|||
location: '',
|
||||
country: '',
|
||||
vpnIp: '',
|
||||
installationModel: '',
|
||||
externalEms: 'No',
|
||||
});
|
||||
const requiredFields = ['name', 'location', 'country', 'vpnIp'];
|
||||
const requiredFields = ['name', 'location', 'country', 'vpnIp', 'installationModel'];
|
||||
|
||||
const DeviceTypes = [
|
||||
{ id: 3, name: 'Growatt' },
|
||||
|
|
@ -171,6 +174,42 @@ function SodistorehomeInstallationForm(props: SodistorehomeInstallationFormPros)
|
|||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormControl
|
||||
fullWidth
|
||||
required
|
||||
error={formValues.installationModel === ''}
|
||||
sx={{
|
||||
marginTop: 1,
|
||||
marginBottom: 1,
|
||||
width: 390
|
||||
}}
|
||||
>
|
||||
<InputLabel
|
||||
sx={{
|
||||
fontSize: 14,
|
||||
backgroundColor: 'white'
|
||||
}}
|
||||
>
|
||||
<FormattedMessage
|
||||
id="installationModel"
|
||||
defaultMessage="Installation Model"
|
||||
/>
|
||||
</InputLabel>
|
||||
<Select
|
||||
name="installationModel"
|
||||
value={formValues.installationModel || ''}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{Object.keys(INSTALLATION_PRESETS).map((name) => (
|
||||
<MenuItem key={name} value={name}>
|
||||
{name}
|
||||
</MenuItem>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<FormControl
|
||||
fullWidth
|
||||
|
|
|
|||
|
|
@ -18,6 +18,10 @@ export interface I_Installation extends I_S3Credentials {
|
|||
batteryClusterNumber: number;
|
||||
batteryNumber: number;
|
||||
batterySerialNumbers: string;
|
||||
pvStringsPerInverter: string;
|
||||
installationModel: string;
|
||||
externalEms: string;
|
||||
|
||||
parentId: number;
|
||||
s3WriteKey: string;
|
||||
s3WriteSecret: string;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,24 @@
|
|||
"live": "Live Daten",
|
||||
"deleteInstallation": "Installation löschen",
|
||||
"confirmDeleteInstallation": "Möchten Sie diese Installation löschen?",
|
||||
"installationModel": "Installationsmodell",
|
||||
"externalEms": "Externes EMS",
|
||||
"externalEmsOther": "Externes EMS (angeben)",
|
||||
"emsNo": "Nein",
|
||||
"emsOther": "Andere",
|
||||
"generalInfo": "Allgemeine Informationen",
|
||||
"installationSetup": "Installationseinrichtung",
|
||||
"selectModel": "Modell auswählen...",
|
||||
"inverterN": "Wechselrichter {n}",
|
||||
"clusterN": "Cluster {n}",
|
||||
"clustersBatteriesSummary": "{filledClusters}/{totalClusters} Cluster, {filledBat}/{totalBat} Batterien",
|
||||
"batteriesSummary": "{filled}/{total} Batterien",
|
||||
"inverterNSerialNumber": "Wechselrichter {n} Seriennummer",
|
||||
"dataloggerNSerialNumber": "Datenlogger {n} Seriennummer",
|
||||
"pvStringsOnInverterN": "Anzahl PV-Strings an Wechselrichter {n}",
|
||||
"batteryNSerialNumber": "Batterie {n} Seriennummer",
|
||||
"adminSection": "Admin",
|
||||
"confirmPresetSwitch": "Der Wechsel zu einer kleineren Konfiguration entfernt einige Batterie-Seriennummern. Fortfahren?",
|
||||
"bucketLabel": "Bucket",
|
||||
"deleteInstallationWarning": "Bitte notieren Sie den Bucket-Namen oben. Das Löschen der S3-Daten kann mehrere Minuten dauern. Überprüfen Sie nach dem Löschen in Exoscale, ob der Bucket entfernt wurde. Falls nicht, leeren und löschen Sie den Bucket manuell.",
|
||||
"errorOccured": "Ein Fehler ist aufgetreten",
|
||||
|
|
@ -85,6 +103,7 @@
|
|||
"noUsersWithDirectAccessToThis": "Keine Benutzer mit direktem Zugriff",
|
||||
"selectUsers": "Benutzer auswählen",
|
||||
"cancel": "Abbrechen",
|
||||
"continue": "Fortfahren",
|
||||
"addNewFolder": "Neuen Ordner hinzufügen",
|
||||
"addNewInstallation": "Neue Installation hinzufügen",
|
||||
"deleteFolder": "Ordner löschen",
|
||||
|
|
|
|||
|
|
@ -55,6 +55,24 @@
|
|||
"live": "Live View",
|
||||
"deleteInstallation": "Delete Installation",
|
||||
"confirmDeleteInstallation": "Do you want to delete this installation?",
|
||||
"installationModel": "Installation Model",
|
||||
"externalEms": "External EMS",
|
||||
"externalEmsOther": "External EMS (specify)",
|
||||
"emsNo": "No",
|
||||
"emsOther": "Other",
|
||||
"generalInfo": "General Info",
|
||||
"installationSetup": "Installation Setup",
|
||||
"selectModel": "Select model...",
|
||||
"inverterN": "Inverter {n}",
|
||||
"clusterN": "Cluster {n}",
|
||||
"clustersBatteriesSummary": "{filledClusters}/{totalClusters} clusters, {filledBat}/{totalBat} batteries",
|
||||
"batteriesSummary": "{filled}/{total} batteries",
|
||||
"inverterNSerialNumber": "Inverter {n} Serial Number",
|
||||
"dataloggerNSerialNumber": "Datalogger {n} Serial Number",
|
||||
"pvStringsOnInverterN": "Number of PV Strings on Inverter {n}",
|
||||
"batteryNSerialNumber": "Battery {n} Serial Number",
|
||||
"adminSection": "Admin",
|
||||
"confirmPresetSwitch": "Switching to a smaller configuration will remove some battery serial number entries. Continue?",
|
||||
"bucketLabel": "Bucket",
|
||||
"deleteInstallationWarning": "Please note the bucket name above. Purging S3 data may take several minutes. After deletion, verify in Exoscale that the bucket has been removed. If not, purge and delete the bucket manually.",
|
||||
"errorOccured": "An error has occurred",
|
||||
|
|
@ -67,6 +85,7 @@
|
|||
"noUsersWithDirectAccessToThis": "No users with direct access to this ",
|
||||
"selectUsers": "Select Users",
|
||||
"cancel": "Cancel",
|
||||
"continue": "Continue",
|
||||
"addNewFolder": "Add new Folder",
|
||||
"addNewInstallation": "Add new Installation",
|
||||
"deleteFolder": "Delete Folder",
|
||||
|
|
|
|||
|
|
@ -67,6 +67,24 @@
|
|||
"live": "Diffusion en direct",
|
||||
"deleteInstallation": "Supprimer l'installation",
|
||||
"confirmDeleteInstallation": "Voulez-vous supprimer cette installation ?",
|
||||
"installationModel": "Modèle d'installation",
|
||||
"externalEms": "EMS externe",
|
||||
"externalEmsOther": "EMS externe (préciser)",
|
||||
"emsNo": "Non",
|
||||
"emsOther": "Autre",
|
||||
"generalInfo": "Informations générales",
|
||||
"installationSetup": "Configuration de l'installation",
|
||||
"selectModel": "Sélectionner le modèle...",
|
||||
"inverterN": "Onduleur {n}",
|
||||
"clusterN": "Cluster {n}",
|
||||
"clustersBatteriesSummary": "{filledClusters}/{totalClusters} clusters, {filledBat}/{totalBat} batteries",
|
||||
"batteriesSummary": "{filled}/{total} batteries",
|
||||
"inverterNSerialNumber": "Numéro de série onduleur {n}",
|
||||
"dataloggerNSerialNumber": "Numéro de série datalogger {n}",
|
||||
"pvStringsOnInverterN": "Nombre de chaînes PV sur onduleur {n}",
|
||||
"batteryNSerialNumber": "Numéro de série batterie {n}",
|
||||
"adminSection": "Admin",
|
||||
"confirmPresetSwitch": "Le passage à une configuration plus petite supprimera certains numéros de série de batteries. Continuer ?",
|
||||
"bucketLabel": "Bucket",
|
||||
"deleteInstallationWarning": "Veuillez noter le nom du bucket ci-dessus. La purge des données S3 peut prendre plusieurs minutes. Après la suppression, vérifiez dans Exoscale que le bucket a bien été supprimé. Sinon, purgez et supprimez le bucket manuellement.",
|
||||
"errorOccured": "Une erreur s'est produite",
|
||||
|
|
@ -79,6 +97,7 @@
|
|||
"noUsersWithDirectAccessToThis": "Aucun utilisateur ayant un accès direct",
|
||||
"selectUsers": "Sélectionnez les utilisateurs",
|
||||
"cancel": "Annuler",
|
||||
"continue": "Continuer",
|
||||
"addNewFolder": "Ajouter un nouveau dossier",
|
||||
"addNewInstallation": "Ajouter une nouvelle installation",
|
||||
"deleteFolder": "Supprimer le dossier",
|
||||
|
|
|
|||
|
|
@ -55,6 +55,24 @@
|
|||
"live": "Vista in diretta",
|
||||
"deleteInstallation": "Elimina installazione",
|
||||
"confirmDeleteInstallation": "Vuoi eliminare questa installazione?",
|
||||
"installationModel": "Modello di installazione",
|
||||
"externalEms": "EMS esterno",
|
||||
"externalEmsOther": "EMS esterno (specificare)",
|
||||
"emsNo": "No",
|
||||
"emsOther": "Altro",
|
||||
"generalInfo": "Informazioni generali",
|
||||
"installationSetup": "Configurazione installazione",
|
||||
"selectModel": "Seleziona modello...",
|
||||
"inverterN": "Inverter {n}",
|
||||
"clusterN": "Cluster {n}",
|
||||
"clustersBatteriesSummary": "{filledClusters}/{totalClusters} cluster, {filledBat}/{totalBat} batterie",
|
||||
"batteriesSummary": "{filled}/{total} batterie",
|
||||
"inverterNSerialNumber": "Numero di serie inverter {n}",
|
||||
"dataloggerNSerialNumber": "Numero di serie datalogger {n}",
|
||||
"pvStringsOnInverterN": "Numero di stringhe PV sull'inverter {n}",
|
||||
"batteryNSerialNumber": "Numero di serie batteria {n}",
|
||||
"adminSection": "Admin",
|
||||
"confirmPresetSwitch": "Il passaggio a una configurazione più piccola rimuoverà alcuni numeri di serie delle batterie. Continuare?",
|
||||
"bucketLabel": "Bucket",
|
||||
"deleteInstallationWarning": "Prendi nota del nome del bucket qui sopra. L'eliminazione dei dati S3 potrebbe richiedere diversi minuti. Dopo l'eliminazione, verifica in Exoscale che il bucket sia stato rimosso. In caso contrario, svuota ed elimina il bucket manualmente.",
|
||||
"errorOccured": "Si è verificato un errore",
|
||||
|
|
@ -67,6 +85,7 @@
|
|||
"noUsersWithDirectAccessToThis": "Nessun utente con accesso diretto a questo",
|
||||
"selectUsers": "Seleziona utenti",
|
||||
"cancel": "Annulla",
|
||||
"continue": "Continua",
|
||||
"addNewFolder": "Aggiungi nuova cartella",
|
||||
"addNewInstallation": "Aggiungi nuova installazione",
|
||||
"deleteFolder": "Elimina cartella",
|
||||
|
|
|
|||
Loading…
Reference in New Issue