提交 f0722ec0 编写于 作者: nengyuangzhang's avatar nengyuangzhang

updated EnergyStoreagePowerStation

上级 78b3bfd5
......@@ -39,6 +39,7 @@ from reports import equipmentstatistics
from reports import equipmenttracking
from reports import energystoragepowerstationdetails
from reports import energystoragepowerstationlist
from reports import energystoragepowerstationreporting
from reports import fddfault
from reports import meterbatch
from reports import metercarbon
......@@ -833,6 +834,8 @@ api.add_route('/reports/energystoragepowerstationdetails',
energystoragepowerstationdetails.Reporting())
api.add_route('/reports/energystoragepowerstationlist',
energystoragepowerstationlist.Reporting())
api.add_route('/reports/energystoragepowerstationreporting',
energystoragepowerstationreporting.Reporting())
api.add_route('/reports/equipmentbatch',
equipmentbatch.Reporting())
api.add_route('/reports/equipmentcarbon',
......
......@@ -42,8 +42,8 @@ class Reporting:
api_key_control(req)
print(req.params)
# this procedure accepts energy storage power station id or uuid
energy_storage_power_station_id = req.params.get('energystoragepowerstationid')
energy_storage_power_station_uuid = req.params.get('energystoragepowerstationuuid')
energy_storage_power_station_id = req.params.get('id')
energy_storage_power_station_uuid = req.params.get('uuid')
################################################################################################################
# Step 1: valid parameters
......
import re
from datetime import datetime, timedelta, timezone
from decimal import Decimal
import falcon
import mysql.connector
import simplejson as json
from core.useractivity import access_control, api_key_control
import config
class Reporting:
@staticmethod
def __init__():
"""Initializes Class"""
pass
@staticmethod
def on_options(req, resp):
resp.status = falcon.HTTP_200
####################################################################################################################
# PROCEDURES
# Step 1: valid parameters
# Step 2: query the energy storage power station
# Step 3: query associated containers
# Step 4: query associated batteries in containers
# Step 5: query associated power conversion systems in containers
# Step 6: query associated grids in containers
# Step 7: query associated loads in containers
# Step 8: query associated sensors in containers
# Step 9: query associated meters data in containers
# Step 10: query associated points data in containers
# Step 11: construct the report
####################################################################################################################
@staticmethod
def on_get(req, resp):
if 'API-KEY' not in req.headers or \
not isinstance(req.headers['API-KEY'], str) or \
len(str.strip(req.headers['API-KEY'])) == 0:
access_control(req)
else:
api_key_control(req)
print(req.params)
# this procedure accepts energy storage power station id or uuid
energy_storage_power_station_id = req.params.get('id')
energy_storage_power_station_uuid = req.params.get('uuid')
################################################################################################################
# Step 1: valid parameters
################################################################################################################
if energy_storage_power_station_id is None and energy_storage_power_station_uuid is None:
raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_ENERGY_STORAGE_POWER_STATION_ID')
if energy_storage_power_station_id is not None:
energy_storage_power_station_id = str.strip(energy_storage_power_station_id)
if not energy_storage_power_station_id.isdigit() or int(energy_storage_power_station_id) <= 0:
raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_ENERGY_STORAGE_POWER_STATION_ID')
if energy_storage_power_station_uuid is not None:
regex = re.compile(r'^[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}\Z', re.I)
match = regex.match(str.strip(energy_storage_power_station_uuid))
if not bool(match):
raise falcon.HTTPError(status=falcon.HTTP_400, title='API.BAD_REQUEST',
description='API.INVALID_ENERGY_STORAGE_POWER_STATION_UUID')
reporting_start_datetime_utc = datetime.utcnow() - timedelta(days=1)
reporting_end_datetime_utc = datetime.utcnow()
################################################################################################################
# Step 2: query the energy storage power station
################################################################################################################
cnx_system = mysql.connector.connect(**config.myems_system_db)
cursor_system = cnx_system.cursor()
query = (" SELECT id, name, uuid "
" FROM tbl_contacts ")
cursor_system.execute(query)
rows_contacts = cursor_system.fetchall()
contact_dict = dict()
if rows_contacts is not None and len(rows_contacts) > 0:
for row in rows_contacts:
contact_dict[row[0]] = {"id": row[0],
"name": row[1],
"uuid": row[2]}
query = (" SELECT id, name, uuid "
" FROM tbl_cost_centers ")
cursor_system.execute(query)
rows_cost_centers = cursor_system.fetchall()
cost_center_dict = dict()
if rows_cost_centers is not None and len(rows_cost_centers) > 0:
for row in rows_cost_centers:
cost_center_dict[row[0]] = {"id": row[0],
"name": row[1],
"uuid": row[2]}
if energy_storage_power_station_id is not None:
query = (" SELECT id, name, uuid, "
" address, postal_code, latitude, longitude, capacity, "
" contact_id, cost_center_id, svg, description "
" FROM tbl_energy_storage_power_stations "
" WHERE id = %s ")
cursor_system.execute(query, (energy_storage_power_station_id,))
row = cursor_system.fetchone()
elif energy_storage_power_station_uuid is not None:
query = (" SELECT id, name, uuid, "
" address, postal_code, latitude, longitude, capacity, "
" contact_id, cost_center_id, svg, description "
" FROM tbl_energy_storage_power_stations "
" WHERE uuid = %s ")
cursor_system.execute(query, (energy_storage_power_station_uuid,))
row = cursor_system.fetchone()
if row is None:
cursor_system.close()
cnx_system.close()
raise falcon.HTTPError(status=falcon.HTTP_404, title='API.NOT_FOUND',
description='API.ENERGY_STORAGE_POWER_STATION_NOT_FOUND')
else:
energy_storage_power_station_id = row[0]
contact = contact_dict.get(row[8], None)
cost_center = cost_center_dict.get(row[9], None)
meta_result = {"id": row[0],
"name": row[1],
"uuid": row[2],
"address": row[3],
"postal_code": row[4],
"latitude": row[5],
"longitude": row[6],
"capacity": row[7],
"contact": contact,
"cost_center": cost_center,
"svg": row[10],
"description": row[11],
"qrcode": 'energystoragepowerstation:' + row[2]}
point_list = list()
meter_list = list()
# query all energy categories in system
cursor_system.execute(" SELECT id, name, unit_of_measure, kgce, kgco2e "
" FROM tbl_energy_categories "
" ORDER BY id ", )
rows_energy_categories = cursor_system.fetchall()
if rows_energy_categories is None or len(rows_energy_categories) == 0:
if cursor_system:
cursor_system.close()
if cnx_system:
cnx_system.close()
raise falcon.HTTPError(status=falcon.HTTP_404,
title='API.NOT_FOUND',
description='API.ENERGY_CATEGORY_NOT_FOUND')
energy_category_dict = dict()
for row_energy_category in rows_energy_categories:
energy_category_dict[row_energy_category[0]] = {"name": row_energy_category[1],
"unit_of_measure": row_energy_category[2],
"kgce": row_energy_category[3],
"kgco2e": row_energy_category[4]}
################################################################################################################
# Step 3: query associated containers
################################################################################################################
# todo
################################################################################################################
# Step 4: query associated batteries in containers
################################################################################################################
# todo
################################################################################################################
# Step 5: query associated power conversion systems in containers
################################################################################################################
# todo
################################################################################################################
# Step 6: query associated grids in containers
################################################################################################################
# todo
################################################################################################################
# Step 7: query associated loads in containers
################################################################################################################
# todo
################################################################################################################
# Step 8: query associated sensors in containers
################################################################################################################
# todo
################################################################################################################
# Step 9: query associated meters data in containers
################################################################################################################
# todo
################################################################################################################
# Step 10: query associated points data in containers
################################################################################################################
parameters_data = dict()
parameters_data['names'] = list()
parameters_data['timestamps'] = list()
parameters_data['values'] = list()
if cursor_system:
cursor_system.close()
if cnx_system:
cnx_system.close()
# if cursor_historical:
# cursor_historical.close()
# if cnx_historical:
# cnx_historical.close()
################################################################################################################
# Step 11: construct the report
################################################################################################################
result = dict()
result['energy_storage_power_station'] = meta_result
result['parameters'] = {
"names": parameters_data['names'],
"timestamps": parameters_data['timestamps'],
"values": parameters_data['values']
}
result['reporting_period'] = dict()
result['reporting_period']['names'] = list()
result['reporting_period']['units'] = list()
result['reporting_period']['subtotals'] = list()
result['reporting_period']['increment_rates'] = list()
result['reporting_period']['timestamps'] = list()
result['reporting_period']['values'] = list()
resp.text = json.dumps(result)
import React, { Fragment, useState, useEffect } from 'react';
import {
Breadcrumb,
BreadcrumbItem,
Button,
ButtonGroup,
Card,
CardBody,
Col,
CustomInput,
Row,
Form,
FormGroup,
Input,
Label,
Spinner,
} from 'reactstrap';
import Loader from '../../common/Loader';
import { isIterableArray } from '../../../helpers/utils';
import Flex from '../../common/Flex';
import classNames from 'classnames';
import EnergyStoragePowerStationList from './EnergyStoragePowerStationList';
import EnergyStoragePowerStationFooter from './EnergyStoragePowerStationFooter';
import usePagination from '../../../hooks/usePagination';
import { getCookieValue, createCookie, checkEmpty } from '../../../helpers/utils';
import withRedirect from '../../../hoc/withRedirect';
import { withTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { APIBaseURL, settings } from '../../../config';
import CustomizeMapBox from '../common/CustomizeMapBox';
const EnergyStoragePowerStation = ({ setRedirect, setRedirectUrl, t }) => {
useEffect(() => {
let is_logged_in = getCookieValue('is_logged_in');
let user_name = getCookieValue('user_name');
let user_display_name = getCookieValue('user_display_name');
let user_uuid = getCookieValue('user_uuid');
let token = getCookieValue('token');
if (checkEmpty(is_logged_in) || checkEmpty(token)|| checkEmpty(user_uuid) || !is_logged_in) {
setRedirectUrl(`/authentication/basic/login`);
setRedirect(true);
} else {
//update expires time of cookies
createCookie('is_logged_in', true, settings.cookieExpireTime);
createCookie('user_name', user_name, settings.cookieExpireTime);
createCookie('user_display_name', user_display_name, settings.cookieExpireTime);
createCookie('user_uuid', user_uuid, settings.cookieExpireTime);
createCookie('token', token, settings.cookieExpireTime);
}
});
useEffect(() => {
let timer = setInterval(() => {
let is_logged_in = getCookieValue('is_logged_in');
if (is_logged_in === null || !is_logged_in) {
setRedirectUrl(`/authentication/basic/login`);
setRedirect(true);
}
}, 1000);
return () => clearInterval(timer);
}, []);
// State
const [energyStoragePowerStationArray, setEnergyStoragePowerStationArray] = useState([]);
const [energyStoragePowerStationIds, setEnergyStoragePowerStationIds] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [geojson, setGeojson] = useState([]);
const [rootLatitude, setRootLatitude] = useState('');
const [rootLongitude, setRootLongitude] = useState('');
useEffect(() => {
let isResponseOK = false;
fetch(APIBaseURL + '/reports/energystoragepowerstationlist', {
method: 'GET',
headers: {
"Content-type": "application/json",
"User-UUID": getCookieValue('user_uuid'),
"Token": getCookieValue('token')
},
body: null,
}).then(response => {
console.log(response);
if (response.ok) {
isResponseOK = true;
}
return response.json();
}).then(json => {
console.log(json);
if (isResponseOK) {
console.log(json);
setEnergyStoragePowerStationArray([]);
setEnergyStoragePowerStationIds([]);
let energyStoragePowerStationArray = [];
let energyStoragePowerStationIds = [];
let geojsonData = [];
if (json.length > 0) {
setRootLongitude(json[0]['longitude']);
setRootLatitude(json[0]['latitude']);
json.forEach((currentValue, index) => {
let energyStoragePowerStation = {}
energyStoragePowerStation['id'] = json[index]['id'];
energyStoragePowerStation['name'] = json[index]['name'];
energyStoragePowerStation['uuid'] = json[index]['uuid'];
energyStoragePowerStation['address'] = json[index]['address'];
energyStoragePowerStation['postal_code'] = json[index]['postal_code'];
energyStoragePowerStation['latitude'] = json[index]['latitude'];
energyStoragePowerStation['longitude'] = json[index]['longitude'];
energyStoragePowerStation['serial_number'] = json[index]['serial_number'];
energyStoragePowerStation['files'] = [{ id: json[index]['uuid'], src: require('./EnergyStoragePowerStation.jpeg'), }];
energyStoragePowerStation['batteryState'] = json[index]['battery_state'];
energyStoragePowerStation['batterySocPointValue'] = json[index]['battery_soc_point_value'];
energyStoragePowerStation['batteryPowerPointValue'] = json[index]['battery_power_point_value'];
energyStoragePowerStation['photovoltaicPowerPointValue'] = json[index]['photovoltaic_power_point_value'];
energyStoragePowerStation['loadPowerPointValue'] = json[index]['load_power_point_value'];
energyStoragePowerStation['gridPowerPointValue'] = json[index]['grid_power_point_value'];
energyStoragePowerStation['PCSRunState'] = json[index]['pcs_run_state'];
energyStoragePowerStation['alarms'] = ['supply temperature is high', 'return temperature is low'];
energyStoragePowerStation['isOnline'] = json[index]['is_online'];
energyStoragePowerStationArray.push(energyStoragePowerStation);
energyStoragePowerStationIds.push(energyStoragePowerStation['id']);
geojsonData.push({
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [json[index]['longitude'], json[index]['latitude']]
},
'properties': {
'title': json[index]['name'],
'description': json[index]['description'],
'uuid': json[index]['uuid'],
'url': '/energystoragepowerstation/details'
}
})
});
}
setEnergyStoragePowerStationArray(energyStoragePowerStationArray);
setEnergyStoragePowerStationIds(energyStoragePowerStationIds);
console.log('energyStoragePowerStationArray:');
console.log(energyStoragePowerStationArray);
console.log('energyStoragePowerStationIds:');
console.log(energyStoragePowerStationIds);
setIsLoading(false);
setGeojson(geojsonData);
} else {
toast.error(t(json.description));
}
}).catch(err => {
console.log(err);
});
}, []);
const labelClasses = 'ls text-uppercase text-600 font-weight-semi-bold mb-0';
const sliderSettings = {
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
// Hook
const { data: paginationData, meta: paginationMeta, handler: paginationHandler } = usePagination(energyStoragePowerStationIds);
const { total, itemsPerPage, from, to } = paginationMeta;
const { perPage } = paginationHandler;
const isList = true;
const isGrid = false;
return (
<Fragment>
<Card>
<CardBody className={classNames({ 'p-0 overflow-hidden': isList, 'pb-0': isGrid })}>
<Row>
<Col xs={8}>
{isLoading ? (
<Loader />
) : (
<Row noGutters={isList}>
{isIterableArray(energyStoragePowerStationArray) &&
energyStoragePowerStationArray
.filter(energyStoragePowerStation => paginationData.includes(energyStoragePowerStation.id))
.map((energyStoragePowerStation, index) => <EnergyStoragePowerStationList {...energyStoragePowerStation} sliderSettings={sliderSettings} key={energyStoragePowerStation.id} index={index} />)}
</Row>
)}
</Col>
<Col>
<CustomizeMapBox Latitude={rootLatitude} Longitude={rootLongitude} Zoom={10} Geojson={geojson}></CustomizeMapBox>
</Col>
</Row>
</CardBody>
<EnergyStoragePowerStationFooter meta={paginationMeta} handler={paginationHandler} />
</Card>
<Card className="mb-3">
<CardBody>
<Row className="justify-content-between align-items-center">
<Col sm="auto" className="mb-2 mb-sm-0" tag={Flex} align="center">
<h6 className="mb-0 text-nowrap ml-2">
{t('Show Up to')}
</h6>
<CustomInput
id="itemsPerPage"
type="select"
bsSize="sm"
value={itemsPerPage}
onChange={({ target }) => perPage(Number(target.value))}
>
<option value={5}>5</option>
<option value={10}>10</option>
<option value={20}>20</option>
<option value={total}>{t('All')}</option>
</CustomInput>
<h6 className="mb-0 text-nowrap ml-2">
{t('FROM - TO of TOTAL', { 'FROM': from, 'TO': to, 'TOTAL': total })}
</h6>
</Col>
</Row>
</CardBody>
</Card>
</Fragment>
);
};
export default withTranslation()(withRedirect(EnergyStoragePowerStation));
......@@ -109,7 +109,7 @@ const EnergyStoragePowerStationDetails = ({ setRedirect, setRedirectUrl, t }) =>
useEffect(() => {
let isResponseOK = false;
fetch(APIBaseURL + '/reports/energystoragepowerstation?energystoragepowerstationuuid=' + energyStoragePowerStationUUID, {
fetch(APIBaseURL + '/reports/energystoragepowerstationdetails?uuid=' + energyStoragePowerStationUUID, {
method: 'GET',
headers: {
"Content-type": "application/json",
......@@ -126,13 +126,13 @@ const EnergyStoragePowerStationDetails = ({ setRedirect, setRedirectUrl, t }) =>
}).then(json => {
if (isResponseOK) {
console.log(json);
setEnergyStoragePowerStationName(json['energystoragepowerstation']['name']);
setEnergyStoragePowerStationAddress(json['energystoragepowerstation']['address']);
setEnergyStoragePowerStationPostalCode(json['energystoragepowerstation']['postal_code']);
setEnergyStoragePowerStationCapacity(json['energystoragepowerstation']['capacity']);
setEnergyStoragePowerStationLatitude(json['energystoragepowerstation']['latitude']);
setEnergyStoragePowerStationLongitude(json['energystoragepowerstation']['longitude']);
setEnergyStoragePowerStationSVG({__html: json['energystoragepowerstation']['svg']});
setEnergyStoragePowerStationName(json['energy_storage_power_station']['name']);
setEnergyStoragePowerStationAddress(json['energy_storage_power_station']['address']);
setEnergyStoragePowerStationPostalCode(json['energy_storage_power_station']['postal_code']);
setEnergyStoragePowerStationCapacity(json['energy_storage_power_station']['capacity']);
setEnergyStoragePowerStationLatitude(json['energy_storage_power_station']['latitude']);
setEnergyStoragePowerStationLongitude(json['energy_storage_power_station']['longitude']);
setEnergyStoragePowerStationSVG({__html: json['energy_storage_power_station']['svg']});
let timestamps = {}
json['parameters']['timestamps'].forEach((currentValue, index) => {
timestamps['a' + index] = currentValue;
......
import React, { useContext, useState } from 'react';
import PropTypes from 'prop-types';
import { Badge, Col, Row } from 'reactstrap';
import { Link } from 'react-router-dom';
import React, { Fragment, useState, useEffect } from 'react';
import {
Breadcrumb,
BreadcrumbItem,
Button,
ButtonGroup,
Card,
CardBody,
Col,
CustomInput,
Row,
Form,
FormGroup,
Input,
Label,
Spinner,
} from 'reactstrap';
import Loader from '../../common/Loader';
import { isIterableArray } from '../../../helpers/utils';
import Slider from 'react-slick/lib';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Flex from '../../common/Flex';
import classNames from 'classnames';
import ButtonIcon from '../../common/ButtonIcon';
import AppContext, { ProductContext } from '../../../context/Context';
import EnergyStoragePowerStationListItem from './EnergyStoragePowerStationListItem';
import EnergyStoragePowerStationFooter from './EnergyStoragePowerStationFooter';
import usePagination from '../../../hooks/usePagination';
import { getCookieValue, createCookie, checkEmpty } from '../../../helpers/utils';
import withRedirect from '../../../hoc/withRedirect';
import { withTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { APIBaseURL, settings } from '../../../config';
import CustomizeMapBox from '../common/CustomizeMapBox';
const EnergyStoragePowerStationList = ({
id,
uuid,
files,
name,
address,
postal_code,
serial_number,
batteryState,
batterySocPointValue,
batteryPowerPointValue,
photovoltaicPowerPointValue,
loadPowerPointValue,
gridPowerPointValue,
alarms,
isOnline,
PCSRunState,
index,
t
}) => {
const { isDark } = useContext(AppContext);
const { favouriteItemsDispatch } = useContext(ProductContext);
const [cartLoading, setCartLoading] = useState(false);
const handleAddToCart = () => {
setCartLoading(true);
setTimeout(() => {
setCartLoading(false);
const EnergyStoragePowerStationList = ({ setRedirect, setRedirectUrl, t }) => {
useEffect(() => {
let is_logged_in = getCookieValue('is_logged_in');
let user_name = getCookieValue('user_name');
let user_display_name = getCookieValue('user_display_name');
let user_uuid = getCookieValue('user_uuid');
let token = getCookieValue('token');
if (checkEmpty(is_logged_in) || checkEmpty(token)|| checkEmpty(user_uuid) || !is_logged_in) {
setRedirectUrl(`/authentication/basic/login`);
setRedirect(true);
} else {
//update expires time of cookies
createCookie('is_logged_in', true, settings.cookieExpireTime);
createCookie('user_name', user_name, settings.cookieExpireTime);
createCookie('user_display_name', user_display_name, settings.cookieExpireTime);
createCookie('user_uuid', user_uuid, settings.cookieExpireTime);
createCookie('token', token, settings.cookieExpireTime);
}
});
useEffect(() => {
let timer = setInterval(() => {
let is_logged_in = getCookieValue('is_logged_in');
if (is_logged_in === null || !is_logged_in) {
setRedirectUrl(`/authentication/basic/login`);
setRedirect(true);
}
}, 1000);
return () => clearInterval(timer);
}, []);
// State
const [energyStoragePowerStationArray, setEnergyStoragePowerStationArray] = useState([]);
const [energyStoragePowerStationIds, setEnergyStoragePowerStationIds] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [geojson, setGeojson] = useState([]);
const [rootLatitude, setRootLatitude] = useState('');
const [rootLongitude, setRootLongitude] = useState('');
useEffect(() => {
let isResponseOK = false;
fetch(APIBaseURL + '/reports/energystoragepowerstationlist', {
method: 'GET',
headers: {
"Content-type": "application/json",
"User-UUID": getCookieValue('user_uuid'),
"Token": getCookieValue('token')
},
body: null,
}).then(response => {
console.log(response);
if (response.ok) {
isResponseOK = true;
}
return response.json();
}).then(json => {
console.log(json);
if (isResponseOK) {
console.log(json);
setEnergyStoragePowerStationArray([]);
setEnergyStoragePowerStationIds([]);
let energyStoragePowerStationArray = [];
let energyStoragePowerStationIds = [];
let geojsonData = [];
if (json.length > 0) {
setRootLongitude(json[0]['longitude']);
setRootLatitude(json[0]['latitude']);
json.forEach((currentValue, index) => {
let energyStoragePowerStation = {}
energyStoragePowerStation['id'] = json[index]['id'];
energyStoragePowerStation['name'] = json[index]['name'];
energyStoragePowerStation['uuid'] = json[index]['uuid'];
energyStoragePowerStation['address'] = json[index]['address'];
energyStoragePowerStation['postal_code'] = json[index]['postal_code'];
energyStoragePowerStation['latitude'] = json[index]['latitude'];
energyStoragePowerStation['longitude'] = json[index]['longitude'];
energyStoragePowerStation['serial_number'] = json[index]['serial_number'];
energyStoragePowerStation['files'] = [{ id: json[index]['uuid'], src: require('./EnergyStoragePowerStation.jpeg'), }];
energyStoragePowerStation['batteryState'] = json[index]['battery_state'];
energyStoragePowerStation['batterySocPointValue'] = json[index]['battery_soc_point_value'];
energyStoragePowerStation['batteryPowerPointValue'] = json[index]['battery_power_point_value'];
energyStoragePowerStation['photovoltaicPowerPointValue'] = json[index]['photovoltaic_power_point_value'];
energyStoragePowerStation['loadPowerPointValue'] = json[index]['load_power_point_value'];
energyStoragePowerStation['gridPowerPointValue'] = json[index]['grid_power_point_value'];
energyStoragePowerStation['PCSRunState'] = json[index]['pcs_run_state'];
energyStoragePowerStation['alarms'] = ['supply temperature is high', 'return temperature is low'];
energyStoragePowerStation['isOnline'] = json[index]['is_online'];
energyStoragePowerStationArray.push(energyStoragePowerStation);
energyStoragePowerStationIds.push(energyStoragePowerStation['id']);
geojsonData.push({
'type': 'Feature',
'geometry': {
'type': 'Point',
'coordinates': [json[index]['longitude'], json[index]['latitude']]
},
'properties': {
'title': json[index]['name'],
'description': json[index]['description'],
'uuid': json[index]['uuid'],
'url': '/energystoragepowerstation/details'
}
})
});
}
setEnergyStoragePowerStationArray(energyStoragePowerStationArray);
setEnergyStoragePowerStationIds(energyStoragePowerStationIds);
console.log('energyStoragePowerStationArray:');
console.log(energyStoragePowerStationArray);
console.log('energyStoragePowerStationIds:');
console.log(energyStoragePowerStationIds);
setIsLoading(false);
setGeojson(geojsonData);
} else {
toast.error(t(json.description));
}
}).catch(err => {
console.log(err);
});
}, []);
const labelClasses = 'ls text-uppercase text-600 font-weight-semi-bold mb-0';
const sliderSettings = {
infinite: true,
speed: 500,
slidesToShow: 1,
slidesToScroll: 1
};
// Hook
const { data: paginationData, meta: paginationMeta, handler: paginationHandler } = usePagination(energyStoragePowerStationIds);
const { total, itemsPerPage, from, to } = paginationMeta;
const { perPage } = paginationHandler;
const isList = true;
const isGrid = false;
return (
<Col xs={12} className={classNames('p-3', { 'bg-100': isDark && index % 2 !== 0 })}>
<div className="p-1">
<Row>
<Col sm={5} md={4}>
<div className="position-relative h-sm-100">
<Link className="d-block h-100" to={`/energystoragepowerstation/details?uuid=${uuid}`} target = "_blank">
<img
className="img-fluid fit-cover w-sm-100 h-sm-100 rounded absolute-sm-centered"
src={files[0]['src']}
/>
</Link>
{isOnline && (
<Badge color="success" pill className="position-absolute t-0 r-0 mr-2 mt-2 fs--2 z-index-2">
{PCSRunState === 'Running' ? t('PCS Running') : PCSRunState === 'Initializing' ? t('PCS Initializing') : PCSRunState === 'Standby' ? t('PCS Standby') : PCSRunState === 'Shutdown' ? t('PCS Shutdown') : PCSRunState === 'Fault' ? t('PCS Fault') : t('PCS Unknown')}
</Badge>
<Fragment>
<Card>
<CardBody className={classNames({ 'p-0 overflow-hidden': isList, 'pb-0': isGrid })}>
<Row>
<Col xs={8}>
{isLoading ? (
<Loader />
) : (
<Row noGutters={isList}>
{isIterableArray(energyStoragePowerStationArray) &&
energyStoragePowerStationArray
.filter(energyStoragePowerStation => paginationData.includes(energyStoragePowerStation.id))
.map((energyStoragePowerStation, index) => <EnergyStoragePowerStationListItem {...energyStoragePowerStation} sliderSettings={sliderSettings} key={energyStoragePowerStation.id} index={index} />)}
</Row>
)}
</div>
</Col>
<Col sm={7} md={8}>
<Row>
<Col lg={7}>
<h5 className="mt-3 mt-sm-0">
<Link to={`/energystoragepowerstation/details?uuid=${uuid}`} target = "_blank">{name}</Link>
</h5>
<p className="fs--1 mb-2 mb-md-3">
{address}
</p>
<p className="fs--1 mb-2 mb-md-3">
{postal_code}
</p>
<p className="fs--1 mb-2 mb-md-3">
{serial_number}
</p>
<div className="d-none d-lg-block">
<p className="fs--1 mb-1">{t('Battery Power')}:<strong>{batteryPowerPointValue} kW</strong></p>
<p className="fs--1 mb-1">{t('Photovoltaic Power')}:<strong>{photovoltaicPowerPointValue} kW</strong></p>
<p className="fs--1 mb-1">{t('Load Power')}:<strong>{loadPowerPointValue} kW</strong></p>
<p className="fs--1 mb-1">{t('Grid Power')}:<strong>{gridPowerPointValue} kW</strong></p>
</div>
</Col>
<Col lg={5} tag={Flex} justify="between" column>
<div>
<h4 className="fs-1 fs-md-2 text-warning mb-0">
SoC: {batterySocPointValue} %
</h4>
<p className="fs--1 mb-1">
{t('Communication Status')}:{' '}
<strong className={classNames({ 'text-success': isOnline, 'text-danger': !isOnline })}>
{isOnline ? t('Communication Online') : t('Communication Offline')}
</strong>
</p>
<p className="fs--1 mb-1">
{t('Battery State')}:{' '}
<strong className={classNames({ 'text-success': batteryState === 'Charging' || batteryState === 'Discharging',
'text-danger': batteryState === 'Unknown' || batteryState === 'Stopped'})}>
{batteryState === 'Charging' ? t('Battery Charging') : batteryState === 'Discharging' ? t('Battery Discharging') : batteryState === 'Stopped' ? t('Battery Stopped'): t('Battery Unknown')}
</strong>
</p>
<p className="fs--1 mb-1">
{t('PCS Run State')}:{' '}
<strong className={classNames({ 'text-success': PCSRunState === 'Running',
'text-danger': PCSRunState === 'Unknown' || PCSRunState === 'Initializing' || PCSRunState === 'Standby' || PCSRunState === 'Shutdown' || PCSRunState === 'Fault'})}>
{PCSRunState === 'Running' ? t('PCS Running') : PCSRunState === 'Initializing' ? t('PCS Initializing') : PCSRunState === 'Standby' ? t('PCS Standby') : PCSRunState === 'Shutdown' ? t('PCS Shutdown') : PCSRunState === 'Fault' ? t('PCS Fault') : t('PCS Unknown')}
</strong>
</p>
</div>
<div className="mt-md-2">
<ButtonIcon
color="primary"
size="sm"
icon="tv"
iconClassName="ml-2 d-none d-md-inline-block"
className="w-lg-100 mt-2"
onClick={() => window.open(`energystoragepowerstation/details?uuid=${uuid}`, '_blank')}
>
{t('Monitoring')}
</ButtonIcon>
<ButtonIcon
color="primary"
size="sm"
icon="chart-pie"
iconClassName="ml-2 d-none d-md-inline-block"
className="w-lg-100 mt-2"
onClick={() => window.open(`energystoragepowerstation/reporting?uuid=${uuid}`, '_blank')}
>
{t('Reporting')}
</ButtonIcon>
<ButtonIcon
color={isOnline ? 'outline-danger' : 'outline-secondary'}
size="sm"
className={classNames('w-lg-100 mt-2 mr-2 mr-lg-0', {
'border-300': !isOnline
})}
icon={[isOnline ? 'fas' : 'far', 'exclamation-triangle']}
onClick={() => window.open('notification', '_blank')}
>
{t('Fault Alarms')}({alarms.length})
</ButtonIcon>
<ButtonIcon
color="primary"
size="sm"
icon="tools"
iconClassName="ml-2 d-none d-md-inline-block"
className="w-lg-100 mt-2"
onClick={handleAddToCart}
>
{t('Maintenance')}
</ButtonIcon>
</div>
</Col>
</Col>
<Col>
<CustomizeMapBox Latitude={rootLatitude} Longitude={rootLongitude} Zoom={10} Geojson={geojson}></CustomizeMapBox>
</Col>
</Row>
</Col>
</Row>
</div>
</Col>
);
};
</CardBody>
<EnergyStoragePowerStationFooter meta={paginationMeta} handler={paginationHandler} />
</Card>
<Card className="mb-3">
<CardBody>
<Row className="justify-content-between align-items-center">
<Col sm="auto" className="mb-2 mb-sm-0" tag={Flex} align="center">
<h6 className="mb-0 text-nowrap ml-2">
{t('Show Up to')}
</h6>
<CustomInput
id="itemsPerPage"
type="select"
bsSize="sm"
value={itemsPerPage}
onChange={({ target }) => perPage(Number(target.value))}
>
<option value={5}>5</option>
<option value={10}>10</option>
<option value={20}>20</option>
<option value={total}>{t('All')}</option>
</CustomInput>
<h6 className="mb-0 text-nowrap ml-2">
{t('FROM - TO of TOTAL', { 'FROM': from, 'TO': to, 'TOTAL': total })}
</h6>
</Col>
EnergyStoragePowerStationList.propTypes = {
name: PropTypes.string.isRequired,
files: PropTypes.array,
address: PropTypes.string,
postal_code: PropTypes.string,
serial_number: PropTypes.string,
batteryState: PropTypes.string,
batterySocPointValue: PropTypes.number,
batteryPowerPointValue: PropTypes.number,
photovoltaicPowerPointValue: PropTypes.number,
loadPowerPointValue: PropTypes.number,
gridPowerPointValue: PropTypes.number,
alarms: PropTypes.array,
isOnline: PropTypes.bool,
PCSRunState: PropTypes.string
</Row>
</CardBody>
</Card>
</Fragment>
);
};
EnergyStoragePowerStationList.defaultProps = { isOnline: false, files: [] };
export default withTranslation()(EnergyStoragePowerStationList);
export default withTranslation()(withRedirect(EnergyStoragePowerStationList));
import React, { useContext, useState } from 'react';
import PropTypes from 'prop-types';
import { Badge, Col, Row } from 'reactstrap';
import { Link } from 'react-router-dom';
import { isIterableArray } from '../../../helpers/utils';
import Slider from 'react-slick/lib';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import Flex from '../../common/Flex';
import classNames from 'classnames';
import ButtonIcon from '../../common/ButtonIcon';
import AppContext, { ProductContext } from '../../../context/Context';
import { withTranslation } from 'react-i18next';
const EnergyStoragePowerStationListItem = ({
id,
uuid,
files,
name,
address,
postal_code,
serial_number,
batteryState,
batterySocPointValue,
batteryPowerPointValue,
photovoltaicPowerPointValue,
loadPowerPointValue,
gridPowerPointValue,
alarms,
isOnline,
PCSRunState,
index,
t
}) => {
const { isDark } = useContext(AppContext);
const { favouriteItemsDispatch } = useContext(ProductContext);
const [cartLoading, setCartLoading] = useState(false);
const handleAddToCart = () => {
setCartLoading(true);
setTimeout(() => {
setCartLoading(false);
}, 1000);
};
return (
<Col xs={12} className={classNames('p-3', { 'bg-100': isDark && index % 2 !== 0 })}>
<div className="p-1">
<Row>
<Col sm={5} md={4}>
<div className="position-relative h-sm-100">
<Link className="d-block h-100" to={`/energystoragepowerstation/details?uuid=${uuid}`} target = "_blank">
<img
className="img-fluid fit-cover w-sm-100 h-sm-100 rounded absolute-sm-centered"
src={files[0]['src']}
/>
</Link>
{isOnline && (
<Badge color="success" pill className="position-absolute t-0 r-0 mr-2 mt-2 fs--2 z-index-2">
{PCSRunState === 'Running' ? t('PCS Running') : PCSRunState === 'Initializing' ? t('PCS Initializing') : PCSRunState === 'Standby' ? t('PCS Standby') : PCSRunState === 'Shutdown' ? t('PCS Shutdown') : PCSRunState === 'Fault' ? t('PCS Fault') : t('PCS Unknown')}
</Badge>
)}
</div>
</Col>
<Col sm={7} md={8}>
<Row>
<Col lg={7}>
<h5 className="mt-3 mt-sm-0">
<Link to={`/energystoragepowerstation/details?uuid=${uuid}`} target = "_blank">{name}</Link>
</h5>
<p className="fs--1 mb-2 mb-md-3">
{address}
</p>
<p className="fs--1 mb-2 mb-md-3">
{postal_code}
</p>
<p className="fs--1 mb-2 mb-md-3">
{serial_number}
</p>
<div className="d-none d-lg-block">
<p className="fs--1 mb-1">{t('Battery Power')}:<strong>{batteryPowerPointValue} kW</strong></p>
<p className="fs--1 mb-1">{t('Photovoltaic Power')}:<strong>{photovoltaicPowerPointValue} kW</strong></p>
<p className="fs--1 mb-1">{t('Load Power')}:<strong>{loadPowerPointValue} kW</strong></p>
<p className="fs--1 mb-1">{t('Grid Power')}:<strong>{gridPowerPointValue} kW</strong></p>
</div>
</Col>
<Col lg={5} tag={Flex} justify="between" column>
<div>
<h4 className="fs-1 fs-md-2 text-warning mb-0">
SoC: {batterySocPointValue} %
</h4>
<p className="fs--1 mb-1">
{t('Communication Status')}:{' '}
<strong className={classNames({ 'text-success': isOnline, 'text-danger': !isOnline })}>
{isOnline ? t('Communication Online') : t('Communication Offline')}
</strong>
</p>
<p className="fs--1 mb-1">
{t('Battery State')}:{' '}
<strong className={classNames({ 'text-success': batteryState === 'Charging' || batteryState === 'Discharging',
'text-danger': batteryState === 'Unknown' || batteryState === 'Stopped'})}>
{batteryState === 'Charging' ? t('Battery Charging') : batteryState === 'Discharging' ? t('Battery Discharging') : batteryState === 'Stopped' ? t('Battery Stopped'): t('Battery Unknown')}
</strong>
</p>
<p className="fs--1 mb-1">
{t('PCS Run State')}:{' '}
<strong className={classNames({ 'text-success': PCSRunState === 'Running',
'text-danger': PCSRunState === 'Unknown' || PCSRunState === 'Initializing' || PCSRunState === 'Standby' || PCSRunState === 'Shutdown' || PCSRunState === 'Fault'})}>
{PCSRunState === 'Running' ? t('PCS Running') : PCSRunState === 'Initializing' ? t('PCS Initializing') : PCSRunState === 'Standby' ? t('PCS Standby') : PCSRunState === 'Shutdown' ? t('PCS Shutdown') : PCSRunState === 'Fault' ? t('PCS Fault') : t('PCS Unknown')}
</strong>
</p>
</div>
<div className="mt-md-2">
<ButtonIcon
color="primary"
size="sm"
icon="tv"
iconClassName="ml-2 d-none d-md-inline-block"
className="w-lg-100 mt-2"
onClick={() => window.open(`energystoragepowerstation/details?uuid=${uuid}`, '_blank')}
>
{t('Monitoring')}
</ButtonIcon>
<ButtonIcon
color="primary"
size="sm"
icon="chart-pie"
iconClassName="ml-2 d-none d-md-inline-block"
className="w-lg-100 mt-2"
onClick={() => window.open(`energystoragepowerstation/reporting?uuid=${uuid}`, '_blank')}
>
{t('Reporting')}
</ButtonIcon>
<ButtonIcon
color={isOnline ? 'outline-danger' : 'outline-secondary'}
size="sm"
className={classNames('w-lg-100 mt-2 mr-2 mr-lg-0', {
'border-300': !isOnline
})}
icon={[isOnline ? 'fas' : 'far', 'exclamation-triangle']}
onClick={() => window.open('notification', '_blank')}
>
{t('Fault Alarms')}({alarms.length})
</ButtonIcon>
<ButtonIcon
color="primary"
size="sm"
icon="tools"
iconClassName="ml-2 d-none d-md-inline-block"
className="w-lg-100 mt-2"
onClick={handleAddToCart}
>
{t('Maintenance')}
</ButtonIcon>
</div>
</Col>
</Row>
</Col>
</Row>
</div>
</Col>
);
};
EnergyStoragePowerStationListItem.propTypes = {
name: PropTypes.string.isRequired,
files: PropTypes.array,
address: PropTypes.string,
postal_code: PropTypes.string,
serial_number: PropTypes.string,
batteryState: PropTypes.string,
batterySocPointValue: PropTypes.number,
batteryPowerPointValue: PropTypes.number,
photovoltaicPowerPointValue: PropTypes.number,
loadPowerPointValue: PropTypes.number,
gridPowerPointValue: PropTypes.number,
alarms: PropTypes.array,
isOnline: PropTypes.bool,
PCSRunState: PropTypes.string
};
EnergyStoragePowerStationListItem.defaultProps = { isOnline: false, files: [] };
export default withTranslation()(EnergyStoragePowerStationListItem);
......@@ -85,7 +85,7 @@ const EnergyStoragePowerStationReporting = ({ setRedirect, setRedirectUrl, t })
useEffect(() => {
let isResponseOK = false;
fetch(APIBaseURL + '/reports/energystoragepowerstation?energystoragepowerstationuuid=' + energyStoragePowerStationUUID, {
fetch(APIBaseURL + '/reports/energystoragepowerstationreporting?uuid=' + energyStoragePowerStationUUID, {
method: 'GET',
headers: {
"Content-type": "application/json",
......
......@@ -197,7 +197,7 @@ import Microgrid from '../components/MyEMS/Microgrid/Microgrid';
import MicrogridDetails from '../components/MyEMS/Microgrid/MicrogridDetails';
import MicrogridReporting from '../components/MyEMS/Microgrid/MicrogridReporting';
// Energy Storage Power Statioin
import EnergyStoragePowerStation from '../components/MyEMS/EnergyStoragePowerStation/EnergyStoragePowerStation';
import EnergyStoragePowerStationList from '../components/MyEMS/EnergyStoragePowerStation/EnergyStoragePowerStationList';
import EnergyStoragePowerStationDetails from '../components/MyEMS/EnergyStoragePowerStation/EnergyStoragePowerStationDetails';
import EnergyStoragePowerStationReporting from '../components/MyEMS/EnergyStoragePowerStation/EnergyStoragePowerStationReporting';
// FDD
......@@ -459,7 +459,7 @@ const MyEMSRoutes = () => (
<Route path="/microgrid/reporting" exact component={MicrogridReporting} />
{/*EnergyStoragePowerStation*/}
<Route path="/energystoragepowerstation" exact component={EnergyStoragePowerStation} />
<Route path="/energystoragepowerstation" exact component={EnergyStoragePowerStationList} />
<Route path="/energystoragepowerstation/details" exact component={EnergyStoragePowerStationDetails} />
<Route path="/energystoragepowerstation/reporting" exact component={EnergyStoragePowerStationReporting} />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册