Added SodistoreGrid as an empty templated and built S3 bucket creation pipeline
This commit is contained in:
parent
7df4842980
commit
7aacddd761
|
|
@ -200,6 +200,8 @@ public class Controller : ControllerBase
|
|||
bucketPath = "s3://" + installation.S3BucketId + "-3e5b3069-214a-43ee-8d85-57d72000c19d/" + startTimestamp;
|
||||
else if (installation.Product == (int)ProductType.SodioHome)
|
||||
bucketPath = "s3://" + installation.S3BucketId + "-e7b9a240-3c5d-4d2e-a019-6d8b1f7b73fa/" + startTimestamp;
|
||||
else if (installation.Product == (int)ProductType.SodistoreGrid)
|
||||
bucketPath = "s3://" + installation.S3BucketId + "-5109c126-e141-43ab-8658-f3c44c838ae8/" + startTimestamp;
|
||||
else
|
||||
bucketPath = "s3://" + installation.S3BucketId + "-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e/" + startTimestamp;
|
||||
Console.WriteLine("Fetching data for "+startTimestamp);
|
||||
|
|
@ -546,6 +548,19 @@ public class Controller : ControllerBase
|
|||
.ToList();
|
||||
}
|
||||
|
||||
[HttpGet(nameof(GetAllSodistoreGridInstallations))]
|
||||
public ActionResult<IEnumerable<Installation>> GetAllSodistoreGridInstallations(Token authToken)
|
||||
{
|
||||
var user = Db.GetSession(authToken)?.User;
|
||||
|
||||
if (user is null)
|
||||
return Unauthorized();
|
||||
|
||||
return user
|
||||
.AccessibleInstallations(product:(int)ProductType.SodistoreGrid)
|
||||
.ToList();
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet(nameof(GetAllFolders))]
|
||||
|
|
@ -1513,6 +1528,7 @@ public class Controller : ControllerBase
|
|||
0 => config.GetConfigurationSalimax(), // Salimax
|
||||
3 => config.GetConfigurationSodistoreMax(), // SodiStoreMax
|
||||
2 => config.GetConfigurationSodistoreHome(), // SodiStoreHome
|
||||
4 => config.GetConfigurationSodistoreGrid(), // SodistoreGrid
|
||||
_ => config.GetConfigurationString() // fallback
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,12 @@ public class Configuration
|
|||
$"BatteriesCount: {BatteriesCount}, ClusterNumber: {ClusterNumber}, PvNumber: {PvNumber}, ControlPermission:{ControlPermission}, "+
|
||||
$"SinexcelTimeChargeandDischargePower: {TimeChargeandDischargePower}, SinexcelStartTimeChargeandDischargeDayandTime: {StartTimeChargeandDischargeDayandTime}, SinexcelStopTimeChargeandDischargeDayandTime: {StopTimeChargeandDischargeDayandTime}";
|
||||
}
|
||||
|
||||
// TODO: SodistoreGrid — update configuration fields when defined
|
||||
public string GetConfigurationSodistoreGrid()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
public enum CalibrationChargeType
|
||||
|
|
|
|||
|
|
@ -7,7 +7,8 @@ public enum ProductType
|
|||
Salimax = 0,
|
||||
Salidomo = 1,
|
||||
SodioHome =2,
|
||||
SodiStoreMax=3
|
||||
SodiStoreMax=3,
|
||||
SodistoreGrid=4
|
||||
}
|
||||
|
||||
public enum StatusType
|
||||
|
|
|
|||
|
|
@ -145,6 +145,7 @@ public static class ExoCmd
|
|||
const String method = "iam-role";
|
||||
String rolename = installation.Product==(int)ProductType.Salimax?Db.Installations.Count(f => f.Product == (int)ProductType.Salimax) + installation.Name:
|
||||
installation.Product==(int)ProductType.SodiStoreMax?Db.Installations.Count(f => f.Product == (int)ProductType.SodiStoreMax) + installation.Name:
|
||||
installation.Product==(int)ProductType.SodistoreGrid?Db.Installations.Count(f => f.Product == (int)ProductType.SodistoreGrid) + installation.Name:
|
||||
Db.Installations.Count(f => f.Product == (int)ProductType.Salidomo) + installation.Name;
|
||||
|
||||
|
||||
|
|
@ -320,6 +321,7 @@ public static class ExoCmd
|
|||
const String method = "iam-role";
|
||||
String rolename = installation.Product==(int)ProductType.Salimax?Db.Installations.Count(f => f.Product == (int)ProductType.Salimax) + installation.Name:
|
||||
installation.Product==(int)ProductType.SodiStoreMax?Db.Installations.Count(f => f.Product == (int)ProductType.SodiStoreMax) + installation.Name:
|
||||
installation.Product==(int)ProductType.SodistoreGrid?Db.Installations.Count(f => f.Product == (int)ProductType.SodistoreGrid) + installation.Name:
|
||||
Db.Installations.Count(f => f.Product == (int)ProductType.Salidomo) + installation.Name;
|
||||
|
||||
var contentString = $$"""
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ public static class InstallationMethods
|
|||
private static readonly String BucketNameSalt = "3e5b3069-214a-43ee-8d85-57d72000c19d";
|
||||
private static readonly String SalidomoBucketNameSalt = "c0436b6a-d276-4cd8-9c44-1eae86cf5d0e";
|
||||
private static readonly String SodioHomeBucketNameSalt = "e7b9a240-3c5d-4d2e-a019-6d8b1f7b73fa";
|
||||
private static readonly String SodistoreGridBucketNameSalt = "5109c126-e141-43ab-8658-f3c44c838ae8";
|
||||
|
||||
public static String BucketName(this Installation installation)
|
||||
{
|
||||
|
|
@ -23,6 +24,11 @@ public static class InstallationMethods
|
|||
return $"{installation.S3BucketId}-{SodioHomeBucketNameSalt}";
|
||||
}
|
||||
|
||||
if (installation.Product == (int)ProductType.SodistoreGrid)
|
||||
{
|
||||
return $"{installation.S3BucketId}-{SodistoreGridBucketNameSalt}";
|
||||
}
|
||||
|
||||
return $"{installation.S3BucketId}-{SalidomoBucketNameSalt}";
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ public static class SessionMethods
|
|||
|
||||
}
|
||||
|
||||
if (installation.Product == (int)ProductType.SodiStoreMax || installation.Product == (int)ProductType.SodioHome)
|
||||
if (installation.Product == (int)ProductType.SodiStoreMax || installation.Product == (int)ProductType.SodioHome || installation.Product == (int)ProductType.SodistoreGrid)
|
||||
{
|
||||
return user is not null
|
||||
&& user.UserType != 0
|
||||
|
|
@ -295,7 +295,7 @@ public static class SessionMethods
|
|||
.Apply(Db.Update);
|
||||
}
|
||||
|
||||
if (installation.Product == (int)ProductType.SodiStoreMax)
|
||||
if (installation.Product == (int)ProductType.SodiStoreMax || installation.Product == (int)ProductType.SodistoreGrid)
|
||||
{
|
||||
|
||||
return user is not null
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ public class DeleteOldDataFromS3
|
|||
{
|
||||
|
||||
string configPath = "/home/ubuntu/.s3cfg";
|
||||
string bucketPath = installation.Product ==(int)ProductType.Salidomo ? $"s3://{installation.S3BucketId}-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e/{timestamps_to_delete}*" : $"s3://{installation.S3BucketId}-3e5b3069-214a-43ee-8d85-57d72000c19d/{timestamps_to_delete}*" ;
|
||||
string bucketPath = installation.Product == (int)ProductType.Salidomo
|
||||
? $"s3://{installation.S3BucketId}-c0436b6a-d276-4cd8-9c44-1eae86cf5d0e/{timestamps_to_delete}*"
|
||||
: installation.Product == (int)ProductType.SodistoreGrid
|
||||
? $"s3://{installation.S3BucketId}-5109c126-e141-43ab-8658-f3c44c838ae8/{timestamps_to_delete}*"
|
||||
: $"s3://{installation.S3BucketId}-3e5b3069-214a-43ee-8d85-57d72000c19d/{timestamps_to_delete}*" ;
|
||||
|
||||
//Console.WriteLine($"Deleting old data from {bucketPath}");
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public class Session : Relation<String, Int64>
|
|||
public Boolean AccessToSalidomo { get; set; } = false;
|
||||
public Boolean AccessToSodistoreMax { get; set; } = false;
|
||||
public Boolean AccessToSodioHome { get; set; } = false;
|
||||
public Boolean AccessToSodistoreGrid { get; set; } = false;
|
||||
[Ignore] public Boolean Valid => DateTime.Now - LastSeen <=MaxAge ;
|
||||
|
||||
// Private backing field
|
||||
|
|
@ -49,6 +50,7 @@ public class Session : Relation<String, Int64>
|
|||
AccessToSalidomo = user.AccessibleInstallations(product: (int)ProductType.Salidomo).ToList().Count > 0;
|
||||
AccessToSodistoreMax = user.AccessibleInstallations(product: (int)ProductType.SodiStoreMax).ToList().Count > 0;
|
||||
AccessToSodioHome = user.AccessibleInstallations(product: (int)ProductType.SodioHome).ToList().Count > 0;
|
||||
AccessToSodistoreGrid = user.AccessibleInstallations(product: (int)ProductType.SodistoreGrid).ToList().Count > 0;
|
||||
|
||||
Console.WriteLine("salimax" +user.AccessibleInstallations(product: (int)ProductType.Salimax).ToList().Count);
|
||||
Console.WriteLine("AccessToSodistoreMax" +user.AccessibleInstallations(product: (int)ProductType.SodiStoreMax).ToList().Count);
|
||||
|
|
|
|||
|
|
@ -100,6 +100,11 @@ public static class RabbitMqManager
|
|||
monitorLink =
|
||||
$"https://monitor.inesco.energy/sodistore_installations/list/installation/{installation.S3BucketId}/batteryview";
|
||||
}
|
||||
else if (installation.Product == (int)ProductType.SodistoreGrid)
|
||||
{
|
||||
monitorLink =
|
||||
$"https://monitor.inesco.energy/sodistoregrid_installations/list/installation/{installation.S3BucketId}/batteryview";
|
||||
}
|
||||
else
|
||||
{
|
||||
monitorLink =
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@ public static class WebsocketManager
|
|||
if ((installationConnection.Value.Product == (int)ProductType.Salimax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.Salidomo && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(60)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.SodioHome && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(4)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.SodiStoreMax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2))
|
||||
(installationConnection.Value.Product == (int)ProductType.SodiStoreMax && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2)) ||
|
||||
(installationConnection.Value.Product == (int)ProductType.SodistoreGrid && (DateTime.Now - installationConnection.Value.Timestamp) > TimeSpan.FromMinutes(2))
|
||||
)
|
||||
{
|
||||
Console.WriteLine("Installation ID is " + installationConnection.Key);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,8 @@ function App() {
|
|||
setAccessToSalimax,
|
||||
setAccessToSalidomo,
|
||||
setAccessToSodiohome,
|
||||
setAccessToSodistore
|
||||
setAccessToSodistore,
|
||||
setAccessToSodistoreGrid
|
||||
} = useContext(ProductIdContext);
|
||||
|
||||
const [language, setLanguage] = useState<string>(
|
||||
|
|
@ -102,12 +103,15 @@ function App() {
|
|||
setAccessToSalidomo(response.data.accessToSalidomo);
|
||||
setAccessToSodiohome(response.data.accessToSodioHome);
|
||||
setAccessToSodistore(response.data.accessToSodistoreMax);
|
||||
setAccessToSodistoreGrid(response.data.accessToSodistoreGrid);
|
||||
if (response.data.accessToSalimax) {
|
||||
navigate(routes.installations);
|
||||
} else if (response.data.accessToSalidomo) {
|
||||
navigate(routes.salidomo_installations);
|
||||
} else if (response.data.accessToSodistoreMax) {
|
||||
navigate(routes.sodistore_installations);
|
||||
} else if (response.data.accessToSodistoreGrid) {
|
||||
navigate(routes.sodistoregrid_installations);
|
||||
} else {
|
||||
navigate(routes.sodiohome_installations);
|
||||
}
|
||||
|
|
@ -215,6 +219,15 @@ function App() {
|
|||
}
|
||||
/>
|
||||
|
||||
<Route
|
||||
path={routes.sodistoregrid_installations + '*'}
|
||||
element={
|
||||
<AccessContextProvider>
|
||||
<InstallationTabs product={4} />
|
||||
</AccessContextProvider>
|
||||
}
|
||||
/>
|
||||
|
||||
<Route path={routes.users + '*'} element={<Users />} />
|
||||
<Route
|
||||
path={'*'}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
"salidomo_installations": "/salidomo_installations/",
|
||||
"sodistore_installations": "/sodistore_installations/",
|
||||
"sodiohome_installations": "/sodiohome_installations/",
|
||||
"sodistoregrid_installations": "/sodistoregrid_installations/",
|
||||
"installation": "installation/",
|
||||
"login": "/login/",
|
||||
"forgotPassword": "/forgotPassword/",
|
||||
|
|
|
|||
|
|
@ -40,7 +40,8 @@ function Login() {
|
|||
setAccessToSalimax,
|
||||
setAccessToSalidomo,
|
||||
setAccessToSodiohome,
|
||||
setAccessToSodistore
|
||||
setAccessToSodistore,
|
||||
setAccessToSodistoreGrid
|
||||
} = useContext(ProductIdContext);
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
|
@ -84,6 +85,7 @@ function Login() {
|
|||
setAccessToSalidomo(response.data.accessToSalidomo);
|
||||
setAccessToSodiohome(response.data.accessToSodioHome);
|
||||
setAccessToSodistore(response.data.accessToSodistoreMax);
|
||||
setAccessToSodistoreGrid(response.data.accessToSodistoreGrid);
|
||||
|
||||
if (rememberMe) {
|
||||
cookies.set('rememberedUsername', username, { path: '/' });
|
||||
|
|
@ -95,6 +97,8 @@ function Login() {
|
|||
navigate(routes.salidomo_installations);
|
||||
} else if (response.data.accessToSodistoreMax) {
|
||||
navigate(routes.sodistore_installations);
|
||||
} else if (response.data.accessToSodistoreGrid) {
|
||||
navigate(routes.sodistoregrid_installations);
|
||||
} else {
|
||||
navigate(routes.sodiohome_installations);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ function BatteryView(props: BatteryViewProps) {
|
|||
) : (
|
||||
<TableCell align="center">Max Cell Voltage</TableCell>
|
||||
)}
|
||||
{product === 3 && (
|
||||
{(product === 3 || product === 4) && (
|
||||
<TableCell align="center">Voltage Difference</TableCell>
|
||||
)}
|
||||
</TableRow>
|
||||
|
|
@ -469,7 +469,7 @@ function BatteryView(props: BatteryViewProps) {
|
|||
</TableCell>
|
||||
</>
|
||||
)}
|
||||
{product === 3 && (
|
||||
{(product === 3 || product === 4) && (
|
||||
<>
|
||||
{(() => {
|
||||
const cellVoltagesString =
|
||||
|
|
@ -524,7 +524,7 @@ function BatteryView(props: BatteryViewProps) {
|
|||
})()}
|
||||
</>
|
||||
)}
|
||||
{product === 3 && (
|
||||
{(product === 3 || product === 4) && (
|
||||
<>
|
||||
{(() => {
|
||||
const cellVoltagesString =
|
||||
|
|
|
|||
|
|
@ -328,9 +328,12 @@ function Information(props: InformationProps) {
|
|||
label="S3 Bucket Name"
|
||||
name="s3bucketname"
|
||||
value={
|
||||
product === 0 || product == 3
|
||||
formValues.product === 0 || formValues.product == 3
|
||||
? formValues.s3BucketId +
|
||||
'-3e5b3069-214a-43ee-8d85-57d72000c19d'
|
||||
: formValues.product == 4
|
||||
? formValues.s3BucketId +
|
||||
'-5109c126-e141-43ab-8658-f3c44c838ae8'
|
||||
: formValues.s3BucketId +
|
||||
'-e7b9a240-3c5d-4d2e-a019-6d8b1f7b73fa'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,9 +57,13 @@ function Installation(props: singleInstallationProps) {
|
|||
s3BucketId: props.current_installation.s3BucketId
|
||||
};
|
||||
|
||||
// TODO: SodistoreGrid — uses its own bucket salt
|
||||
const s3BucketSalt =
|
||||
props.current_installation.product === 4
|
||||
? '5109c126-e141-43ab-8658-f3c44c838ae8'
|
||||
: '3e5b3069-214a-43ee-8d85-57d72000c19d';
|
||||
const s3Bucket =
|
||||
props.current_installation.s3BucketId.toString() +
|
||||
'-3e5b3069-214a-43ee-8d85-57d72000c19d';
|
||||
props.current_installation.s3BucketId.toString() + '-' + s3BucketSalt;
|
||||
|
||||
const s3Credentials = { s3Bucket, ...S3data };
|
||||
|
||||
|
|
@ -427,12 +431,15 @@ function Installation(props: singleInstallationProps) {
|
|||
}
|
||||
></Route>
|
||||
|
||||
{/* TODO: SodistoreGrid — PV View excluded, add back when data path is ready */}
|
||||
{props.current_installation.product !== 4 && (
|
||||
<Route
|
||||
path={routes.pvview + '/*'}
|
||||
element={
|
||||
<PvView values={values} connected={connected}></PvView>
|
||||
}
|
||||
></Route>
|
||||
)}
|
||||
|
||||
<Route
|
||||
path={routes.overview}
|
||||
|
|
@ -447,11 +454,28 @@ function Installation(props: singleInstallationProps) {
|
|||
<Route
|
||||
path={routes.live}
|
||||
element={
|
||||
props.current_installation.product === 4 ? (
|
||||
// TODO: SodistoreGrid — implement actual topology layout
|
||||
<Container
|
||||
maxWidth="xl"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '40vh'
|
||||
}}
|
||||
>
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
Live view coming soon
|
||||
</Typography>
|
||||
</Container>
|
||||
) : (
|
||||
<Topology
|
||||
values={values}
|
||||
connected={connected}
|
||||
loading={loading}
|
||||
></Topology>
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
|
|
@ -470,10 +494,27 @@ function Installation(props: singleInstallationProps) {
|
|||
<Route
|
||||
path={routes.configuration}
|
||||
element={
|
||||
props.current_installation.product === 4 ? (
|
||||
// TODO: SodistoreGrid — implement actual configuration
|
||||
<Container
|
||||
maxWidth="xl"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
height: '40vh'
|
||||
}}
|
||||
>
|
||||
<Typography variant="body1" color="text.secondary">
|
||||
Configuration not yet available
|
||||
</Typography>
|
||||
</Container>
|
||||
) : (
|
||||
<Configuration
|
||||
values={values}
|
||||
id={props.current_installation.id}
|
||||
></Configuration>
|
||||
)
|
||||
}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -39,11 +39,18 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
|
||||
const {
|
||||
salimax_or_sodistore_Installations,
|
||||
sodistoreGridInstallations,
|
||||
fetchAllInstallations,
|
||||
socket,
|
||||
openSocket,
|
||||
closeSocket
|
||||
} = useContext(InstallationsContext);
|
||||
|
||||
// Use the correct installations array based on product
|
||||
const installations =
|
||||
props.product === 4
|
||||
? sodistoreGridInstallations
|
||||
: salimax_or_sodistore_Installations;
|
||||
const { product, setProduct } = useContext(ProductIdContext);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -93,7 +100,10 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
return ret_path;
|
||||
};
|
||||
|
||||
const singleInstallationTabs =
|
||||
// TODO: SodistoreGrid — PV View excluded for product 4, add back when data path is ready
|
||||
const hidePvView = props.product === 4;
|
||||
|
||||
const singleInstallationTabs = (
|
||||
currentUser.userType == UserType.admin
|
||||
? [
|
||||
{
|
||||
|
|
@ -204,7 +214,8 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
<FormattedMessage id="information" defaultMessage="Information" />
|
||||
)
|
||||
}
|
||||
];
|
||||
]
|
||||
).filter((tab) => !(hidePvView && tab.value === 'pvview'));
|
||||
|
||||
const tabs =
|
||||
currentTab != 'list' &&
|
||||
|
|
@ -372,7 +383,12 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
}
|
||||
];
|
||||
|
||||
return salimax_or_sodistore_Installations.length > 1 ? (
|
||||
// Filter out PV View for SodistoreGrid
|
||||
const filteredTabs = hidePvView
|
||||
? tabs.filter((tab) => tab.value !== 'pvview')
|
||||
: tabs;
|
||||
|
||||
return installations.length > 1 ? (
|
||||
<>
|
||||
<Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
|
||||
<TabsContainerWrapper>
|
||||
|
|
@ -384,7 +400,7 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
textColor="primary"
|
||||
indicatorColor="primary"
|
||||
>
|
||||
{tabs.map((tab) => (
|
||||
{filteredTabs.map((tab) => (
|
||||
<Tab
|
||||
key={tab.value}
|
||||
value={tab.value}
|
||||
|
|
@ -415,7 +431,7 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
<Grid item xs={12}>
|
||||
<Box p={4}>
|
||||
<InstallationSearch
|
||||
installations={salimax_or_sodistore_Installations}
|
||||
installations={installations}
|
||||
/>
|
||||
</Box>
|
||||
</Grid>
|
||||
|
|
@ -428,6 +444,10 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
element={
|
||||
props.product === 0 ? (
|
||||
<Navigate to={routes.installations + routes.list} />
|
||||
) : props.product === 4 ? (
|
||||
<Navigate
|
||||
to={routes.sodistoregrid_installations + routes.list}
|
||||
/>
|
||||
) : (
|
||||
<Navigate
|
||||
to={routes.sodistore_installations + routes.list}
|
||||
|
|
@ -441,7 +461,7 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
</Container>
|
||||
<Footer />
|
||||
</>
|
||||
) : salimax_or_sodistore_Installations.length === 1 ? (
|
||||
) : installations.length === 1 ? (
|
||||
<>
|
||||
<Container maxWidth="xl" sx={{ marginTop: '20px' }} className="mainframe">
|
||||
<TabsContainerWrapper>
|
||||
|
|
@ -480,7 +500,7 @@ function InstallationTabs(props: InstallationTabsProps) {
|
|||
<Box p={4}>
|
||||
<Installation
|
||||
current_installation={
|
||||
salimax_or_sodistore_Installations[0]
|
||||
installations[0]
|
||||
}
|
||||
type="installation"
|
||||
></Installation>
|
||||
|
|
|
|||
|
|
@ -65,10 +65,11 @@ function TreeInformation(props: TreeInformationProps) {
|
|||
setProduct(e.target.value); // Directly update the product state
|
||||
};
|
||||
|
||||
const ProductTypes = ['Salimax', 'Salidomo', 'SodistoreHome', 'SodistoreMax'];
|
||||
const ProductTypes = ['Salimax', 'Salidomo', 'SodistoreHome', 'SodistoreMax', 'SodistoreGrid'];
|
||||
const ProductDisplayNames: Record<string, string> = {
|
||||
'SodistoreHome': 'Sodistore Home',
|
||||
'SodistoreMax': 'Sodistore Max'
|
||||
'SodistoreMax': 'Sodistore Max',
|
||||
'SodistoreGrid': 'Sodistore Grid'
|
||||
};
|
||||
|
||||
const isMobile = window.innerWidth <= 1490;
|
||||
|
|
@ -327,7 +328,8 @@ function TreeInformation(props: TreeInformationProps) {
|
|||
)}
|
||||
{openModalInstallation &&
|
||||
(product == 'Salimax' ||
|
||||
product == 'SodistoreMax') && (
|
||||
product == 'SodistoreMax' ||
|
||||
product == 'SodistoreGrid') && (
|
||||
<InstallationForm
|
||||
cancel={handleFormCancel}
|
||||
submit={handleInstallationFormSubmit}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,7 @@ function InstallationTree() {
|
|||
key={installation.id}
|
||||
path={routes.installation + installation.id + '/*'}
|
||||
element={
|
||||
installation.product == 0 || installation.product == 3 ? (
|
||||
installation.product == 0 || installation.product == 3 || installation.product == 4 ? (
|
||||
<Installation
|
||||
key={installation.id}
|
||||
current_installation={installation}
|
||||
|
|
|
|||
|
|
@ -31,6 +31,9 @@ const InstallationsContextProvider = ({
|
|||
const [sodiohomeInstallations, setSodiohomeInstallations] = useState<
|
||||
I_Installation[]
|
||||
>([]);
|
||||
const [sodistoreGridInstallations, setSodistoreGridInstallations] = useState<
|
||||
I_Installation[]
|
||||
>([]);
|
||||
const [foldersAndInstallations, setFoldersAndInstallations] = useState([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [error, setError] = useState(false);
|
||||
|
|
@ -89,16 +92,31 @@ const InstallationsContextProvider = ({
|
|||
: installation;
|
||||
});
|
||||
|
||||
const updatedSodistoreGrid = sodistoreGridInstallations.map(
|
||||
(installation) => {
|
||||
const update = pendingUpdates.current[installation.id];
|
||||
return update
|
||||
? {
|
||||
...installation,
|
||||
status: update.status,
|
||||
testingMode: update.testingMode
|
||||
}
|
||||
: installation;
|
||||
}
|
||||
);
|
||||
|
||||
setSalidomoInstallations(updatedSalidomo);
|
||||
setSalimax_Or_Sodistore_Installations(updatedSalimax);
|
||||
setSodiohomeInstallations(updatedSodiohome);
|
||||
setSodistoreGridInstallations(updatedSodistoreGrid);
|
||||
|
||||
// Clear the pending updates after applying
|
||||
pendingUpdates.current = {};
|
||||
}, [
|
||||
salidomoInstallations,
|
||||
salimax_or_sodistore_Installations,
|
||||
sodiohomeInstallations
|
||||
sodiohomeInstallations,
|
||||
sodistoreGridInstallations
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -172,6 +190,8 @@ const InstallationsContextProvider = ({
|
|||
setSalidomoInstallations(res.data);
|
||||
} else if (product === 0 || product === 3) {
|
||||
setSalimax_Or_Sodistore_Installations(res.data);
|
||||
} else if (product === 4) {
|
||||
setSodistoreGridInstallations(res.data);
|
||||
}
|
||||
|
||||
if (open_socket) {
|
||||
|
|
@ -390,6 +410,7 @@ const InstallationsContextProvider = ({
|
|||
salimax_or_sodistore_Installations,
|
||||
salidomoInstallations,
|
||||
sodiohomeInstallations,
|
||||
sodistoreGridInstallations,
|
||||
foldersAndInstallations,
|
||||
fetchAllInstallations,
|
||||
fetchAllFoldersAndInstallations,
|
||||
|
|
@ -416,6 +437,7 @@ const InstallationsContextProvider = ({
|
|||
salimax_or_sodistore_Installations,
|
||||
salidomoInstallations,
|
||||
sodiohomeInstallations,
|
||||
sodistoreGridInstallations,
|
||||
foldersAndInstallations,
|
||||
loading,
|
||||
error,
|
||||
|
|
|
|||
|
|
@ -9,10 +9,12 @@ interface ProductIdContextType {
|
|||
accessToSalidomo: boolean;
|
||||
accessToSodiohome: boolean;
|
||||
accessToSodistore: boolean;
|
||||
accessToSodistoreGrid: boolean;
|
||||
setAccessToSalimax: (access: boolean) => void;
|
||||
setAccessToSalidomo: (access: boolean) => void;
|
||||
setAccessToSodiohome: (access: boolean) => void;
|
||||
setAccessToSodistore: (access: boolean) => void;
|
||||
setAccessToSodistoreGrid: (access: boolean) => void;
|
||||
}
|
||||
|
||||
// Create the context.
|
||||
|
|
@ -43,6 +45,10 @@ export const ProductIdContextProvider = ({
|
|||
const storedValue = localStorage.getItem('accessToSodistore');
|
||||
return storedValue === 'true';
|
||||
});
|
||||
const [accessToSodistoreGrid, setAccessToSodistoreGrid] = useState(() => {
|
||||
const storedValue = localStorage.getItem('accessToSodistoreGrid');
|
||||
return storedValue === 'true';
|
||||
});
|
||||
// const [product, setProduct] = useState(location.includes('salidomo') ? 1 : 0);
|
||||
// const [product, setProduct] = useState<number>(
|
||||
// productMapping[Object.keys(productMapping).find((key) => location.includes(key)) || ''] || -1
|
||||
|
|
@ -52,6 +58,8 @@ export const ProductIdContextProvider = ({
|
|||
return 1;
|
||||
} else if (location.includes('sodiohome')) {
|
||||
return 2;
|
||||
} else if (location.includes('sodistoregrid')) {
|
||||
return 4;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -80,6 +88,10 @@ export const ProductIdContextProvider = ({
|
|||
setAccessToSodistore(access);
|
||||
localStorage.setItem('accessToSodistore', JSON.stringify(access));
|
||||
};
|
||||
const changeAccessSodistoreGrid = (access: boolean) => {
|
||||
setAccessToSodistoreGrid(access);
|
||||
localStorage.setItem('accessToSodistoreGrid', JSON.stringify(access));
|
||||
};
|
||||
|
||||
return (
|
||||
<ProductIdContext.Provider
|
||||
|
|
@ -90,10 +102,12 @@ export const ProductIdContextProvider = ({
|
|||
accessToSalidomo,
|
||||
accessToSodiohome,
|
||||
accessToSodistore,
|
||||
accessToSodistoreGrid,
|
||||
setAccessToSalimax: changeAccessSalimax,
|
||||
setAccessToSalidomo: changeAccessSalidomo,
|
||||
setAccessToSodiohome: changeAccessSodiohome,
|
||||
setAccessToSodistore: changeAccessSodistore
|
||||
setAccessToSodistore: changeAccessSodistore,
|
||||
setAccessToSodistoreGrid: changeAccessSodistoreGrid
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
|
|
|
|||
|
|
@ -89,8 +89,9 @@ export const transformInputToBatteryViewDataJson = async (
|
|||
const categories = isSodioHome
|
||||
? ['Soc', 'Power', 'Voltage', 'Current', 'Soh']
|
||||
: ['Soc', 'Temperature', 'Power', 'Voltage', 'Current'];
|
||||
// TODO: SodistoreGrid — update data paths when installation data format is finalized
|
||||
const pathCategories =
|
||||
product === 3
|
||||
product === 3 || product === 4
|
||||
? [
|
||||
'.BatteryDeligreenDataRecord.Soc',
|
||||
'.BatteryDeligreenDataRecord.TemperaturesList.EnvironmentTemperature',
|
||||
|
|
@ -167,7 +168,7 @@ export const transformInputToBatteryViewDataJson = async (
|
|||
);
|
||||
|
||||
const adjustedTimestamp =
|
||||
product == 0 || product == 2 || product == 3
|
||||
product == 0 || product == 2 || product == 3 || product == 4
|
||||
? new Date(timestampArray[i] * 1000)
|
||||
: new Date(timestampArray[i] * 100000);
|
||||
//Timezone offset is negative, so we convert the timestamp to the current zone by subtracting the corresponding offset
|
||||
|
|
@ -270,7 +271,7 @@ export const transformInputToBatteryViewDataJson = async (
|
|||
if (battery_nodes.length > old_length) {
|
||||
battery_nodes.forEach((node) => {
|
||||
const node_number =
|
||||
product == 3 ? Number(node) + 1 : Number(node) - 1;
|
||||
product == 3 || product == 4 ? Number(node) + 1 : Number(node) - 1;
|
||||
if (!pathsToSave.includes('Node' + node_number)) {
|
||||
pathsToSave.push('Node' + node_number);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ function SidebarMenu() {
|
|||
accessToSalimax,
|
||||
accessToSodistore,
|
||||
accessToSalidomo,
|
||||
accessToSodiohome
|
||||
accessToSodiohome,
|
||||
accessToSodistoreGrid
|
||||
} = useContext(ProductIdContext);
|
||||
|
||||
return (
|
||||
|
|
@ -242,6 +243,27 @@ function SidebarMenu() {
|
|||
</List>
|
||||
)}
|
||||
|
||||
{accessToSodistoreGrid && (
|
||||
<List component="div">
|
||||
<ListItem component="div">
|
||||
<Button
|
||||
disableRipple
|
||||
component={RouterLink}
|
||||
onClick={closeSidebar}
|
||||
to="/sodistoregrid_installations"
|
||||
startIcon={<BrightnessLowTwoToneIcon />}
|
||||
>
|
||||
<Box sx={{ marginTop: '3px' }}>
|
||||
<FormattedMessage
|
||||
id="sodistoregrid"
|
||||
defaultMessage="Sodistore Grid"
|
||||
/>
|
||||
</Box>
|
||||
</Button>
|
||||
</ListItem>
|
||||
</List>
|
||||
)}
|
||||
|
||||
{accessToSodiohome && (
|
||||
<List component="div">
|
||||
<ListItem component="div">
|
||||
|
|
|
|||
Loading…
Reference in New Issue