Merge branch 'develop' of https://gitee.com/hyh123_a/myems into develop

pull/64/head
hyh123a 2021-09-07 15:18:34 +08:00
commit 74ee2a9eba
15 changed files with 109 additions and 78 deletions

View File

@ -834,6 +834,7 @@ function config($translateProvider) {
INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name', INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name',
INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID', INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID',
INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID', INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID',
KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK: 'Knowledge File Cannot be Removed from Disk',
KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found', KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found',
MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category', MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category',
MASTER_METER_NOT_FOUND: 'Master Meter Not Found', MASTER_METER_NOT_FOUND: 'Master Meter Not Found',
@ -1821,6 +1822,7 @@ function config($translateProvider) {
INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name', INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name',
INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID', INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID',
INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID', INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID',
KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK: 'Knowledge File Cannot be Removed from Disk',
KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found', KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found',
MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category', MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category',
MASTER_METER_NOT_FOUND: 'Master Meter Not Found', MASTER_METER_NOT_FOUND: 'Master Meter Not Found',
@ -2807,6 +2809,7 @@ function config($translateProvider) {
INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name', INVALID_VIRTUAL_METER_NAME: 'Invalid Virtual Meter Name',
INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID', INVALID_WEB_MESSAGE_ID: 'Invalid Web Message ID',
INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID', INVALID_WECHAT_MESSAGE_ID: 'Invalid Wechat Message ID',
KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK: 'Knowledge File Cannot be Removed from Disk',
KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found', KNOWLEDGE_FILE_NOT_FOUND: 'Knowledge File Not Found',
MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category', MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY: 'Master Meter Does Not Belong To Same Energy Category',
MASTER_METER_NOT_FOUND: 'Master Meter Not Found', MASTER_METER_NOT_FOUND: 'Master Meter Not Found',

View File

@ -7,6 +7,22 @@ DROP DATABASE IF EXISTS `myems_fdd_db` ;
CREATE DATABASE IF NOT EXISTS `myems_fdd_db` ; CREATE DATABASE IF NOT EXISTS `myems_fdd_db` ;
USE `myems_fdd_db` ; USE `myems_fdd_db` ;
-- ---------------------------------------------------------------------------------------------------------------------
-- Table `myems_fdd_db`.`tbl_aliyun_sms_api`
-- refer to https://dysms.console.aliyun.com/
-- API Version 2017-05-25
-- ---------------------------------------------------------------------------------------------------------------------
DROP TABLE IF EXISTS `myems_fdd_db`.`tbl_aliyun_sms_api` ;
CREATE TABLE IF NOT EXISTS `myems_fdd_db`.`tbl_aliyun_sms_api` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`access_key_id` VARCHAR(256) NOT NULL,
`access_key_secret` VARCHAR(256) NOT NULL,
`endpoint` VARCHAR(256) NOT NULL,
`sign_name` VARCHAR(256) NOT NULL,
`template_code` VARCHAR(256) NOT NULL,
PRIMARY KEY (`id`));
-- --------------------------------------------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------------------------------------------------
-- Table `myems_fdd_db`.`tbl_email_messages` -- Table `myems_fdd_db`.`tbl_email_messages`
-- --------------------------------------------------------------------------------------------------------------------- -- ---------------------------------------------------------------------------------------------------------------------

View File

@ -1243,6 +1243,6 @@ USE `myems_system_db`;
INSERT INTO `myems_system_db`.`tbl_versions` INSERT INTO `myems_system_db`.`tbl_versions`
(`id`, `version`, `release_date`) (`id`, `version`, `release_date`)
VALUES VALUES
(1, '1.2.3', '2021-09-04'); (1, '1.2.4', '2021-09-11');
COMMIT; COMMIT;

View File

@ -0,0 +1,18 @@
-- ---------------------------------------------------------------------------------------------------------------------
-- Table `myems_fdd_db`.`tbl_aliyun_sms_api`
-- refer to https://dysms.console.aliyun.com/
-- API Version 2017-05-25
-- ---------------------------------------------------------------------------------------------------------------------
CREATE TABLE IF NOT EXISTS `myems_fdd_db`.`tbl_aliyun_sms_api` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`access_key_id` VARCHAR(256) NOT NULL,
`access_key_secret` VARCHAR(256) NOT NULL,
`endpoint` VARCHAR(256) NOT NULL,
`sign_name` VARCHAR(256) NOT NULL,
`template_code` VARCHAR(256) NOT NULL,
PRIMARY KEY (`id`));
DROP TABLE IF EXISTS `myems_fdd_db`.`tbl_gsm_modems` ;
-- UPDATE VERSION NUMBER
UPDATE myems_system_db.tbl_versions SET version='1.2.4', release_date='2021-09-11' WHERE id=1;

View File

@ -117,9 +117,7 @@ git clone https://github.com/MyEMS/myems.git
cd ~/myems/myems-api cd ~/myems/myems-api
sudo cp -R ~/myems/myems-api /myems-api sudo cp -R ~/myems/myems-api /myems-api
``` ```
Change the config file: Change IP address in the config file:
Note: change cookie domain to the actual domain or IP address of Web UI and Admin UI
```bash ```bash
sudo nano /myems-api/config.py sudo nano /myems-api/config.py
``` ```
@ -283,9 +281,9 @@ curl -i -X GET {{base_url}}/costfiles
curl -i -X DELETE {{base_url}}/costfiles/{id} curl -i -X DELETE {{base_url}}/costfiles/{id}
``` ```
* POST Upload a Cost File * POST Upload a Cost File
(user must login first to get cookie) (call users login API to get 'User-UUID' and 'Token')
```bash ```bash
curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/costfiles curl -i -H "User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4" -H "Token: 02f93023a39c98e1d1bc9f5197a83dfc5ddc0d48" -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/costfiles
``` ```
* GET Restore a Cost File by ID from database to disk * GET Restore a Cost File by ID from database to disk
```bash ```bash
@ -944,9 +942,9 @@ curl -i -X GET {{base_url}}/knowledgefiles
curl -i -X DELETE {{base_url}}/knowledgefiles/{id} curl -i -X DELETE {{base_url}}/knowledgefiles/{id}
``` ```
* POST Upload a Knowledge File * POST Upload a Knowledge File
(user must login first to get cookie) (call users login API to get 'User-UUID' and 'Token')
```bash ```bash
curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/knowledgefiles curl -i -H "User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4" -H "Token: 02f93023a39c98e1d1bc9f5197a83dfc5ddc0d48" -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/knowledgefiles
``` ```
* GET Restore a Knowledge File by id from database to disk * GET Restore a Knowledge File by id from database to disk
```bash ```bash
@ -1140,9 +1138,9 @@ curl -i -X GET {{base_url}}/offlinemeterfiles
curl -i -X DELETE {{base_url}}/offlinemeterfiles/{id} curl -i -X DELETE {{base_url}}/offlinemeterfiles/{id}
``` ```
* POST Upload an Offline Meter File * POST Upload an Offline Meter File
(user must log in first to get cookie) (call users login API to get 'User-UUID' and 'Token')
```bash ```bash
curl -i -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/offlinemeterfiles curl -i -H "User-UUID: dcdb67d1-6116-4987-916f-6fc6cf2bc0e4" -H "Token: 02f93023a39c98e1d1bc9f5197a83dfc5ddc0d48" -H "Content-Type: application/TBD" -X POST -d 'file: (binary)' {{base_url}}/offlinemeterfiles
``` ```
* GET Restore an Offline Meter File by ID from database to disk * GET Restore an Offline Meter File by ID from database to disk
```bash ```bash

View File

@ -61,10 +61,6 @@ myems_reporting_db = {
'database': 'myems_reporting_db', 'database': 'myems_reporting_db',
} }
# address for Cookie domain
# use the actual domain or IP address of Web UI and Admin UI
myems_api_domain = '127.0.0.1'
# indicated in how many minutes to calculate meter energy consumption # indicated in how many minutes to calculate meter energy consumption
# 30 for half hourly period # 30 for half hourly period
# 60 for hourly period # 60 for hourly period

View File

@ -257,12 +257,11 @@ class KnowledgeFileItem:
file_uuid = row[0] file_uuid = row[0]
# Define file_path # Define file_path
file_path = os.path.join(config.upload_path, file_uuid) file_path = os.path.join(config.upload_path, file_uuid)
# remove the file from disk # remove the file from disk
os.remove(file_path) os.remove(file_path)
except Exception as ex: except Exception as ex:
raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR', raise falcon.HTTPError(falcon.HTTP_400, title='API.ERROR',
description='API.KNOWLEDGE_FILE_NOT_FOUND') description='API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK')
cursor.execute(" DELETE FROM tbl_knowledge_files WHERE id = %s ", (id_,)) cursor.execute(" DELETE FROM tbl_knowledge_files WHERE id = %s ", (id_,))
cnx.commit() cnx.commit()

View File

@ -447,10 +447,6 @@ class UserLogin:
cnx.commit() cnx.commit()
cursor.close() cursor.close()
cnx.disconnect() cnx.disconnect()
resp.set_cookie('user_uuid', user_uuid,
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
resp.set_cookie('token', token,
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
del result['salt'] del result['salt']
del result['password'] del result['password']
result['token'] = token result['token'] = token
@ -502,11 +498,6 @@ class UserLogout:
if rowcount is None or rowcount == 0: if rowcount is None or rowcount == 0:
raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND', raise falcon.HTTPError(falcon.HTTP_404, title='API.NOT_FOUND',
description='API.USER_SESSION_NOT_FOUND') description='API.USER_SESSION_NOT_FOUND')
resp.set_cookie('user_uuid', '',
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
resp.set_cookie('token', '',
domain=config.myems_api_domain, path='/', secure=False, http_only=False)
resp.body = json.dumps("OK") resp.body = json.dumps("OK")
resp.status = falcon.HTTP_200 resp.status = falcon.HTTP_200

View File

@ -54,12 +54,12 @@ def user_logger(func):
func(*args, **kwargs) func(*args, **kwargs)
return return
req, resp = args req, resp = args
cookies = req.cookies headers = req.headers
if cookies is not None and 'user_uuid' in cookies.keys(): if headers is not None and 'USER-UUID' in headers.keys():
user_uuid = cookies['user_uuid'] user_uuid = headers['USER-UUID']
else: else:
# todo: deal with requests with NULL user_uuid # todo: deal with requests with NULL user_uuid
print('user_logger: user_uuid is NULL') print('user_logger: USER-UUID is NULL')
# do not log for NULL user_uuid # do not log for NULL user_uuid
func(*args, **kwargs) func(*args, **kwargs)
return return

View File

@ -33,7 +33,6 @@ class Reporting:
#################################################################################################################### ####################################################################################################################
@staticmethod @staticmethod
def on_get(req, resp): def on_get(req, resp):
print(req.params)
user_uuid = req.params.get('useruuid') user_uuid = req.params.get('useruuid')
period_type = req.params.get('periodtype') period_type = req.params.get('periodtype')
base_start_datetime_local = req.params.get('baseperiodstartdatetime') base_start_datetime_local = req.params.get('baseperiodstartdatetime')

88
web/README.md vendored
View File

@ -1,67 +1,63 @@
# MyEMS Web # MyEMS Web
## Introduction ## Introduction
MyEMS Web 用户界面,用于能源数据分析 MyEMS Web 用户界面,用于查询能源报表
Providing Web UI for MyEMS users to analysis energy data Providing Web UI of MyEMS for viewing energy reports
## Prerequisites ## Prerequisites
Node.js Node.js
nginx-1.18.0 or later ## Running in Local Environment for Development
## Running in Local environment
This project is scaffolded using Create React App.
* Install Node.js via binary archive on Linux * Install Node.js via binary archive on Linux
Download Current Linux Binaries (x64) from https://nodejs.org/en/download/current/ Download Current Linux Binaries (x64) from https://nodejs.org/en/download/current/
Unzip the binary archive to /usr/local/bin/nodejs,
```bash ```bash
sudo mkdir -p /usr/local/lib/nodejs sudo mkdir -p /usr/local/lib/nodejs
sudo tar -xJvf node-v1x.x.x-linux-x64.tar.xz -C /usr/local/lib/nodejs sudo tar -xJvf node-vxx.x.x-linux-x64.tar.xz -C /usr/local/lib/nodejs
sudo ln -s /usr/local/lib/nodejs/node-vxx.x.x-linux-x64/bin/node /usr/bin/node
sudo ln -s /usr/local/lib/nodejs/node-vxx.x.x-linux-x64/bin/npm /usr/bin/npm
sudo ln -s /usr/local/lib/nodejs/node-vxx.x.x-linux-x64/bin/npx /usr/bin/npx
``` ```
Using sudo to symlink node, npm, and npx into /usr/bin/: Test installation
```bash
sudo ln -s /usr/local/lib/nodejs/node-v1x.x.x-linux-x64/bin/node /usr/bin/node
```
```bash
sudo ln -s /usr/local/lib/nodejs/node-v1x.x.x-linux-x64/bin/npm /usr/bin/npm
```
```bash
sudo ln -s /usr/local/lib/nodejs/node-v1x.x.x-linux-x64/bin/npx /usr/bin/npx
```
Test installation using
```bash ```bash
node -v node -v
```
```bash
npm version npm version
```
```bash
npx -v npx -v
``` ```
* Open the “myems/web” directory with your cmd or terminal * Download all the necessary dependencies into the node_modules directory.
* Run 'sudo npm i --unsafe-perm=true --allow-root' ```bash
cd myems/web
This command will download all the necessary dependencies for falcon in the node_modules directory. sudo npm i --unsafe-perm=true --allow-root
* If you modified any scss files, then you need to compile SCSS ```
Run 'sudo npm run scss' command in your project directory to compile scss. * If you modified any scss files then you need to compile SCSS, else you can safely ignore this step.
* Run 'sudo npm start' Run below command in your project directory to compile scss.
```bash
sudo npm run scss
```
* Starting the Development Server
A local web server will start at http://localhost:3000. A local web server will start at http://localhost:3000.
We are using webpack and webpack-serve to automatically detect file changes. So, if you edit and save a file, your browser will automatically refresh and preview the change. We are using webpack and webpack-serve to automatically detect file changes. So, if you edit and save a file, your browser will automatically refresh and preview the change.
```
sudo npm start
```
## Creating a Production Build ## Install Production Build Option 1: on Node.js Web Server
* Run 'sudo npm run build' command in your project directory to make the Production build. * Run below command in your project directory to make the Production build.
This will create an optimized production build by compililing, merging and minifying all the source files as necessary and put them in the build/ folder. This will create an optimized production build by compililing, merging and minifying all the source files as necessary and put them in the build/ folder.
```bash
sudo npm run build
```
* Run the production build locally at http://localhost:80.
If you want to listen on other port, change it in myems/web/server.js
```
sudo node server.js
```
You can run 'node server.js' to run the production build locally at http://localhost:5000. ## Install Production Build Option 2: on NGINX Server (Highly Recommended)
## Option 1: Install Production Build on NGINX Server
* Install NGINX Server * Install NGINX Server
refer to http://nginx.org/en/docs/install.html refer to http://nginx.org/en/docs/install.html
* Configure NGINX * Configure NGINX
@ -107,16 +103,16 @@ Restart NGINX
sudo systemctl restart nginx sudo systemctl restart nginx
``` ```
* Download myems: * Download MyEMS:
```bash ```bash
cd ~ cd ~
git clone https://github.com/MyEMS/myems.git git clone https://github.com/MyEMS/myems.git
``` ```
* Install myems-web : * Install MyEMS Web UI:
Check and change the config file if necessary: Check and change the config file if necessary:
```bash ```bash
cd ~/myems/web cd myems/web
sudo nano src/config.js sudo nano src/config.js
``` ```
Build and Compress Build and Compress
@ -133,7 +129,7 @@ sudo rm -r /var/www/html/web
sudo mv build /var/www/html/web sudo mv build /var/www/html/web
``` ```
## Option 2: Install Production Build on Apache2 Server ## Install Production Build Option 3: on Apache2 Server
* Install Apache2 Server * Install Apache2 Server
refer to https://httpd.apache.org/docs/2.4/install.html refer to https://httpd.apache.org/docs/2.4/install.html
@ -165,21 +161,21 @@ Add a new 'VirtualHost' as below
</VirtualHost> </VirtualHost>
``` ```
* Download myems: * Download MyEMS:
```bash ```bash
cd ~ cd ~
git clone https://github.com/MyEMS/myems.git git clone https://github.com/MyEMS/myems.git
``` ```
* Install myems-web : * Install MyEMS Web UI:
Check and change the config file if necessary: Check and change the config file if necessary:
```bash ```bash
cd ~/myems/web cd myems/web
sudo nano src/config.js sudo nano src/config.js
``` ```
Build and Compress Build and Compress
```bash ```bash
cd ~/myems/web/ cd myems/web/
sudo npm run build sudo npm run build
tar czvf myems-web.tar.gz build tar czvf myems-web.tar.gz build
``` ```
@ -190,4 +186,4 @@ tar czvf myems-web.tar.gz build
tar xzf myems-web.tar.gz tar xzf myems-web.tar.gz
sudo rm -r /var/www/web sudo rm -r /var/www/web
sudo mv build /var/www/web sudo mv build /var/www/web
``` ```

11
web/package-lock.json generated vendored
View File

@ -30,6 +30,7 @@
"echarts-for-react": "^2.0.16", "echarts-for-react": "^2.0.16",
"element-resize-event": "^3.0.3", "element-resize-event": "^3.0.3",
"emoji-mart": "^3.0.0", "emoji-mart": "^3.0.0",
"express-rate-limit": "^5.3.0",
"fuse.js": "^6.4.3", "fuse.js": "^6.4.3",
"google-maps-react": "^2.0.6", "google-maps-react": "^2.0.6",
"i18next": "^19.6.3", "i18next": "^19.6.3",
@ -8599,6 +8600,11 @@
"node": ">= 0.10.0" "node": ">= 0.10.0"
} }
}, },
"node_modules/express-rate-limit": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz",
"integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew=="
},
"node_modules/express/node_modules/array-flatten": { "node_modules/express/node_modules/array-flatten": {
"version": "1.1.1", "version": "1.1.1",
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=" "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
@ -28780,6 +28786,11 @@
} }
} }
}, },
"express-rate-limit": {
"version": "5.3.0",
"resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.3.0.tgz",
"integrity": "sha512-qJhfEgCnmteSeZAeuOKQ2WEIFTX5ajrzE0xS6gCOBCoRQcU+xEzQmgYQQTpzCcqUAAzTEtu4YEih4pnLfvNtew=="
},
"ext": { "ext": {
"version": "1.4.0", "version": "1.4.0",
"integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==",

1
web/package.json vendored
View File

@ -25,6 +25,7 @@
"echarts-for-react": "^2.0.16", "echarts-for-react": "^2.0.16",
"element-resize-event": "^3.0.3", "element-resize-event": "^3.0.3",
"emoji-mart": "^3.0.0", "emoji-mart": "^3.0.0",
"express-rate-limit": "^5.3.0",
"fuse.js": "^6.4.3", "fuse.js": "^6.4.3",
"google-maps-react": "^2.0.6", "google-maps-react": "^2.0.6",
"i18next": "^19.6.3", "i18next": "^19.6.3",

4
web/server.js vendored
View File

@ -21,6 +21,6 @@ app.use(limiter);
app.get('*', function(req, res) { app.get('*', function(req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html')); res.sendFile(path.join(__dirname, 'build', 'index.html'));
}); });
app.listen(process.env.PORT || 5000, function() { app.listen(process.env.PORT || 80, function() {
console.log(`Frontend start on http://localhost:5000`); console.log(`Frontend start on http://localhost:80`);
}); });

View File

@ -597,6 +597,7 @@ const resources = {
"API.INVALID_VIRTUAL_METER_NAME": "Invalid virtual meter name", "API.INVALID_VIRTUAL_METER_NAME": "Invalid virtual meter name",
"API.INVALID_WEB_MESSAGE_ID": "Invalid web message id", "API.INVALID_WEB_MESSAGE_ID": "Invalid web message id",
"API.INVALID_WECHAT_MESSAGE_ID": "Invalid wechat message id", "API.INVALID_WECHAT_MESSAGE_ID": "Invalid wechat message id",
"API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK": "Knowledge File Cannot be Removed from Disk",
"API.KNOWLEDGE_FILE_NOT_FOUND": "Knowledge file not found", "API.KNOWLEDGE_FILE_NOT_FOUND": "Knowledge file not found",
"API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "Master meter does not belong to same energy category", "API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "Master meter does not belong to same energy category",
"API.MASTER_METER_NOT_FOUND": "Master meter not found", "API.MASTER_METER_NOT_FOUND": "Master meter not found",
@ -1346,6 +1347,7 @@ const resources = {
"API.INVALID_VIRTUAL_METER_NAME": "", "API.INVALID_VIRTUAL_METER_NAME": "",
"API.INVALID_WEB_MESSAGE_ID": "", "API.INVALID_WEB_MESSAGE_ID": "",
"API.INVALID_WECHAT_MESSAGE_ID": "", "API.INVALID_WECHAT_MESSAGE_ID": "",
"API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK": "",
"API.KNOWLEDGE_FILE_NOT_FOUND": "", "API.KNOWLEDGE_FILE_NOT_FOUND": "",
"API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "", "API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "",
"API.MASTER_METER_NOT_FOUND": "", "API.MASTER_METER_NOT_FOUND": "",
@ -2095,6 +2097,7 @@ const resources = {
"API.INVALID_VIRTUAL_METER_NAME": "", "API.INVALID_VIRTUAL_METER_NAME": "",
"API.INVALID_WEB_MESSAGE_ID": "", "API.INVALID_WEB_MESSAGE_ID": "",
"API.INVALID_WECHAT_MESSAGE_ID": "", "API.INVALID_WECHAT_MESSAGE_ID": "",
"API.KNOWLEDGE_FILE_CANNOT_BE_REMOVED_FROM_DISK": "",
"API.KNOWLEDGE_FILE_NOT_FOUND": "", "API.KNOWLEDGE_FILE_NOT_FOUND": "",
"API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "", "API.MASTER_METER_DOES_NOT_BELONG_TO_SAME_ENERGY_CATEGORY": "",
"API.MASTER_METER_NOT_FOUND": "", "API.MASTER_METER_NOT_FOUND": "",