Merge branch 'develop'
commit
a20932016d
|
@ -26,7 +26,7 @@ python-decouple
|
||||||
```bash
|
```bash
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
chmod +x run.sh
|
chmod +x run.sh
|
||||||
run.sh
|
./run.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
@ -55,8 +55,8 @@ python3 setup.py install
|
||||||
```bash
|
```bash
|
||||||
cd ~/tools
|
cd ~/tools
|
||||||
wget https://cdn.mysql.com/archives/mysql-connector-python-8.0/mysql-connector-python-8.0.23.tar.gz
|
wget https://cdn.mysql.com/archives/mysql-connector-python-8.0/mysql-connector-python-8.0.23.tar.gz
|
||||||
tar xzf mysql-connector-python-8.0.20.tar.gz
|
tar xzf mysql-connector-python-8.0.23.tar.gz
|
||||||
cd ~/tools/mysql-connector-python-8.0.20
|
cd ~/tools/mysql-connector-python-8.0.23
|
||||||
python3 setup.py install
|
python3 setup.py install
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -145,13 +145,20 @@ Create .env file based on example.env and edit the .env file if needed:
|
||||||
cp /myems-api/example.env /myems-api/.env
|
cp /myems-api/example.env /myems-api/.env
|
||||||
nano /myems-api/.env
|
nano /myems-api/.env
|
||||||
```
|
```
|
||||||
Change the listening port (default is 8000) in gunicorn.socket:
|
Check or change the listening port (default is 8000) in myems-api.service and myems-api.socket:
|
||||||
|
```bash
|
||||||
|
nano /myems-api/myems-api.service
|
||||||
|
```
|
||||||
|
```
|
||||||
|
ExecStart=/usr/local/bin/gunicorn -b 0.0.0.0:8000 --pid /run/myems-api/pid --timeout 600 --workers=4 app:api
|
||||||
|
```
|
||||||
```bash
|
```bash
|
||||||
nano /myems-api/myems-api.socket
|
nano /myems-api/myems-api.socket
|
||||||
```
|
```
|
||||||
```bash
|
```bash
|
||||||
ListenStream=0.0.0.0:8000
|
ListenStream=0.0.0.0:8000
|
||||||
```
|
```
|
||||||
|
Add port to firewall:
|
||||||
```bash
|
```bash
|
||||||
ufw allow 8000
|
ufw allow 8000
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import calendar
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import mysql.connector
|
import mysql.connector
|
||||||
import collections
|
import collections
|
||||||
|
@ -11,7 +12,7 @@ import statistics
|
||||||
# rows_hourly: list of (start_datetime_utc, actual_value), should belong to one energy_category_id
|
# rows_hourly: list of (start_datetime_utc, actual_value), should belong to one energy_category_id
|
||||||
# start_datetime_utc: start datetime in utc
|
# start_datetime_utc: start datetime in utc
|
||||||
# end_datetime_utc: end datetime in utc
|
# end_datetime_utc: end datetime in utc
|
||||||
# period_type: one of the following period types, 'hourly', 'daily', 'monthly' and 'yearly'
|
# period_type: one of the following period types, 'hourly', 'daily', 'weekly', 'monthly' and 'yearly'
|
||||||
# Note: this procedure doesn't work with multiple energy categories
|
# Note: this procedure doesn't work with multiple energy categories
|
||||||
########################################################################################################################
|
########################################################################################################################
|
||||||
def aggregate_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetime_utc, period_type):
|
def aggregate_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetime_utc, period_type):
|
||||||
|
@ -19,7 +20,7 @@ def aggregate_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetim
|
||||||
if start_datetime_utc is None or \
|
if start_datetime_utc is None or \
|
||||||
end_datetime_utc is None or \
|
end_datetime_utc is None or \
|
||||||
start_datetime_utc >= end_datetime_utc or \
|
start_datetime_utc >= end_datetime_utc or \
|
||||||
period_type not in ('hourly', 'daily', 'monthly', 'yearly'):
|
period_type not in ('hourly', 'daily', 'weekly', 'monthly', 'yearly'):
|
||||||
return list()
|
return list()
|
||||||
|
|
||||||
start_datetime_utc = start_datetime_utc.replace(tzinfo=None)
|
start_datetime_utc = start_datetime_utc.replace(tzinfo=None)
|
||||||
|
@ -58,6 +59,28 @@ def aggregate_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetim
|
||||||
|
|
||||||
return result_rows_daily
|
return result_rows_daily
|
||||||
|
|
||||||
|
elif period_type == 'weekly':
|
||||||
|
result_rows_weekly = list()
|
||||||
|
# todo: add config.working_day_start_time_local
|
||||||
|
# todo: add config.minutes_to_count
|
||||||
|
# calculate the start datetime in utc of the monday in the first week in local
|
||||||
|
start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3]))
|
||||||
|
weekday = start_datetime_local.weekday()
|
||||||
|
current_datetime_utc = \
|
||||||
|
start_datetime_local.replace(hour=0) - timedelta(days=weekday, hours=int(config.utc_offset[1:3]))
|
||||||
|
while current_datetime_utc <= end_datetime_utc:
|
||||||
|
|
||||||
|
next_datetime_utc = current_datetime_utc + timedelta(days=7)
|
||||||
|
|
||||||
|
subtotal = Decimal(0.0)
|
||||||
|
for row in rows_hourly:
|
||||||
|
if current_datetime_utc <= row[0] < next_datetime_utc:
|
||||||
|
subtotal += row[1]
|
||||||
|
result_rows_weekly.append((current_datetime_utc, subtotal))
|
||||||
|
current_datetime_utc = next_datetime_utc
|
||||||
|
|
||||||
|
return result_rows_weekly
|
||||||
|
|
||||||
elif period_type == "monthly":
|
elif period_type == "monthly":
|
||||||
result_rows_monthly = list()
|
result_rows_monthly = list()
|
||||||
# todo: add config.working_day_start_time_local
|
# todo: add config.working_day_start_time_local
|
||||||
|
@ -143,7 +166,7 @@ def aggregate_hourly_data_by_period(rows_hourly, start_datetime_utc, end_datetim
|
||||||
result_rows_yearly = list()
|
result_rows_yearly = list()
|
||||||
# todo: add config.working_day_start_time_local
|
# todo: add config.working_day_start_time_local
|
||||||
# todo: add config.minutes_to_count
|
# todo: add config.minutes_to_count
|
||||||
# calculate the start datetime in utc of the first day in the first month in local
|
# calculate the start datetime in utc of the first day in the first year in local
|
||||||
start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3]))
|
start_datetime_local = start_datetime_utc + timedelta(hours=int(config.utc_offset[1:3]))
|
||||||
current_datetime_utc = start_datetime_local.replace(month=1, day=1, hour=0) - timedelta(
|
current_datetime_utc = start_datetime_local.replace(month=1, day=1, hour=0) - timedelta(
|
||||||
hours=int(config.utc_offset[1:3]))
|
hours=int(config.utc_offset[1:3]))
|
||||||
|
|
|
@ -15,8 +15,8 @@ class VersionItem:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def on_get(req, resp):
|
def on_get(req, resp):
|
||||||
|
|
||||||
result = {"version": 'MyEMS v1.1.2',
|
result = {"version": 'MyEMS v1.3.2',
|
||||||
"release-date": '202104023',
|
"release-date": '2021-10-22',
|
||||||
"website": "https://myems.io"}
|
"website": "https://myems.io"}
|
||||||
resp.body = json.dumps(result)
|
resp.body = json.dumps(result)
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ mysql> show databases; // 查看数据库是否导入OK
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.部署mymes-api服务
|
### 3.部署mymes-api服务
|
||||||
安装一堆python依赖库
|
安装python依赖库
|
||||||
```shell
|
```shell
|
||||||
# 安装anytree
|
# 安装anytree
|
||||||
$ cd ~/tools
|
$ cd ~/tools
|
||||||
|
@ -136,10 +136,10 @@ $ source ~/.zshrc
|
||||||
### 4.运行myems-api服务
|
### 4.运行myems-api服务
|
||||||
```shell
|
```shell
|
||||||
$ git clone https://github.com/kuuyee/myems-api.git
|
$ git clone https://github.com/kuuyee/myems-api.git
|
||||||
$ cd myems-api
|
$ cd myems/myems-api
|
||||||
$ gunicorn -b 127.0.0.1:8000 app:api
|
$ gunicorn -b 0.0.0.0:8000 app:api
|
||||||
[2021-02-16 22:21:46 +0800] [3252] [INFO] Starting gunicorn 20.0.4
|
[2021-02-16 22:21:46 +0800] [3252] [INFO] Starting gunicorn 20.0.4
|
||||||
[2021-02-16 22:21:46 +0800] [3252] [INFO] Listening at: http://127.0.0.1:8000 (3252)
|
[2021-02-16 22:21:46 +0800] [3252] [INFO] Listening at: http://0.0.0.0:8000 (3252)
|
||||||
[2021-02-16 22:21:46 +0800] [3252] [INFO] Using worker: sync
|
[2021-02-16 22:21:46 +0800] [3252] [INFO] Using worker: sync
|
||||||
[2021-02-16 22:21:46 +0800] [3253] [INFO] Booting worker with pid: 3253
|
[2021-02-16 22:21:46 +0800] [3253] [INFO] Booting worker with pid: 3253
|
||||||
|
|
||||||
|
@ -148,12 +148,12 @@ $ gunicorn -b 127.0.0.1:8000 app:api
|
||||||
|
|
||||||
### 5.验证myems-api服务
|
### 5.验证myems-api服务
|
||||||
|
|
||||||
打开浏览器访问[http://localhost:8000/version](http://localhost:8000/version)
|
打开浏览器访问[http://0.0.0.0:8000/version](http://0.0.0.0:8000/version)
|
||||||
如果看到如下输出就表示服务启动正常。
|
如果看到如下输出就表示服务启动正常。
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"version": "MyEMS 1.0.3 (Community Edition)",
|
"version": "MyEMS 1.3.2",
|
||||||
"release-date": "20210215",
|
"release-date": "2021-10-22",
|
||||||
"website": "https://myems.io"
|
"website": "https://myems.io"
|
||||||
}
|
}
|
||||||
```
|
```
|
|
@ -8,7 +8,7 @@ PIDFile=/run/myems-api/pid
|
||||||
User=root
|
User=root
|
||||||
Group=root
|
Group=root
|
||||||
WorkingDirectory=/myems-api
|
WorkingDirectory=/myems-api
|
||||||
ExecStart=/usr/local/bin/gunicorn --pid /run/myems-api/pid --timeout 600 --workers=4 app:api
|
ExecStart=/usr/local/bin/gunicorn -b 0.0.0.0:8000 --pid /run/myems-api/pid --timeout 600 --workers=4 app:api
|
||||||
ExecReload=/bin/kill -s HUP $MAINPID
|
ExecReload=/bin/kill -s HUP $MAINPID
|
||||||
ExecStop=/bin/kill -s TERM $MAINPID
|
ExecStop=/bin/kill -s TERM $MAINPID
|
||||||
PrivateTmp=true
|
PrivateTmp=true
|
||||||
|
|
|
@ -53,7 +53,7 @@ class Reporting:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_PERIOD_TYPE')
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_PERIOD_TYPE')
|
||||||
else:
|
else:
|
||||||
period_type = str.strip(period_type)
|
period_type = str.strip(period_type)
|
||||||
if period_type not in ['hourly', 'daily', 'monthly', 'yearly']:
|
if period_type not in ['hourly', 'daily', 'weekly', 'monthly', 'yearly']:
|
||||||
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_PERIOD_TYPE')
|
raise falcon.HTTPError(falcon.HTTP_400, title='API.BAD_REQUEST', description='API.INVALID_PERIOD_TYPE')
|
||||||
|
|
||||||
timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
|
timezone_offset = int(config.utc_offset[1:3]) * 60 + int(config.utc_offset[4:6])
|
||||||
|
@ -208,6 +208,8 @@ class Reporting:
|
||||||
current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
|
current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
|
||||||
elif period_type == 'daily':
|
elif period_type == 'daily':
|
||||||
current_datetime = current_datetime_local.strftime('%Y-%m-%d')
|
current_datetime = current_datetime_local.strftime('%Y-%m-%d')
|
||||||
|
elif period_type == 'weekly':
|
||||||
|
current_datetime = current_datetime_local.strftime('%Y-%m-%d')
|
||||||
elif period_type == 'monthly':
|
elif period_type == 'monthly':
|
||||||
current_datetime = current_datetime_local.strftime('%Y-%m')
|
current_datetime = current_datetime_local.strftime('%Y-%m')
|
||||||
elif period_type == 'yearly':
|
elif period_type == 'yearly':
|
||||||
|
@ -250,6 +252,8 @@ class Reporting:
|
||||||
current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
|
current_datetime = current_datetime_local.strftime('%Y-%m-%dT%H:%M:%S')
|
||||||
elif period_type == 'daily':
|
elif period_type == 'daily':
|
||||||
current_datetime = current_datetime_local.strftime('%Y-%m-%d')
|
current_datetime = current_datetime_local.strftime('%Y-%m-%d')
|
||||||
|
elif period_type == 'weekly':
|
||||||
|
current_datetime = current_datetime_local.strftime('%Y-%m-%d')
|
||||||
elif period_type == 'monthly':
|
elif period_type == 'monthly':
|
||||||
current_datetime = current_datetime_local.strftime('%Y-%m')
|
current_datetime = current_datetime_local.strftime('%Y-%m')
|
||||||
elif period_type == 'yearly':
|
elif period_type == 'yearly':
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
gunicorn --pid pid --timeout 600 --workers=4 app:api
|
gunicorn -b 0.0.0.0:8000 --pid pid --timeout 600 --workers=4 app:api
|
Loading…
Reference in New Issue