STANDARD: Metadata for Solar Plants
Contents
- Background solar plant levels
- Metadata structure
- Installation metadata
- Inverter metadata
- String metadata
- Module metadata
- Pyranometer metadata
- Power meter metadata
- Customer file metadata
Background solar plant levels
A solar plant consists of:
- Plant level - at the connection point with the rest of the building's or premises' electrical installation. Contains one or more solar installations.
- Installation level - group of inverters from one manufacturer or measured by one device (such as a solar gateway, solar hub, ...). (Usually in portals all inverters from one manufacturer are grouped as one installation). Has one or more solar inverters as children.
- Inverter level - individual inverters. Can contain one or more strings.
- String level - individual solar panel strings. Can contain one or more modules.
- Module level - individual solar module level. Primarily used by Solar Edge. Physical meaning is to be verified.
- Solar panel level - individual solar panel.
For each level there is data in influx db in a metric. See also STANDARD: Metrics data collection and STANDARD: Messages & alarm messages
Level | Influx metric / measurement | Example usage |
---|---|---|
Plant | solarPlantMetrics | All solar production combined for one address |
Installation | solarInstallationMetrics | All solar production from one portal, from one solar gateway, from one solar assistance solar hub |
Inverter | solarInverterMetrics | Solar production from an individual inverter |
String | solarStringMetrics | Solar production from an individual string |
Module | solarModuleMetrics | Solar production from an individual module |
Panels | solarPanelsMetrics | Solar production from an individual plant |
Metadata structure
See Metadata for devices standard
Installation metadata
/*
General (required!) properties
*/
nodeId: string = "";
nodeType: "solarInstallation" = "solarInstallation";
nodeInfluxSeries: any[] = [];
nodeParentsIds: string[] = [];
nodeChildrenIds: string[] = [];
name: string = "";
isInstaller: true = true;
isAdmin: true = true;
/*
Important optional properties
*/
info: {
installationType?: string; // Type of the installation
installationDate?: string; // Date at which an installation was built, in ISO8601 format
activationDate?: string; // Date at which Eniris started collecting information about an installation, in ISO8601 format
commissioningDate?: string; // Date at which an installation was approved after completion of any required tests, in ISO8601 format
minimalIrradiation?: number = 0; // The minimal irradiation in Wh/m², before an installation should be active (used to calculate the uptime)
productionOffset?: {
date: string; // in ISO8601 format
value: number;
}; // Specify the total production for a particular date
productionScalingFactor: number = 1; // Rescale all production values by this particular value
productionPrediction?: {
mode: "sumOfChildren"
}|{
mode: "systemPower_kWp"
systemPower_kWp: number
}|{
mode: "panelConfiguration",
panelConfiguration: {panelType: string, systemPower_kWp: number, azimuth_degrees: number, tilt_degrees: number}[]
} = { mode: "sumOfChildren" }; // The predicted production (used to calculate the PR can be calculated as either: 1) the sum of the predicted production of the child inverters, 2) predicted using a kWp value, 3) predicted using a panel configuration defined at the installation level
productionDistribution?: {
isStoredInVault: true
}|{
isStoredInVault: false,
values: number[] // Twelve numbers, with a sum equal to one, specifying how the production of an installation is distributed over the months of a year
} = { isStoredInVault: true };
/*
Less important optional properties
*/
timezone?: string; // Not yet in use, but this will be important in the future. Use one of the tz database names: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
imageUrl?: string = ""; // An empty string is treated the same as if the imageUrl were undefined
location?: {
address?: {
street?: string,
zip?: string,
city?: string,
state?: string,
country?: string
};
coordinates?: { lat?: number, lng?: number }; // {lat: 0, lng: 0} is treated the same as if the position were undefined
referenceMeteoStation?: string; // If no pyrano meters are defined, this is used to calculate the performance ratio. If left undefined and if there is a valid position, the meteostation closest to the position is automatically used
predictionMeteoStation?: string; // If no pyrano meters are defined, this is used to calculate the performance ratio. If left undefined and if there is a valid position, the meteostation closest to the position is automatically used
};
contacts?: ({
contactType: string,
isLocallyStored: true,
id: string,
name: string,
telephone: string,
email: string,
language: "NL"|"FR"|"EN"|"DE",
}|{
contactType: string,
isLocallyStored: false,
nodeId: string,
contactId: string
})[] = [];
code?: string = "";
unit?: "EUR"|"kWh" = "kWh";
note?: string = "";
dataCapture?: {
dataCaptureType: "scraping",
name: string,
url: string,
scriptLocation: string,
username: string
}|{
dataCaptureType: "api",
name: string,
url: string,
scriptLocation: string,
username?: string,
key?: string
}|{
dataCaptureType: "fileUpload",
name: string,
scriptLocation: string,
server: string,
folder: string
}|{
dataCaptureType: "solarGateway",
model: "CSE-H55N2",
serialNumber: string,
protocolDrivers: string[]
}|{
dataCaptureType: "moxa",
series: "OnCell G3100",
serialNumber: string,
protocolDrivers: string[]
}|{
dataCaptureType: "solarHub",
serialNumber: string
} = { dataCaptureType: "api", name: "", url: "" }; // THIS SOLAR INSTALLATION PROPERTY IS NOT AVAILABLE FOR SOLAR PLANTS
dataLink?: {
dataLinkType: "ethernet"
}|{
dataLinkType: "wifi",
SSID: string
}|{
dataLinkType: "cellular",
SIM: string,
IMEI: string,
IPAddress: string
} = { dataLinkType: "ethernet" };
isActive?: bool = true;
}
}
Inverter metadata
For inverters, the standard metadata should look like:
/*
General (required!) properties
*/
nodeId: string = "";
nodeType: "solarInverter" = "solarInverter";
nodeInfluxSeries: any[] = [];
nodeParentsIds: string[] = [];
nodeChildrenIds: string[] = [];
name: string = "";
isInstaller: true = true;
isAdmin: true = true;
info: {
/*
Optional properties
*/
status?: {
isActive: true
}|{
isActive: false
deactivationDate: string
replacedBy: string
} = { isActive: true };
model?: string;
serialNumber?: string;
series?: string;
maxPower_kWh: number;
manufacturer?: string;
activationDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
installationDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
commissioningDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
productionScalingFactor: number = 1; // Rescale all production values by this particular value
productionPrediction?: {
mode: "sumOfChildren"
}|{
mode: "systemPower_kWp"
systemPower_kWp: number
}|{
mode: "panelConfiguration",
panelConfiguration: {panelType: string, systemPower_kWp: number, azimuth_degrees: number, tilt_degrees: number}[]
} = { mode: "sumOfChildren" }; // The predicted production (used to calculate the PR can be calculated as either: 1) the sum of the predicted production of the child strings, 2) predicted using a kWp value, 3) predicted using a panel configuration defined at the inverter level
protocolDriverParameters?: dict; //Optional. Used by the solar gateway / moxa software. Not necessary to fill out by hand.
}
}
String metadata
The methode infoStrings() of an Eniris-Meter gives back a list of all possible strings, connected to their parents (inverters). For a string, the standard metadata should look like:
/*
General (required!) properties
*/
nodeId: string = "";
nodeType: "solarString" = "solarString";
nodeInfluxSeries: any[] = [];
nodeParentsIds: string[] = [];
nodeChildrenIds: string[] = [];
name: string = "";
isInstaller: true = true;
isAdmin: true = true;
/*
Optional properties
*/
info: {
serialNumber?: string;
model?: string;
series?: string;
manufacturer?: string;
activationDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
installationDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
commissioningDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
status?: {
isActive: true
}|{
isActive: false
deactivationDate: string
replacedBy: string
} = { isActive: true };
productionScalingFactor: number = 1; // Rescale all production values by this particular value
productionPrediction?: {
mode: "systemPower_kWp"
systemPower_kWp: number
}|{
mode: "panelConfiguration",
panelConfiguration: {panelType: string, systemPower_kWp: number, azimuth_degrees: number, tilt_degrees: number}[]
} = { mode: "systemPower_kWp", systemPower_kWp: 0 }; // The predicted production (used to calculate the PR can be calculated as either): 1) predicted using a kWp value, 3) predicted using a panel configuration defined at the inverter level
}
}
Module metadata
For a module, the standard physical metadata should look like:
"nodeId": "SolarString00001",
"nodeType": "solarModule",
"nodeInfluxSeries": [
{
"database": "eniris",
"retentionPolicy": "rp_one_m",
"measurement": "solarStringMetrics",
"tags": {
"stringId": "0030f9112b54",
"serialNo": "A713O3084"
},
"fields": [
"actualPowerTot_W",
"voltage_V",
"current_A"
]
}
],
"nodeParentsIds": [
"SolarInverter00001"
],
"nodeChildrenIds": [],
"active": true,
"replaceBy": "",
"manufacturer": "",
"serialNo": "",
"series": "",
"model": "",
"systemPower_kWp": 0, #default value is 0
"configuration": [
{
"numberOfPanels": 0.0,
"typeOfPanels": "",
"systemPower_kWp": 400,
"azimut_degr": 10,
"tilt_degr": 10
}
]
}
With the "id" we retrieve data from the corresponding metric in influx.
The methode getPhyiscalInfo() of an Eniris-Meter gives back a list of all possible modules
Pyranometer metadata
Pyranometers are the children of installations. So they are at the same level as inverters.
/*
General (required!) properties
*/
nodeId: string = "";
nodeType: "pyranometer";
nodeInfluxSeries: any[] = [];
nodeParentsIds: string[] = [];
nodeChildrenIds: string[] = [];
name: string = "";
isInstaller: true = true;
isAdmin: true = true;
/*
Optional properties
*/
info?: {
status?: {
isActive: true
}|{
isActive: false
deactivationDate: string
replacedBy: string
} = { isActive: true };
serialNumber?: string,
model?: string,
series?: string,
manufacturer?: string,
azimut_degrees?: number = 0,
tilt_degrees?: number = 0;
};
}
Power meter metadata
Power meters are the children of installations. So they are at the same level as inverters.
/*
General (required!) properties
*/
nodeId: string = "";
nodeType: "powerMeter";
nodeInfluxSeries: any[] = [];
nodeParentsIds: string[] = [];
nodeChildrenIds: string[] = [];
name: string = "";
isInstaller: true = true;
isAdmin: true = true;
/*
Optional properties
*/
info: {
/*
Optional properties
*/
status?: {
isActive: true
}|{
isActive: false
deactivationDate: string
replacedBy: string
} = { isActive: true };
isOfficial?: bool = false;
model?: string;
serialNumber?: string;
series?: string;
maxPower_kWh: number;
manufacturer?: string;
activationDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
installationDate?: string; // ISO8601 format, such as 2022-01-24T23:08:17.000Z
}
}
Customer file metadata
Power meters are the children of installations. So they are at the same level as inverters.
/*
General (required!) properties
*/
nodeId: string = "";
nodeType: "customerFile";
nodeInfluxSeries: any[] = [];
nodeParentsIds: string[] = [];
nodeChildrenIds: string[] = [];
name: string = "";
isInstaller: true = true;
isAdmin: true = true;
/*
Optional properties
*/
info: {
/*
Less important optional properties
*/
code?: string = "";
imageUrl?: string = ""; // An empty string is treated the same as if the imageUrl were undefined
address?: {
street: string,
zip: string,
city: string,
state: string,
country: string
} = {street: "", zip: "", city: "", state: "", country: ""};
position?: { lat: number, lng: number }; // {lat: 0, lng: 0} is treated the same as if the position were undefined
contacts?: ({
contactType: string,
isLocallyStored: true,
id: string,
name: string,
telephone: string,
email: string,
language: "NL"|"FR"|"EN"|"DE",
}|{
contactType: string,
isLocallyStored: false,
deviceId: string,
nodeId: string
})[] = [];
}
}