137 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			137 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
| // types/siteData.ts
 | |
| 
 | |
| const generateDailyData = (
 | |
|   type: 'consumption' | 'generation',
 | |
|   min: number,
 | |
|   max: number
 | |
| ): { time: string; value: number }[] => {
 | |
|   return Array.from({ length: 48 }, (_, i) => {
 | |
|     const hour = Math.floor(i / 2);
 | |
|     const minute = i % 2 === 0 ? '00' : '30';
 | |
|     const time = `${hour.toString().padStart(2, '0')}:${minute}`;
 | |
|     let value = Math.random() * (max - min) + min;
 | |
| 
 | |
|     if (type === 'generation') {
 | |
|       if (hour < 8 || hour >= 18) {
 | |
|         value = 0;
 | |
|       } else {
 | |
|         const peakHour = 13;
 | |
|         const offset = Math.abs(hour + (i % 2 === 0 ? 0 : 0.5) - peakHour);
 | |
|         value = Math.max(0, max - offset * 5 + Math.random() * 5);
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     return { time, value: parseFloat(value.toFixed(2)) };
 | |
|   });
 | |
| };
 | |
| 
 | |
| 
 | |
| export type SiteName = 'Site A' | 'Site B' | 'Site C';
 | |
| 
 | |
| export interface SiteDetails {
 | |
|     location: string;
 | |
|     inverterProvider: string;
 | |
|     emergencyContact: string;
 | |
|     lastSyncTimestamp: string;
 | |
|     consumptionData: number[]; // e.g., Daily consumption in kWh
 | |
|     generationData: number[]; // e.g., Daily generation in kWh
 | |
|     connectedDevices: string[];
 | |
|     // Properties for SystemOverview
 | |
|     systemStatus: string; // e.g., "Normal", "Faulty"
 | |
|     temperature: string; // e.g., "35°C"
 | |
|     solarPower: number; // Power generated by solar (kW) - Real-time
 | |
|     realTimePower: number; // Real-time power used (kW)
 | |
|     installedPower: number; // Installed capacity (kWp)
 | |
|     
 | |
|       dailyTimeSeriesData: {
 | |
|     consumption: { time: string; value: number }[];
 | |
|     generation: { time: string; value: number }[];
 | |
|   };
 | |
|     // For savings calculation:
 | |
|     gridImportPrice_RM_per_kWh: number; // Price paid for electricity from the grid
 | |
|     solarExportTariff_RM_per_kWh: number; // Price received for excess solar sent to grid (e.g., FiT)
 | |
|     theoreticalMaxGeneration_kWh?: number; // For efficiency calculation (e.g., based on installedPower * peak sun hours)
 | |
| }
 | |
| 
 | |
| // Helper function to sum data for monthly totals (if consumptionData/generationData are daily)
 | |
| const calculateMonthlyTotal = (dataArray: number[]): number => {
 | |
|     return dataArray.reduce((sum, value) => sum + value, 0);
 | |
| };
 | |
| 
 | |
| const generateYearlyDataInRange = (min: number, max: number) =>
 | |
|   Array(365)
 | |
|     .fill(0)
 | |
|     .map(() => Math.floor(Math.random() * (max - min + 1)) + min);
 | |
| 
 | |
| 
 | |
| export const mockSiteData: Record<SiteName, SiteDetails & {
 | |
|   dailyTimeSeriesData: {
 | |
|     consumption: { time: string; value: number }[];
 | |
|     generation: { time: string; value: number }[];
 | |
|   };
 | |
| }> = {
 | |
|   'Site A': {
 | |
|     location: 'Petaling Jaya, Selangor',
 | |
|     inverterProvider: 'SolarEdge',
 | |
|     emergencyContact: '+60 12-345 6789',
 | |
|     lastSyncTimestamp: '2025-06-03 15:30:00',
 | |
|     consumptionData: generateYearlyDataInRange(80, 250),
 | |
|     generationData: generateYearlyDataInRange(80, 250),
 | |
|     systemStatus: 'Normal',
 | |
|     temperature: '35°C',
 | |
|     solarPower: 108.4,
 | |
|     realTimePower: 108.4,
 | |
|     installedPower: 174.9,
 | |
|     gridImportPrice_RM_per_kWh: 0.50,
 | |
|     solarExportTariff_RM_per_kWh: 0.30,
 | |
|     theoreticalMaxGeneration_kWh: 80000,
 | |
|     connectedDevices: [],
 | |
|     dailyTimeSeriesData: {
 | |
|       consumption: generateDailyData('consumption', 80, 250),
 | |
|       generation: generateDailyData('generation', 80, 100),
 | |
|     },
 | |
|   },
 | |
|   'Site B': {
 | |
|     location: 'Kuala Lumpur, Wilayah Persekutuan',
 | |
|     inverterProvider: 'Huawei',
 | |
|     emergencyContact: '+60 19-876 5432',
 | |
|     lastSyncTimestamp: '2025-06-02 10:15:00',
 | |
|     consumptionData: generateYearlyDataInRange(200, 450),
 | |
|     generationData: generateYearlyDataInRange(200, 450),
 | |
|     systemStatus: 'Normal',
 | |
|     temperature: '32°C',
 | |
|     solarPower: 95.2,
 | |
|     realTimePower: 95.2,
 | |
|     installedPower: 150.0,
 | |
|     gridImportPrice_RM_per_kWh: 0.52,
 | |
|     solarExportTariff_RM_per_kWh: 0.32,
 | |
|     theoreticalMaxGeneration_kWh: 190000,
 | |
|     connectedDevices: [],
 | |
|     dailyTimeSeriesData: {
 | |
|       consumption: generateDailyData('consumption', 150, 300),
 | |
|       generation: generateDailyData('generation', 0, 120),
 | |
|     },
 | |
|   },
 | |
|   'Site C': {
 | |
|     location: 'Johor Bahru, Johor',
 | |
|     inverterProvider: 'Enphase',
 | |
|     emergencyContact: '+60 13-555 1234',
 | |
|     lastSyncTimestamp: '2025-06-03 08:00:00',
 | |
|     consumptionData: generateYearlyDataInRange(400, 550),
 | |
|     generationData: generateYearlyDataInRange(400, 550),
 | |
|     systemStatus: 'Faulty',
 | |
|     temperature: '30°C',
 | |
|     solarPower: 25.0,
 | |
|     realTimePower: 70.0,
 | |
|     installedPower: 120.0,
 | |
|     gridImportPrice_RM_per_kWh: 0.48,
 | |
|     solarExportTariff_RM_per_kWh: 0.28,
 | |
|     theoreticalMaxGeneration_kWh: 180000,
 | |
|     connectedDevices: [],
 | |
|     dailyTimeSeriesData: {
 | |
|       consumption: generateDailyData('consumption', 100, 200),
 | |
|       generation: generateDailyData('generation', 0, 90),
 | |
|     },
 | |
|   },
 | |
| };
 |