Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
MyEMS
MyEMS能源管理系统
提交
309465e9
M
MyEMS能源管理系统
项目概览
MyEMS
/
MyEMS能源管理系统
通知
46
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
M
MyEMS能源管理系统
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
309465e9
编写于
3月 31, 2023
作者:
nengyuangzhang
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'develop'
上级
88ba7406
fc312ec7
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
725 addition
and
4 deletion
+725
-4
database/install/myems_system_db.sql
database/install/myems_system_db.sql
+2
-1
database/upgrade/upgrade3.2.0.sql
database/upgrade/upgrade3.2.0.sql
+6
-1
myems-api/app.py
myems-api/app.py
+3
-0
myems-api/reports/spaceenvironmentmonitor.py
myems-api/reports/spaceenvironmentmonitor.py
+224
-0
myems-web/src/components/MyEMS/Space/RealtimeData.js
myems-web/src/components/MyEMS/Space/RealtimeData.js
+179
-0
myems-web/src/components/MyEMS/Space/SpaceEnvironmentMonitor.js
...web/src/components/MyEMS/Space/SpaceEnvironmentMonitor.js
+303
-0
myems-web/src/i18n.js
myems-web/src/i18n.js
+3
-0
myems-web/src/layouts/MyEMSRoutes.js
myems-web/src/layouts/MyEMSRoutes.js
+3
-1
myems-web/src/routes.js
myems-web/src/routes.js
+2
-1
未找到文件。
database/install/myems_system_db.sql
浏览文件 @
309465e9
...
...
@@ -431,6 +431,7 @@ VALUES
(
108
,
'Statistics'
,
'/space/statistics'
,
100
,
0
),
(
109
,
'Saving'
,
'/space/saving'
,
100
,
0
),
(
110
,
'Carbon'
,
'/space/carbon'
,
100
,
0
),
(
111
,
'Environment Monitor'
,
'/space/environmentmonitor'
,
100
,
0
),
(
200
,
'Equipment Data'
,
'/equipment'
,
NULL
,
0
),
(
201
,
'Energy Category Data'
,
'/equipment/energycategory'
,
200
,
0
),
(
202
,
'Energy Item Data'
,
'/equipment/energyitem'
,
200
,
0
),
...
...
@@ -1327,7 +1328,7 @@ USE `myems_system_db`;
INSERT
INTO
`myems_system_db`
.
`tbl_versions`
(
`id`
,
`version`
,
`release_date`
)
VALUES
(
1
,
'3.2.0
RC'
,
'2023-03-10
'
);
(
1
,
'3.2.0
'
,
'2023-03-31
'
);
COMMIT
;
...
...
database/upgrade/upgrade3.2.0
RC
.sql
→
database/upgrade/upgrade3.2.0.sql
浏览文件 @
309465e9
...
...
@@ -7,6 +7,11 @@
DROP
TABLE
IF
EXISTS
`myems_production_db`
.
`tbl_shopfloor_working_days`
;
-- ADD MENUS
INSERT
INTO
myems_system_db
.
tbl_menus
(
id
,
name
,
route
,
parent_menu_id
,
is_hidden
)
VALUES
(
111
,
'Environment Monitor'
,
'/space/environmentmonitor'
,
100
,
0
);
-- UPDATE VERSION NUMBER
UPDATE
`myems_system_db`
.
`tbl_versions`
SET
version
=
'3.2.0
RC'
,
release_date
=
'2023-03-10
'
WHERE
id
=
1
;
UPDATE
`myems_system_db`
.
`tbl_versions`
SET
version
=
'3.2.0
'
,
release_date
=
'2023-03-31
'
WHERE
id
=
1
;
myems-api/app.py
浏览文件 @
309465e9
...
...
@@ -63,6 +63,7 @@ from reports import spacecost
from
reports
import
spaceefficiency
from
reports
import
spaceenergycategory
from
reports
import
spaceenergyitem
from
reports
import
spaceenvironmentmonitor
from
reports
import
spaceincome
from
reports
import
spaceload
from
reports
import
spaceoutput
...
...
@@ -673,6 +674,8 @@ api.add_route('/reports/storeenergycategory',
storeenergycategory
.
Reporting
())
api
.
add_route
(
'/reports/storeenergyitem'
,
storeenergyitem
.
Reporting
())
api
.
add_route
(
'/reports/spaceenvironmentmonitor'
,
spaceenvironmentmonitor
.
Reporting
())
api
.
add_route
(
'/reports/storeload'
,
storeload
.
Reporting
())
api
.
add_route
(
'/reports/storesaving'
,
...
...
myems-api/reports/spaceenvironmentmonitor.py
0 → 100644
浏览文件 @
309465e9
import
re
from
datetime
import
datetime
,
timedelta
,
timezone
import
falcon
import
mysql.connector
import
simplejson
as
json
import
config
class
Reporting
:
@
staticmethod
def
__init__
():
""""Initializes Reporting"""
pass
@
staticmethod
def
on_options
(
req
,
resp
):
resp
.
status
=
falcon
.
HTTP_200
####################################################################################################################
# PROCEDURES
# Step 1: valid parameters
# Step 2: query the sensor
# Step 3: query associated points
# Step 4: query associated points data
# Step 5: construct the report
####################################################################################################################
@
staticmethod
def
on_get
(
req
,
resp
):
print
(
req
.
params
)
sensor_id
=
req
.
params
.
get
(
'sensorid'
)
sensor_uuid
=
req
.
params
.
get
(
'sensoruuid'
)
quick_mode
=
req
.
params
.
get
(
'quickmode'
)
################################################################################################################
# Step 1: valid parameters
################################################################################################################
if
sensor_id
is
None
and
sensor_uuid
is
None
:
raise
falcon
.
HTTPError
(
falcon
.
HTTP_400
,
title
=
'API.BAD_REQUEST'
,
description
=
'API.INVALID_SENSOR_ID'
)
if
sensor_id
is
not
None
:
sensor_id
=
str
.
strip
(
sensor_id
)
if
not
sensor_id
.
isdigit
()
or
int
(
sensor_id
)
<=
0
:
raise
falcon
.
HTTPError
(
falcon
.
HTTP_400
,
title
=
'API.BAD_REQUEST'
,
description
=
'API.INVALID_SENSOR_UUID'
)
is_quick_mode
=
False
if
quick_mode
is
not
None
and
\
len
(
str
.
strip
(
quick_mode
))
>
0
and
\
str
.
lower
(
str
.
strip
(
quick_mode
))
in
(
'true'
,
't'
,
'on'
,
'yes'
,
'y'
):
is_quick_mode
=
True
timezone_offset
=
int
(
config
.
utc_offset
[
1
:
3
])
*
60
+
int
(
config
.
utc_offset
[
4
:
6
])
if
config
.
utc_offset
[
0
]
==
'-'
:
timezone_offset
=
-
timezone_offset
reporting_end_datetime_utc
=
datetime
.
utcnow
()
reporting_start_datetime_utc
=
reporting_end_datetime_utc
-
timedelta
(
minutes
=
60
)
################################################################################################################
# Step 2: query the sensor
################################################################################################################
cnx_system
=
mysql
.
connector
.
connect
(
**
config
.
myems_system_db
)
cursor_system
=
cnx_system
.
cursor
()
cnx_historical
=
mysql
.
connector
.
connect
(
**
config
.
myems_historical_db
)
cursor_historical
=
cnx_historical
.
cursor
()
if
sensor_id
is
not
None
:
cursor_system
.
execute
(
" SELECT id, name, uuid, description "
" FROM tbl_sensors "
" WHERE id = %s "
,
(
sensor_id
,))
row_sensor
=
cursor_system
.
fetchone
()
elif
sensor_uuid
is
not
None
:
cursor_system
.
execute
(
" SELECT id, name, uuid, description "
" FROM tbl_sensors "
" WHERE uuid = %s "
,
(
sensor_uuid
,))
row_sensor
=
cursor_system
.
fetchone
()
if
row_sensor
is
None
:
if
cursor_system
:
cursor_system
.
close
()
if
cnx_system
:
cnx_system
.
close
()
if
cursor_historical
:
cursor_historical
.
close
()
if
cnx_historical
:
cnx_historical
.
close
()
raise
falcon
.
HTTPError
(
falcon
.
HTTP_404
,
title
=
'API.NOT_FOUND'
,
description
=
'API.SENSOR_NOT_FOUND'
)
sensor
=
dict
()
sensor
[
'id'
]
=
row_sensor
[
0
]
sensor
[
'name'
]
=
row_sensor
[
1
]
sensor
[
'uuid'
]
=
row_sensor
[
2
]
sensor
[
'description'
]
=
row_sensor
[
3
]
################################################################################################################
# Step 3: query associated points
################################################################################################################
point_list
=
list
()
cursor_system
.
execute
(
" SELECT p.id, p.name, p.units, p.object_type "
" FROM tbl_sensors s, tbl_sensors_points sp, tbl_points p "
" WHERE s.id = %s AND s.id = sp.sensor_id AND p.id = sp.point_id "
" ORDER BY p.id "
,
(
sensor
[
'id'
],))
rows_points
=
cursor_system
.
fetchall
()
if
rows_points
is
not
None
and
len
(
rows_points
)
>
0
:
for
row
in
rows_points
:
point_list
.
append
({
"id"
:
row
[
0
],
"name"
:
row
[
1
],
"units"
:
row
[
2
],
"object_type"
:
row
[
3
]})
################################################################################################################
# Step 4: query associated points data
################################################################################################################
energy_value_data
=
dict
()
energy_value_data
[
'name'
]
=
None
energy_value_data
[
'timestamps'
]
=
list
()
energy_value_data
[
'values'
]
=
list
()
parameters_data
=
dict
()
parameters_data
[
'names'
]
=
list
()
parameters_data
[
'timestamps'
]
=
list
()
parameters_data
[
'values'
]
=
list
()
if
not
is_quick_mode
:
for
point
in
point_list
:
point_values
=
[]
point_timestamps
=
[]
if
point
[
'object_type'
]
==
'ENERGY_VALUE'
:
energy_value_data
[
'name'
]
=
point
[
'name'
]
+
' ('
+
point
[
'units'
]
+
')'
query
=
(
" SELECT utc_date_time, actual_value "
" FROM tbl_energy_value "
" WHERE point_id = %s "
" AND utc_date_time BETWEEN %s AND %s "
" ORDER BY utc_date_time "
)
cursor_historical
.
execute
(
query
,
(
point
[
'id'
],
reporting_start_datetime_utc
,
reporting_end_datetime_utc
))
rows
=
cursor_historical
.
fetchall
()
if
rows
is
not
None
and
len
(
rows
)
>
0
:
for
row
in
rows
:
current_datetime_local
=
row
[
0
].
replace
(
tzinfo
=
timezone
.
utc
)
+
\
timedelta
(
minutes
=
timezone_offset
)
current_datetime
=
current_datetime_local
.
strftime
(
'%Y-%m-%dT%H:%M:%S'
)
energy_value_data
[
'timestamps'
].
append
(
current_datetime
)
energy_value_data
[
'values'
].
append
(
row
[
1
])
elif
point
[
'object_type'
]
==
'ANALOG_VALUE'
:
query
=
(
" SELECT utc_date_time, actual_value "
" FROM tbl_analog_value "
" WHERE point_id = %s "
" AND utc_date_time BETWEEN %s AND %s "
" ORDER BY utc_date_time "
)
cursor_historical
.
execute
(
query
,
(
point
[
'id'
],
reporting_start_datetime_utc
,
reporting_end_datetime_utc
))
rows
=
cursor_historical
.
fetchall
()
if
rows
is
not
None
and
len
(
rows
)
>
0
:
for
row
in
rows
:
current_datetime_local
=
row
[
0
].
replace
(
tzinfo
=
timezone
.
utc
)
+
\
timedelta
(
minutes
=
timezone_offset
)
current_datetime
=
current_datetime_local
.
strftime
(
'%Y-%m-%dT%H:%M:%S'
)
point_timestamps
.
append
(
current_datetime
)
point_values
.
append
(
row
[
1
])
parameters_data
[
'names'
].
append
(
point
[
'name'
]
+
' ('
+
point
[
'units'
]
+
')'
)
parameters_data
[
'timestamps'
].
append
(
point_timestamps
)
parameters_data
[
'values'
].
append
(
point_values
)
elif
point
[
'object_type'
]
==
'DIGITAL_VALUE'
:
query
=
(
" SELECT utc_date_time, actual_value "
" FROM tbl_digital_value "
" WHERE point_id = %s "
" AND utc_date_time BETWEEN %s AND %s "
" ORDER BY utc_date_time "
)
cursor_historical
.
execute
(
query
,
(
point
[
'id'
],
reporting_start_datetime_utc
,
reporting_end_datetime_utc
))
rows
=
cursor_historical
.
fetchall
()
if
rows
is
not
None
and
len
(
rows
)
>
0
:
for
row
in
rows
:
current_datetime_local
=
row
[
0
].
replace
(
tzinfo
=
timezone
.
utc
)
+
\
timedelta
(
minutes
=
timezone_offset
)
current_datetime
=
current_datetime_local
.
strftime
(
'%Y-%m-%dT%H:%M:%S'
)
point_timestamps
.
append
(
current_datetime
)
point_values
.
append
(
row
[
1
])
parameters_data
[
'names'
].
append
(
point
[
'name'
]
+
' ('
+
point
[
'units'
]
+
')'
)
parameters_data
[
'timestamps'
].
append
(
point_timestamps
)
parameters_data
[
'values'
].
append
(
point_values
)
################################################################################################################
# Step 5: construct the report
################################################################################################################
if
cursor_system
:
cursor_system
.
close
()
if
cnx_system
:
cnx_system
.
close
()
if
cursor_historical
:
cursor_historical
.
close
()
if
cnx_historical
:
cnx_historical
.
close
()
result
=
{
"sensor"
:
{
"sensor_id"
:
sensor
[
'id'
],
"name"
:
sensor
[
'name'
],
"uuid"
:
sensor
[
'uuid'
],
"description"
:
sensor
[
'description'
],
},
"energy_value"
:
energy_value_data
,
"parameters"
:
{
"names"
:
parameters_data
[
'names'
],
"timestamps"
:
parameters_data
[
'timestamps'
],
"values"
:
parameters_data
[
'values'
]
},
}
resp
.
text
=
json
.
dumps
(
result
)
myems-web/src/components/MyEMS/Space/RealtimeData.js
0 → 100644
浏览文件 @
309465e9
import
React
,
{
Component
}
from
'
react
'
;
import
{
Card
,
CardHeader
,
CardBody
,
ListGroup
,
ListGroupItem
}
from
'
reactstrap
'
;
import
{
withTranslation
}
from
'
react-i18next
'
;
import
{
v4
as
uuid
}
from
'
uuid
'
;
import
{
APIBaseURL
}
from
'
../../../config
'
;
import
{
getCookieValue
}
from
'
../../../helpers/utils
'
;
import
{
toast
}
from
'
react-toastify
'
;
const
dividerBorder
=
'
1px solid rgba(255, 255, 255, 0.15)
'
;
const
listItemBorderColor
=
'
rgba(255, 255, 255, 0.05)
'
;
class
RealtimeData
extends
Component
{
_isMounted
=
false
;
refreshInterval
;
refreshTimeout
;
state
=
{
trendLog
:
[],
currentEnergyValue
:
undefined
,
energyValuePointName
:
undefined
,
pointList
:
[],
};
componentWillUnmount
()
{
this
.
_isMounted
=
false
;
clearInterval
(
this
.
refreshInterval
);
clearTimeout
(
this
.
refreshTimeout
);
}
componentDidMount
()
{
this
.
_isMounted
=
true
;
const
{
t
}
=
this
.
props
;
// fetch meter realtime data at the first time
let
isResponseOK
=
false
;
fetch
(
APIBaseURL
+
'
/reports/spaceenvironmentmonitor?sensorid=
'
+
this
.
props
.
sensorId
,
{
method
:
'
GET
'
,
headers
:
{
"
Content-type
"
:
"
application/json
"
,
"
User-UUID
"
:
getCookieValue
(
'
user_uuid
'
),
"
Token
"
:
getCookieValue
(
'
token
'
)
},
body
:
null
,
}).
then
(
response
=>
{
if
(
response
.
ok
)
{
isResponseOK
=
true
;
}
return
response
.
json
();
}).
then
(
json
=>
{
if
(
isResponseOK
)
{
console
.
log
(
json
);
let
length
=
json
[
'
energy_value
'
][
'
values
'
].
length
;
let
trendLog
=
length
>
60
?
json
[
'
energy_value
'
][
'
values
'
].
slice
(
length
-
60
,
length
)
:
json
[
'
energy_value
'
][
'
values
'
];
let
currentEnergyValue
=
undefined
;
let
energyValuePointName
=
json
[
'
energy_value
'
][
'
name
'
];
let
pointList
=
[];
if
(
trendLog
.
length
>
0
)
{
currentEnergyValue
=
trendLog
[
trendLog
.
length
-
1
];
}
json
[
'
parameters
'
][
'
names
'
].
forEach
((
currentName
,
index
)
=>
{
let
pointItem
=
{}
pointItem
[
'
name
'
]
=
currentName
;
pointItem
[
'
value
'
]
=
undefined
;
let
currentValues
=
json
[
'
parameters
'
][
'
values
'
][
index
];
if
(
currentValues
.
length
>
0
)
{
pointItem
[
'
value
'
]
=
currentValues
[
currentValues
.
length
-
1
];
}
pointList
.
push
(
pointItem
);
});
if
(
this
.
_isMounted
)
{
this
.
setState
({
trendLog
:
trendLog
,
currentEnergyValue
:
currentEnergyValue
,
energyValuePointName
:
energyValuePointName
,
pointList
:
pointList
,
});
}
}
else
{
toast
.
error
(
t
(
json
.
description
));
}
}).
catch
(
err
=>
{
console
.
log
(
err
);
});
//fetch meter realtime data at regular intervals
this
.
refreshInterval
=
setInterval
(()
=>
{
let
isResponseOK
=
false
;
fetch
(
APIBaseURL
+
'
/reports/spaceenvironmentmonitor?sensorid=
'
+
this
.
props
.
sensorId
,
{
method
:
'
GET
'
,
headers
:
{
"
Content-type
"
:
"
application/json
"
,
"
User-UUID
"
:
getCookieValue
(
'
user_uuid
'
),
"
Token
"
:
getCookieValue
(
'
token
'
)
},
body
:
null
,
}).
then
(
response
=>
{
if
(
response
.
ok
)
{
isResponseOK
=
true
;
}
return
response
.
json
();
}).
then
(
json
=>
{
if
(
isResponseOK
)
{
console
.
log
(
json
);
let
trendLog
=
json
[
'
energy_value
'
][
'
values
'
];
let
currentEnergyValue
=
undefined
;
let
energyValuePointName
=
json
[
'
energy_value
'
][
'
name
'
];
let
pointList
=
[];
if
(
trendLog
.
length
>
0
)
{
currentEnergyValue
=
trendLog
[
trendLog
.
length
-
1
];
}
json
[
'
parameters
'
][
'
names
'
].
forEach
((
currentName
,
index
)
=>
{
let
pointItem
=
{}
pointItem
[
'
name
'
]
=
currentName
;
pointItem
[
'
value
'
]
=
undefined
;
let
currentValues
=
json
[
'
parameters
'
][
'
values
'
][
index
];
if
(
currentValues
.
length
>
0
)
{
pointItem
[
'
value
'
]
=
currentValues
[
currentValues
.
length
-
1
];
}
pointList
.
push
(
pointItem
);
});
if
(
this
.
_isMounted
)
{
this
.
setState
({
trendLog
:
trendLog
,
currentEnergyValue
:
currentEnergyValue
,
energyValuePointName
:
energyValuePointName
,
pointList
:
pointList
,
});
}
}
else
{
toast
.
error
(
t
(
json
.
description
))
}
}).
catch
(
err
=>
{
console
.
log
(
err
);
});
},
(
60
+
Math
.
floor
(
Math
.
random
()
*
Math
.
floor
(
10
)))
*
1000
);
// use random interval to avoid paralels requests
}
render
()
{
const
{
t
}
=
this
.
props
;
return
(
<
Card
className
=
"
h-100 bg-gradient
"
>
<
CardHeader
className
=
"
bg-transparent
"
>
<
h5
className
=
"
text-white
"
>
{
this
.
props
.
sensorName
}
<
/h5
>
<
div
className
=
"
real-time-user display-4 font-weight-normal text-white
"
style
=
{{
display
:
!
this
.
state
.
currentEnergyValue
?
"
none
"
:
"
inline
"
}}
>
{
this
.
state
.
currentEnergyValue
}
<
/div
>
<
/CardHeader
>
<
CardBody
className
=
"
text-white fs--1
"
>
<
p
className
=
"
pb-2
"
style
=
{{
borderBottom
:
dividerBorder
,
display
:
!
this
.
state
.
energyValuePointName
?
"
none
"
:
"
inline
"
}}
>
{
t
(
'
Trend in the last hour of Energy Value Point
'
)}
{
this
.
state
.
energyValuePointName
}
<
/p
>
<
ListGroup
flush
className
=
"
mt-4
"
>
<
ListGroupItem
className
=
"
bg-transparent d-flex justify-content-between px-0 py-1 font-weight-semi-bold border-top-0
"
style
=
{{
borderColor
:
listItemBorderColor
}}
>
<
p
className
=
"
mb-0
"
>
{
t
(
'
Related Parameters
'
)}
<
/p
>
<
p
className
=
"
mb-0
"
>
{
t
(
'
Realtime Value
'
)}
<
/p
>
<
/ListGroupItem
>
{
this
.
state
.
pointList
.
map
(
pointItem
=>
(
<
ListGroupItem
key
=
{
uuid
()}
className
=
"
bg-transparent d-flex justify-content-between px-0 py-1
"
style
=
{{
borderColor
:
listItemBorderColor
}}
>
<
p
className
=
"
mb-0
"
>
{
pointItem
[
'
name
'
]}
<
/p
>
<
p
className
=
"
mb-0
"
>
{
pointItem
[
'
value
'
]}
<
/p
>
<
/ListGroupItem
>
))}
<
/ListGroup
>
<
/CardBody
>
<
/Card
>
);
}
}
export
default
withTranslation
()(
RealtimeData
);
myems-web/src/components/MyEMS/Space/SpaceEnvironmentMonitor.js
0 → 100644
浏览文件 @
309465e9
import
React
,
{
Fragment
,
useEffect
,
useState
}
from
'
react
'
;
import
{
Breadcrumb
,
BreadcrumbItem
,
Card
,
CardBody
,
Col
,
Form
,
FormGroup
,
Input
,
Label
,
Row
,
Spinner
,
Pagination
,
PaginationItem
,
PaginationLink
}
from
'
reactstrap
'
;
import
Cascader
from
'
rc-cascader
'
;
import
RealtimeData
from
'
./RealtimeData
'
;
import
{
getCookieValue
,
createCookie
}
from
'
../../../helpers/utils
'
;
import
withRedirect
from
'
../../../hoc/withRedirect
'
;
import
{
withTranslation
}
from
'
react-i18next
'
;
import
{
v4
as
uuid
}
from
'
uuid
'
;
import
{
toast
}
from
'
react-toastify
'
;
import
{
APIBaseURL
}
from
'
../../../config
'
;
const
SpaceEnvironmentMonitor
=
({
setRedirect
,
setRedirectUrl
,
t
})
=>
{
const
[
cursor
,
setCursor
]
=
useState
(
0
);
const
[
maxCursor
,
setMaxCursor
]
=
useState
(
0
);
const
[
selectSensorList
,
setSelectSensorList
]
=
useState
([]);
const
len
=
8
;
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
(
is_logged_in
===
null
||
!
is_logged_in
)
{
setRedirectUrl
(
`/authentication/basic/login`
);
setRedirect
(
true
);
}
else
{
//update expires time of cookies
createCookie
(
'
is_logged_in
'
,
true
,
1000
*
60
*
10
*
1
);
createCookie
(
'
user_name
'
,
user_name
,
1000
*
60
*
10
*
1
);
createCookie
(
'
user_display_name
'
,
user_display_name
,
1000
*
60
*
10
*
1
);
createCookie
(
'
user_uuid
'
,
user_uuid
,
1000
*
60
*
10
*
1
);
createCookie
(
'
token
'
,
token
,
1000
*
60
*
10
*
1
);
}
});
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
[
selectedSpaceName
,
setSelectedSpaceName
]
=
useState
(
undefined
);
const
[
cascaderOptions
,
setCascaderOptions
]
=
useState
(
undefined
);
const
[
sensorList
,
setSensorList
]
=
useState
([]);
const
[
spinnerHidden
,
setSpinnerHidden
]
=
useState
(
false
);
useEffect
(()
=>
{
//begin of getting space tree
let
isResponseOK
=
false
;
fetch
(
APIBaseURL
+
'
/spaces/tree
'
,
{
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
)
{
// rename keys
json
=
JSON
.
parse
(
JSON
.
stringify
([
json
])
.
split
(
'
"id":
'
)
.
join
(
'
"value":
'
)
.
split
(
'
"name":
'
)
.
join
(
'
"label":
'
)
);
setCascaderOptions
(
json
);
// set the default space
setSelectedSpaceName
([
json
[
0
]].
map
(
o
=>
o
.
label
));
let
selectedSpaceID
=
[
json
[
0
]].
map
(
o
=>
o
.
value
);
//begin of getting sensors of the default space
let
isSecondResponseOK
=
false
;
fetch
(
APIBaseURL
+
'
/spaces/
'
+
selectedSpaceID
+
'
/sensors
'
,
{
method
:
'
GET
'
,
headers
:
{
'
Content-type
'
:
'
application/json
'
,
'
User-UUID
'
:
getCookieValue
(
'
user_uuid
'
),
Token
:
getCookieValue
(
'
token
'
)
},
body
:
null
})
.
then
(
response
=>
{
if
(
response
.
ok
)
{
isSecondResponseOK
=
true
;
}
return
response
.
json
();
})
.
then
(
json
=>
{
if
(
isSecondResponseOK
)
{
json
=
JSON
.
parse
(
JSON
.
stringify
([
json
]));
console
.
log
(
json
);
setSensorList
(
json
[
0
]);
setSpinnerHidden
(
true
);
}
else
{
toast
.
error
(
t
(
json
.
description
));
}
})
.
catch
(
err
=>
{
console
.
log
(
err
);
});
//end of getting sensors of the default space
}
else
{
toast
.
error
(
t
(
json
.
description
));
}
})
.
catch
(
err
=>
{
console
.
log
(
err
);
});
//end of getting space tree
},
[]);
const
labelClasses
=
'
ls text-uppercase text-600 font-weight-semi-bold mb-0
'
;
let
onSpaceCascaderChange
=
(
value
,
selectedOptions
)
=>
{
setSelectedSpaceName
(
selectedOptions
.
map
(
o
=>
o
.
label
).
join
(
'
/
'
));
let
selectedSpaceID
=
value
[
value
.
length
-
1
];
setSpinnerHidden
(
false
);
//begin of getting sensors of the selected space
let
isResponseOK
=
false
;
fetch
(
APIBaseURL
+
'
/spaces/
'
+
selectedSpaceID
+
'
/sensors
'
,
{
method
:
'
GET
'
,
headers
:
{
'
Content-type
'
:
'
application/json
'
,
'
User-UUID
'
:
getCookieValue
(
'
user_uuid
'
),
Token
:
getCookieValue
(
'
token
'
)
},
body
:
null
})
.
then
(
response
=>
{
if
(
response
.
ok
)
{
isResponseOK
=
true
;
}
return
response
.
json
();
})
.
then
(
json
=>
{
if
(
isResponseOK
)
{
json
=
JSON
.
parse
(
JSON
.
stringify
([
json
]));
console
.
log
(
json
);
setSensorList
(
json
[
0
]);
setSpinnerHidden
(
true
);
}
else
{
toast
.
error
(
t
(
json
.
description
));
}
})
.
catch
(
err
=>
{
console
.
log
(
err
);
});
//end of getting sensors of the selected space
};
useEffect
(()
=>
{
const
sensorLen
=
sensorList
.
length
;
const
maxCursor
=
Math
.
ceil
(
sensorLen
/
len
);
setCursor
(
1
);
setMaxCursor
(
maxCursor
);
document
.
getElementById
(
"
cursor_2
"
).
hidden
=
true
;
document
.
getElementById
(
"
cursor_3
"
).
hidden
=
true
;
document
.
getElementById
(
"
cursor_4
"
).
hidden
=
true
;
if
(
maxCursor
==
2
){
document
.
getElementById
(
"
cursor_2
"
).
hidden
=
false
;
}
if
(
maxCursor
==
3
){
document
.
getElementById
(
"
cursor_2
"
).
hidden
=
false
;
document
.
getElementById
(
"
cursor_3
"
).
hidden
=
false
;
}
if
(
maxCursor
>=
4
)
{
document
.
getElementById
(
"
cursor_2
"
).
hidden
=
false
;
document
.
getElementById
(
"
cursor_3
"
).
hidden
=
false
;
document
.
getElementById
(
"
cursor_4
"
).
hidden
=
false
;
}
},
[
sensorList
]);
useEffect
(()
=>
{
setSelectSensorList
(
sensorList
.
slice
(
cursor
*
len
-
8
,
cursor
*
len
));
},
[
cursor
,
sensorList
]);
function
getCursor
(
location
){
switch
(
location
){
case
1
:
return
cursor
>
maxCursor
-
3
&&
maxCursor
-
3
>=
0
?
maxCursor
-
3
:
cursor
;
case
2
:
return
cursor
>
maxCursor
-
3
&&
maxCursor
-
3
>=
0
?
maxCursor
-
2
:
cursor
+
1
;
case
3
:
return
cursor
>
maxCursor
-
3
&&
maxCursor
-
3
>=
0
?
maxCursor
-
1
:
cursor
+
2
;
case
4
:
return
cursor
>
maxCursor
-
3
&&
maxCursor
-
3
>=
0
?
maxCursor
:
cursor
+
3
;
}
}
return
(
<
Fragment
>
<
div
>
<
Breadcrumb
>
<
BreadcrumbItem
>
{
t
(
'
Space Data
'
)}
<
/BreadcrumbItem
>
<
BreadcrumbItem
active
>
{
t
(
'
Environment Monitor
'
)}
<
/BreadcrumbItem
>
<
/Breadcrumb
>
<
/div
>
<
Card
className
=
"
bg-light mb-3
"
>
<
CardBody
className
=
"
p-3
"
>
<
Form
>
<
Row
form
>
<
Col
xs
=
{
6
}
sm
=
{
3
}
>
<
FormGroup
className
=
"
form-group
"
>
<
Label
className
=
{
labelClasses
}
for
=
"
space
"
>
{
t
(
'
Space
'
)}
<
/Label
>
<
br
/>
<
Cascader
options
=
{
cascaderOptions
}
onChange
=
{
onSpaceCascaderChange
}
changeOnSelect
expandTrigger
=
"
hover
"
>
<
Input
value
=
{
selectedSpaceName
||
''
}
readOnly
/>
<
/Cascader
>
<
/FormGroup
>
<
/Col
>
<
Col
xs
=
"
auto
"
>
<
FormGroup
>
<
br
/>
<
Spinner
color
=
"
primary
"
hidden
=
{
spinnerHidden
}
/
>
<
/FormGroup
>
<
/Col
>
<
/Row
>
<
/Form
>
<
/CardBody
>
<
/Card
>
<
Row
noGutters
>
{
selectSensorList
.
map
(
sensor
=>
(
<
Col
lg
=
"
3
"
className
=
"
pr-lg-2
"
key
=
{
uuid
()}
>
<
RealtimeData
sensorId
=
{
sensor
[
'
id
'
]}
sensorName
=
{
sensor
[
'
name
'
]}
/
>
<
/Col
>
))}
<
/Row
>
<
Pagination
>
<
PaginationItem
>
<
PaginationLink
first
href
=
"
#
"
onClick
=
{()
=>
setCursor
(
1
)}
/
>
<
/PaginationItem
>
<
PaginationItem
>
<
PaginationLink
previous
href
=
"
#
"
onClick
=
{()
=>
(
cursor
-
1
>=
1
?
setCursor
(
cursor
-
1
)
:
null
)}
/
>
<
/PaginationItem
>
<
PaginationItem
>
<
PaginationLink
href
=
"
#
"
onClick
=
{()
=>
(
setCursor
(
getCursor
(
1
)))}
>
{
getCursor
(
1
)}
<
/PaginationLink
>
<
/PaginationItem
>
<
PaginationItem
id
=
"
cursor_2
"
>
<
PaginationLink
href
=
"
#
"
onClick
=
{()
=>
(
setCursor
(
getCursor
(
2
)))}
>
{
getCursor
(
2
)}
<
/PaginationLink
>
<
/PaginationItem
>
<
PaginationItem
id
=
"
cursor_3
"
>
<
PaginationLink
href
=
"
#
"
onClick
=
{()
=>
(
setCursor
(
getCursor
(
3
)))}
>
{
getCursor
(
3
)}
<
/PaginationLink
>
<
/PaginationItem
>
<
PaginationItem
id
=
"
cursor_4
"
>
<
PaginationLink
href
=
"
#
"
onClick
=
{()
=>
(
setCursor
(
getCursor
(
4
)))}
>
{
getCursor
(
4
)}
<
/PaginationLink
>
<
/PaginationItem
>
<
PaginationItem
>
<
PaginationLink
next
href
=
"
#
"
onClick
=
{()
=>
(
cursor
+
1
<=
maxCursor
?
setCursor
(
cursor
+
1
)
:
null
)}
/
>
<
/PaginationItem
>
<
PaginationItem
>
<
PaginationLink
last
href
=
"
#
"
onClick
=
{()
=>
setCursor
(
maxCursor
)}
/
>
<
/PaginationItem
>
<
/Pagination
>
<
/Fragment
>
);
};
export
default
withTranslation
()(
withRedirect
(
SpaceEnvironmentMonitor
));
\ No newline at end of file
myems-web/src/i18n.js
浏览文件 @
309465e9
...
...
@@ -32,6 +32,7 @@ const resources = {
'
Batch Analysis
'
:
'
Batch Analysis
'
,
'
Saving
'
:
'
Saving
'
,
'
Equipment Tracking
'
:
'
Equipment Tracking
'
,
'
Environment Monitor
'
:
'
Environment Monitor
'
,
'
Meter Energy
'
:
'
Meter Energy
'
,
'
Meter Carbon
'
:
'
Meter Carbon Dioxide Emissions
'
,
'
Meter Cost
'
:
'
Meter Cost
'
,
...
...
@@ -871,6 +872,7 @@ const resources = {
'
Batch Analysis
'
:
'
Charge Analyse
'
,
'
Saving
'
:
'
Sparen
'
,
'
Equipment Tracking
'
:
'
Ausrüstung Datei
'
,
'
Environment Monitor
'
:
'
Umgebungsmonitor
'
,
'
Meter Energy
'
:
'
Meter Energie
'
,
'
Meter Carbon
'
:
'
Meter Kohlendioxidemission
'
,
'
Meter Cost
'
:
'
Meter Kosten
'
,
...
...
@@ -1722,6 +1724,7 @@ const resources = {
'
Batch Analysis
'
:
'
批量分析
'
,
'
Saving
'
:
'
节能分析
'
,
'
Equipment Tracking
'
:
'
设备台账
'
,
'
Environment Monitor
'
:
'
环境监测
'
,
'
Meter Energy
'
:
'
计量表能耗分析
'
,
'
Meter Carbon
'
:
'
计量表碳排放分析
'
,
'
Meter Cost
'
:
'
计量表成本分析
'
,
...
...
myems-web/src/layouts/MyEMSRoutes.js
浏览文件 @
309465e9
...
...
@@ -113,6 +113,7 @@ import SpaceEfficiency from '../components/MyEMS/Space/SpaceEfficiency';
import
SpaceLoad
from
'
../components/MyEMS/Space/SpaceLoad
'
;
import
SpaceStatistics
from
'
../components/MyEMS/Space/SpaceStatistics
'
;
import
SpaceSaving
from
'
../components/MyEMS/Space/SpaceSaving
'
;
import
SpaceEnvironmentMonitor
from
'
../components/MyEMS/Space/SpaceEnvironmentMonitor
'
;
// Equipment
import
EquipmentBatch
from
'
../components/MyEMS/Equipment/EquipmentBatch
'
;
import
EquipmentCarbon
from
'
../components/MyEMS/Equipment/EquipmentCarbon
'
;
...
...
@@ -133,7 +134,7 @@ import MeterComparison from '../components/MyEMS/Meter/MeterComparison';
import
MeterCost
from
'
../components/MyEMS/Meter/MeterCost
'
;
import
MeterEnergy
from
'
../components/MyEMS/Meter/MeterEnergy
'
;
import
MeterRealtime
from
'
../components/MyEMS/Meter/MeterRealtime
'
;
import
MeterSaving
from
'
../components/MyEMS/Meter/MeterSaving
'
import
MeterSaving
from
'
../components/MyEMS/Meter/MeterSaving
'
;
import
MeterSubmetersBalance
from
'
../components/MyEMS/Meter/MeterSubmetersBalance
'
;
import
MeterTracking
from
'
../components/MyEMS/Meter/MeterTracking
'
;
import
MeterTrend
from
'
../components/MyEMS/Meter/MeterTrend
'
;
...
...
@@ -359,6 +360,7 @@ const MyEMSRoutes = () => (
<
Route
path
=
"
/space/load
"
exact
component
=
{
SpaceLoad
}
/
>
<
Route
path
=
"
/space/statistics
"
exact
component
=
{
SpaceStatistics
}
/
>
<
Route
path
=
"
/space/saving
"
exact
component
=
{
SpaceSaving
}
/
>
<
Route
path
=
"
/space/environmentmonitor
"
exact
component
=
{
SpaceEnvironmentMonitor
}
/
>
{
/*Equipment*/
}
<
Route
path
=
"
/equipment/batch
"
exact
component
=
{
EquipmentBatch
}
/
>
...
...
myems-web/src/routes.js
浏览文件 @
309465e9
...
...
@@ -330,7 +330,8 @@ export const spaceRoutes = {
{
to
:
'
/space/efficiency
'
,
name
:
'
Efficiency
'
},
{
to
:
'
/space/load
'
,
name
:
'
Load
'
},
{
to
:
'
/space/statistics
'
,
name
:
'
Statistics
'
},
{
to
:
'
/space/saving
'
,
name
:
'
Saving
'
}
{
to
:
'
/space/saving
'
,
name
:
'
Saving
'
},
{
to
:
'
/space/environmentmonitor
'
,
name
:
'
Environment Monitor
'
}
]
};
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录