Commit 58e2018b by zozo825117

first commit

parents
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
.python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don’t work, or not
# install all needed dependencies.
#Pipfile.lock
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
.pyc
\ No newline at end of file
# Default ignored files
/shelf/
/workspace.xml
# Datasource local storage ignored files
/../../../../../../:\work\github\python\LSDAHD-DTU00020_cloud\.idea/dataSources/
/dataSources.local.xml
# Editor-based HTTP Client requests
/httpRequests/
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="jdk" jdkName="Remote Python 3.7.2 (sftp://root@49.235.95.75:22/root/work/virtualenvs/LSDAHD-DTU00020/bin/python)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PublishConfigData" autoUpload="Always" serverName="tencent_lw" remoteFilesAllowedToDisappearOnAutoupload="false" autoUploadExternalChanges="true">
<serverData>
<paths name="WM201904002(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202011002(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202011003(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202011004(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202011004(tencent3) (1)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202011004(tencent3) (2)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202012001(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202012002(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202012003(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202012004(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="WM202012005(tencent3)">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="pi4_174">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
<paths name="tencent_lw">
<serverdata>
<mappings>
<mapping deploy="/root/work/python_prj/LSDAHD-DTU00020/" local="$PROJECT_DIR$" />
</mappings>
</serverdata>
</paths>
<paths name="ubuntu1804">
<serverdata>
<mappings>
<mapping local="$PROJECT_DIR$" web="/" />
</mappings>
</serverdata>
</paths>
</serverData>
<option name="myAutoUpload" value="ALWAYS" />
</component>
</project>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="DuplicatedCode" enabled="false" level="WEAK WARNING" enabled_by_default="false" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="21">
<item index="0" class="java.lang.String" itemvalue="scipy" />
<item index="1" class="java.lang.String" itemvalue="flask-restplus" />
<item index="2" class="java.lang.String" itemvalue="Werkzeug" />
<item index="3" class="java.lang.String" itemvalue="opencv-python" />
<item index="4" class="java.lang.String" itemvalue="PyQt5" />
<item index="5" class="java.lang.String" itemvalue="matplotlib" />
<item index="6" class="java.lang.String" itemvalue="numpy" />
<item index="7" class="java.lang.String" itemvalue="Flask-SQLAlchemy" />
<item index="8" class="java.lang.String" itemvalue="alembic" />
<item index="9" class="java.lang.String" itemvalue="six" />
<item index="10" class="java.lang.String" itemvalue="Flask-Migrate" />
<item index="11" class="java.lang.String" itemvalue="python-dateutil" />
<item index="12" class="java.lang.String" itemvalue="SQLAlchemy" />
<item index="13" class="java.lang.String" itemvalue="Click" />
<item index="14" class="java.lang.String" itemvalue="Mako" />
<item index="15" class="java.lang.String" itemvalue="python-editor" />
<item index="16" class="java.lang.String" itemvalue="Jinja2" />
<item index="17" class="java.lang.String" itemvalue="Flask" />
<item index="18" class="java.lang.String" itemvalue="Flask-Script" />
<item index="19" class="java.lang.String" itemvalue="MarkupSafe" />
<item index="20" class="java.lang.String" itemvalue="itsdangerous" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyTypeCheckerInspection" enabled="false" level="WARNING" enabled_by_default="false" />
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="false" level="WARNING" enabled_by_default="false" />
</profile>
</component>
\ No newline at end of file
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Remote Python 3.7.2 (sftp://root@49.235.95.75:22/root/work/virtualenvs/LSDAHD-DTU00020/bin/python)" project-jdk-type="Python SDK" />
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/LSDAHD-DTU00020_cloud.iml" filepath="$PROJECT_DIR$/.idea/LSDAHD-DTU00020_cloud.iml" />
</modules>
</component>
</project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WebServers">
<option name="servers">
<webServer id="0b8ddf6f-ec95-4133-9cda-5f8797c5959f" name="tencent_lw">
<fileTransfer accessType="SFTP" host="49.235.95.75" port="22" sshConfigId="1a54db76-5046-48c3-a890-96330ce3c84b" sshConfig="tencent_lw">
<advancedOptions>
<advancedOptions dataProtectionLevel="Private" passiveMode="true" shareSSLContext="true" />
</advancedOptions>
</fileTransfer>
</webServer>
</option>
</component>
</project>
\ No newline at end of file
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from config import config
import pymysql
import socket
import sys
import os
soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
soc.connect(('8.8.8.8', 80))
local_ip = soc.getsockname()[0]
print('local_ip ', local_ip)
# print('local_ip type', type(local_ip))
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
print('sys._MEIPASS: ', sys._MEIPASS)
print('os.getcwd: ', os.getcwd())
template_folder = os.path.join(sys._MEIPASS, 'templates')
static_folder = os.path.join(sys._MEIPASS, 'static')
app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
else:
print('normal mode')
# app = Flask(__name__)
print('cur pwd ', os.getcwd())
static_folder = os.path.join(os.getcwd(), 'app/static')
template_folder = os.path.join(os.getcwd(), 'app/templates')
app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
app.config['SECRET'] = 'my secret key'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = False
app.secret_key = 'secret string'
db = SQLAlchemy()
def create_app(config_name):
app.config.from_object(config[config_name])
from .august import august as august_blueprint
app.register_blueprint(august_blueprint)
config[config_name].init_app(app)
db.init_app(app)
# // 此处缺省了部分代码,后面会加上
return app
from flask import Blueprint
# 实例化 Blueprint 类,两个参数分别为蓝本的名字和蓝本所在包或模块,第二个通常填 __name__ 即可
august = Blueprint('august', __name__)
# 最后导入 防止循环导入
from . import views, errors
# -*- coding:utf-8 -*-
import time
import sys
import hashlib
import hmac
import base64
import stomp
import ssl
import schedule
import threading
import traceback
import json
import uuid
from .default import *
from .models import BatterySystemTable
from datetime import datetime as Datetime
from manage import db, app
class MyListener(stomp.ConnectionListener):
def __init__(self, conn, logger, connect_and_subscribe, Mqtt_ins, user_mysql):
self.conn = conn
self.logger = logger
self.connect_and_subscribe = connect_and_subscribe
self.mqtt_ins = Mqtt_ins
self.user_mysql = user_mysql
self.receive_topic = None
self.dtu_id = None
self.register = None
self.bms_message = ""
def gen_uuid(self):
return uuid.uuid1()
def on_error(self, headers, message):
self.logger.debug('received an error "%s"' % message)
def on_message(self, headers, message):
try:
self.logger.info('received a message: headers "%s" "%s"' % (headers, message))
message_dict = json.loads(message)
modbus_message = message_dict['message']
self.receive_topic = headers['topic']
self.dtu_id = self.get_dtu_id(self.receive_topic)
self.register = message_dict['message'][0:4]
self.data_structure(modbus_message)
except:
self.logger.error(traceback.format_exc())
def on_disconnected(self):
self.logger.debug('disconnected')
self.connect_and_subscribe(self.conn)
def on_heartbeat_timeout(self):
self.logger.debug('on_heartbeat_timeout')
def on_connected(self, headers, body):
self.logger.debug("successfully connected")
self.conn.subscribe(destination='/topic/#', id=1, ack='auto')
self.logger.debug("successfully subscribe")
def get_dtu_id(self, topic):
try:
if len(topic) == 0:
return None
else:
first_count = topic.index('/')
# self.logger.debug('first_count %s' % first_count)
second_count = topic.index('/', first_count + 1)
# self.logger.debug('second_count %s' % second_count)
third_count = topic.index('/', second_count + 1)
# self.logger.debug('third_count %s' % third_count)
result = topic[(second_count+1): third_count]
# self.logger.debug('result %s' % result)
return result
except:
self.logger.error(traceback.format_exc())
return None
def data_structure(self, modbus_msg):
MODBUS_TCP_DICT = {
MODBUS_TCP_READ_ADDRESS: modbus_msg[0: 4],
MODBUS_TCP_EMPTY_DUMMY: modbus_msg[4: 8],
MODBUS_TCP_READ_SIZE: modbus_msg[8: 12],
MODBUS_TCP_DEVICE_ID: modbus_msg[12: 14],
MODBUS_TCP_READ_COMMAND: modbus_msg[14: 16],
}
if MODBUS_TCP_DICT[MODBUS_TCP_READ_ADDRESS] == '7594':
BMS_PKG_DICT = {
BATTERY_STATUS_INFO_ID: '',
DTU_UPTIME: Datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
PKG_ID: '',
DTU_ID: self.dtu_id,
BMS_READ_SIZE: int(modbus_msg[16: 18], 16),
BMS_READ_PKG: modbus_msg[18:],
BMS_CHARGE_STATUS: int(modbus_msg[18: 20], 16),
BMS_SOC: int(modbus_msg[20: 22], 16),
BMS_ERR_STATUS: int(modbus_msg[20: 22], 16),
BMS_ERR_NBR: int(modbus_msg[22: 24], 16),
BMS_ERR_CODE: int(modbus_msg[24: 28], 16),
BMS_VOLTAGE: int(modbus_msg[28: 32], 16),
BMS_CURRENT: int(modbus_msg[32: 34], 16),
BMS_MAX_CELL_VOLTAGE: int(modbus_msg[34: 38], 16),
BMS_MIN_CELL_VOLTAGE: int(modbus_msg[38: 42], 16),
BMS_AVERAGE_CELL_VOLTAGE: int(modbus_msg[42: 46], 16),
BMS_MAX_TEMPERATURE: int(modbus_msg[46: 48], 16),
BMS_MIN_TEMPERATURE: int(modbus_msg[48: 50], 16),
BMS_MOS_TEMPERATURE: int(modbus_msg[50: 52], 16),
BMS_BALANCE_RESISTANCE: int(modbus_msg[52: 54], 16),
BMS_CHARGE_MOS_STATUS: int(modbus_msg[54: 56], 16),
BMS_DISCHARGE_MOS_STATUS: int(modbus_msg[56: 58], 16),
BMS_OTA_BUF_STATUS: int(modbus_msg[58: 60], 16),
BMS_MAGNETIC_CHECK: int(modbus_msg[60: 62], 16),
UPDATE_BY: '',
CREATED_AT: Datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
UPDATED_AT: Datetime.now().strftime('%Y-%m-%d %H:%M:%S')
}
self.logger.debug("MODBUS_TCP_DICT %s" % MODBUS_TCP_DICT)
self.logger.debug("BMS_PKG_DICT %s" % BMS_PKG_DICT)
if BMS_PKG_DICT[BMS_SOC] != '':
send_data = {
"id": '1',
"version": "1.0",
"params": {
"soc": int(BMS_PKG_DICT[BMS_SOC])
},
"method": "thing.event.property.post"
}
self.mqtt_ins.on_publish('/sys/a1uuY5icewu/august_test/thing/event/property/post', 'publish_test', send_data)
# update mysql
with app.app_context():
if BMS_PKG_DICT[BMS_READ_PKG] != self.bms_message:
self.user_mysql.update_local_db_with_dtu_id(BatterySystemTable.__tablename__, self.dtu_id, BMS_PKG_DICT)
self.bms_message = BMS_PKG_DICT[BMS_READ_PKG]
class AMQP:
def __init__(self, logger, Mqtt_ins, user_mysql):
self.logger = logger
self.mqtt_ins = Mqtt_ins
self.user_mysql = user_mysql
# 异步线程运行定时任务,检查连接状态
thread = threading.Thread(target=self.connection_check_timer)
thread.start()
# 接入域名,请参见AMQP客户端接入说明文档。这里直接填入域名,不需要带amqps://前缀
self.conn = stomp.Connection([('greenwhalecloud.iot-amqp.cn-shanghai.aliyuncs.com', 61614)])
self.conn.set_ssl(for_hosts=[('greenwhalecloud.iot-amqp.cn-shanghai.aliyuncs.com', 61614)],
ssl_version=ssl.PROTOCOL_TLS)
try:
self.connect_and_subscribe(self.conn)
except Exception as e:
self.logger.error('connecting failed')
raise e
def connect_and_subscribe(self, conn):
accessKey = "LTAI4GD2CJPgtqusvgrLghop"
accessSecret = "lqWFaQGkga853U42ZT6S6jzhJaQLsf"
consumerGroupId = "1np6hJcF6faKc3kF8ShS000100"
# iotInstanceId:购买的实例请填写实例ID,公共实例请填空字符串""。
iotInstanceId = ""
clientId = "12345"
# 签名方法:支持hmacmd5,hmacsha1和hmacsha256。
signMethod = "hmacsha1"
timestamp = self.current_time_millis()
# userName组装方法,请参见AMQP客户端接入说明文档。
# 若使用二进制传输,则userName需要添加encode=base64参数,服务端会将消息体base64编码后再推送。具体添加方法请参见下一章节“二进制消息体说明”。
username = clientId + "|authMode=aksign" + ",signMethod=" + signMethod \
+ ",timestamp=" + timestamp + ",authId=" + accessKey \
+ ",iotInstanceId=" + iotInstanceId \
+ ",consumerGroupId=" + consumerGroupId + "|"
signContent = "authId=" + accessKey + "&timestamp=" + timestamp
# 计算签名,password组装方法,请参见AMQP客户端接入说明文档。
password = self.do_sign(accessSecret.encode("utf-8"), signContent.encode("utf-8"))
conn.set_listener('', MyListener(conn, self.logger, self.connect_and_subscribe, self.mqtt_ins, self.user_mysql))
conn.connect(username, password, wait=True)
# 清除历史连接检查任务,新建连接检查任务
schedule.clear('conn-check')
schedule.every(1).seconds.do(self.do_check, conn).tag('conn-check')
def current_time_millis(self):
return str(int(round(time.time() * 1000)))
def do_sign(self, secret, sign_content):
m = hmac.new(secret, sign_content, digestmod=hashlib.sha1)
return base64.b64encode(m.digest()).decode("utf-8")
# 检查连接,如果未连接则重新建连
def do_check(self, conn):
self.logger.debug('check connection, is_connected: %s', conn.is_connected())
if not conn.is_connected():
try:
self.connect_and_subscribe(conn)
except Exception as e:
self.logger.debug('disconnected, ', e)
# 定时任务方法,检查连接状态
def connection_check_timer(self):
while 1:
schedule.run_pending()
time.sleep(10)
# coding=utf-8
# system config
DSYSCFG_FILE = "system_config.ini"
DSYSCFG_LOGGING_PATH = 'logging_path'
DSYSCFG_LOGGING_LEVEL = 'logging_level'
# record
DREC_PRODUCT_INFO = 'product_info'
DREC_EQUIPMENT_INDEX = 'equipment_index'
# mqtt config
MqTT_SERVER_HOST = 'mqtt_server_host'
MqTT_SERVER_PORT = 'mqtt_server_port'
MqTT_SERVER_TOPIC = 'mqtt_server_topic'
MqTT_MASTER_HOST = 'mqtt_master_host'
MqTT_MASTER_PORT = 'mqtt_master_port'
MqTT_MASTER_TOPIC = 'mqtt_master_topic'
# mqtt command
# MODBUS TCP
MODBUS_TCP_READ_ADDRESS = 'modbus_tcp_read_address'
MODBUS_TCP_EMPTY_DUMMY = 'modbus_tcp_empty_dummy'
MODBUS_TCP_READ_SIZE = 'modbus_tcp_read_size'
MODBUS_TCP_DEVICE_ID = 'modbus_tcp_device_id'
MODBUS_TCP_READ_COMMAND = 'modbus_tcp_read_command'
# modbus tcp dict
MODBUS_TCP_DICT = {
MODBUS_TCP_READ_ADDRESS: '',
MODBUS_TCP_EMPTY_DUMMY: '',
MODBUS_TCP_READ_SIZE: '',
MODBUS_TCP_DEVICE_ID: '',
MODBUS_TCP_READ_COMMAND: ''
}
# bms pkg
BMS_PKG_MESSAGE = ''
BMS_READ_SIZE = 'bms_read_size'
BMS_READ_PKG = 'bms_read_pkg'
BATTERY_STATUS_INFO_ID = 'battery_status_info_id'
DTU_UPTIME = 'dtu_uptime'
PKG_ID = 'pkg_id'
DTU_ID = 'dtu_id'
BMS_CHARGE_STATUS = 'bms_charge_status'
BMS_SOC = 'bms_soc'
BMS_ERR_STATUS = 'bms_err_status'
BMS_ERR_NBR = 'bms_err_nbr'
BMS_ERR_CODE = 'bms_err_code'
BMS_VOLTAGE = 'bms_voltage'
BMS_CURRENT = 'bms_current'
BMS_MAX_CELL_VOLTAGE = 'bms_max_cell_voltage'
BMS_MIN_CELL_VOLTAGE = 'bms_min_cell_voltage'
BMS_AVERAGE_CELL_VOLTAGE = 'bms_average_cell_voltage'
BMS_MAX_TEMPERATURE = 'bms_max_temperature'
BMS_MIN_TEMPERATURE = 'bms_min_temperature'
BMS_MOS_TEMPERATURE = 'bms_mos_temperature'
BMS_BALANCE_RESISTANCE = 'bms_balance_resistance'
BMS_CHARGE_MOS_STATUS = 'bms_charge_mos_status'
BMS_DISCHARGE_MOS_STATUS = 'bms_discharge_mos_status'
BMS_OTA_BUF_STATUS = 'bms_ota_buf_status'
BMS_MAGNETIC_CHECK = 'bms_magnetic_check'
UPDATE_BY = 'update_by'
CREATED_AT = 'created_at'
UPDATED_AT = 'updated_at'
DELETED_AT = 'deleted_at'
# BMS_PROPERTY_
# bms dict
BMS_PKG_DICT = {
BMS_READ_SIZE: '',
BMS_READ_PKG: '',
BATTERY_STATUS_INFO_ID: '',
DTU_UPTIME: '',
PKG_ID: '',
DTU_ID: '',
BMS_CHARGE_STATUS: '',
BMS_SOC: '',
BMS_ERR_STATUS: '',
BMS_ERR_NBR: '',
BMS_ERR_CODE: '',
BMS_VOLTAGE: '',
BMS_CURRENT: '',
BMS_MAX_CELL_VOLTAGE: '',
BMS_MIN_CELL_VOLTAGE: '',
BMS_AVERAGE_CELL_VOLTAGE: '',
BMS_MAX_TEMPERATURE: '',
BMS_MIN_TEMPERATURE: '',
BMS_MOS_TEMPERATURE: '',
BMS_BALANCE_RESISTANCE: '',
BMS_CHARGE_MOS_STATUS: '',
BMS_DISCHARGE_MOS_STATUS: '',
BMS_OTA_BUF_STATUS: '',
BMS_MAGNETIC_CHECK: '',
UPDATE_BY: '',
CREATED_AT: '',
UPDATED_AT: '',
DELETED_AT: ''
}
from flask import render_template
from . import august
@august.app_errorhandler(404)
def page_not_found(e):
return render_template('404.html'), 404
# -*- coding:utf-8 -*-
from .default import *
from manage import db, app
from app import local_ip
import time
import uuid
def gen_time():
return "%.0f" % time.time()
def gen_uuid():
return uuid.uuid1()
class GenMsg:
def __init__(self, logger, wm_config):
self.logger = logger
self.wm_config = wm_config
# -*- coding:utf-8 -*-
import logging
import logging.handlers
class MyLogging(logging.Logger):
def __init__(self, name, path='', level=logging.DEBUG):
"""
:param name:
:param path:
:param level:
"""
super().__init__(name)
# self.logger = logging.getLogger() # 不加名称设置root logger
self.setLevel(level)
#formatter = logging.Formatter(
# '%(asctime)s.%(msecs)03d:%(name)s:%(funcName)s:%(levelname)s: %(message)s',
# datefmt='%y-%m-%d %H:%M:%S')
formatter = logging.Formatter(
'%(asctime)s.%(msecs)03d:%(funcName)s:%(lineno)d:%(levelname)s: %(message)s',
datefmt='%y-%m-%d %H:%M:%S')
# 使用FileHandler输出到文件
if path != '':
# fh = logging.FileHandler(path)
"""
根据时间 S/H 秒/小时 24h ,文件不删除backupCount=0
"""
# fh = logging.handlers.TimedRotatingFileHandler(filename=path, when='h', interval=24,backupCount=0)
"""
根据文件大小,1000bytes,文件5个备份,滚动删除
"""
fh = logging.handlers.RotatingFileHandler(filename=path, maxBytes=10485760, backupCount=50)
fh.setLevel(level)
fh.setFormatter(formatter)
self.addHandler(fh)
# 使用StreamHandler输出到屏幕
ch = logging.StreamHandler()
ch.setLevel(level)
ch.setFormatter(formatter)
self.addHandler(ch)
# self.debug("This is a debug log.")
# self.info("This is a info log.")
# self.warning("This is a warning log.")
# self.error("This is a error log.")
# self.critical("This is a critical log.")
# -*- coding:utf-8 -*-
from app import db # db是在app/__init__.py生成的关联后的SQLAlchemy实例
class BatterySystemTable(db.Model):
__tablename__ = 'Battery_System_Table'
id = db.Column(db.Integer, primary_key=True)
battery_status_info_id = db.Column(db.String(50), unique=False)
dtu_uptime = db.Column(db.DateTime(), unique=False)
pkg_id = db.Column(db.String(50), unique=False)
dtu_id = db.Column(db.String(50), unique=False)
bms_charge_status = db.Column(db.String(50), unique=False)
bms_soc = db.Column(db.Integer, unique=False)
bms_err_status = db.Column(db.String(50), unique=False)
bms_err_nbr = db.Column(db.String(50), unique=False)
bms_err_code = db.Column(db.String(50), unique=False)
bms_voltage = db.Column(db.String(50), unique=False)
bms_current = db.Column(db.String(50), unique=False)
bms_max_cell_voltage = db.Column(db.String(50), unique=False)
bms_min_cell_voltage = db.Column(db.String(50), unique=False)
bms_average_cell_voltage = db.Column(db.String(50), unique=False)
bms_max_temperature = db.Column(db.String(50), unique=False)
bms_min_temperature = db.Column(db.String(50), unique=False)
bms_mos_temperature = db.Column(db.String(50), unique=False)
bms_balance_resistance = db.Column(db.String(50), unique=False)
bms_charge_mos_status = db.Column(db.String(50), unique=False)
bms_discharge_mos_status = db.Column(db.String(50), unique=False)
bms_ota_buf_status = db.Column(db.String(50), unique=False)
bms_magnetic_check = db.Column(db.String(50), unique=False)
update_by = db.Column(db.String(50), unique=False)
created_at = db.Column(db.DateTime(), unique=False)
updated_at = db.Column(db.DateTime(), unique=False)
deleted_at = db.Column(db.DateTime(), unique=False)
def __repr__(self):
return '<Battery_System_Table %r>' % self.order_number
# -*- coding:utf-8 -*-
from manage import db, app
from .default import *
import json
import paho.mqtt.client as mqtt
import queue
import time
from datetime import datetime as Datetime
import os
import base64
import threading
import traceback
class MqTTClient:
def __init__(self, mq_dict, logger):
self.logger = logger
self.logger.debug('MqTTClient __init__')
self.host = mq_dict['host']
self.port = int(mq_dict['port'])
self.username = mq_dict['username']
self.password = mq_dict['password']
self.mqtt = mqtt.Client(client_id=mq_dict['client_id'])
self.mqtt.username_pw_set(self.username, self.password)
self.topic = mq_dict['topic']
self.msg_queue = queue.Queue()
self.msg_process_threader = threading.Thread(target=self.mq_msg_process)
self.msg_process_threader.start()
def connect(self):
try:
self.mqtt.connect(self.host, self.port)
self.mqtt.on_connect = self.on_connect
self.mqtt.on_message = self.on_message
self.mqtt.disconnect = self.dis_connect
self.mqtt.on_log = self.on_log
self.mqtt.loop_start() # 保持连接
except Exception:
self.logger.error('host: %s error to reconnect' % self.host)
timer_to_reconnect = threading.Timer(3, self.on_reconnect)
timer_to_reconnect.start()
def on_connect(self, client, userdata, flags, rc):
try:
# self.mqtt.subscribe(self.topic, qos=1)
# # 基础通信
# # OTA升级
# self.mqtt.subscribe('/ota/device/inform/a1uuY5icewu/august_test', qos=1)
# self.mqtt.subscribe('/ota/device/upgrade/a1uuY5icewu/august_test', qos=1)
# self.mqtt.subscribe('/ota/device/progress/a1uuY5icewu/august_test', qos=1)
# self.mqtt.subscribe('/ota/device/request/a1uuY5icewu/august_test', qos=1)
#
# # 设备标签
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/deviceinfo/update', qos=1)
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/deviceinfo/update_reply', qos=1)
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/deviceinfo/delete', qos=1)
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/deviceinfo/delete_reply', qos=1)
#
# # 时钟同步
# self.mqtt.subscribe('/ext/ntp/a1uuY5icewu/august_test/request', qos=1)
# self.mqtt.subscribe('/ext/ntp/a1uuY5icewu/august_test/response', qos=1)
#
# # 设备影子
# self.mqtt.subscribe('/shadow/update/a1uuY5icewu/august_test', qos=1)
# self.mqtt.subscribe('/shadow/get/a1uuY5icewu/august_test', qos=1)
#
# # 配置更新
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/config/push', qos=1)
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/config/get', qos=1)
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/config/get_reply', qos=1)
#
# # 物模型通信
# # 属性设置
# self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/service/property/set', qos=1)
# 属性上报
self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/event/property/post', qos=1)
self.mqtt.subscribe('/sys/a1uuY5icewu/august_test/thing/event/property/post_reply', qos=1)
# # 其他
# self.mqtt.subscribe('/sys/a1fOUjbtuw1/august_test/thing/service/property/set', qos=1)
# self.mqtt.subscribe('/sys/a1fOUjbtuw1/august_test/thing/event/property/post', qos=1)
#
# self.mqtt.subscribe('/sys/a1fOUjbtuw1/liuwei_test/thing/service/property/set', qos=1)
# self.mqtt.subscribe('/sys/a1fOUjbtuw1/liuwei_test/thing/event/property/post', qos=1)
# self.mqtt.subscribe('/as/mqtt/status/a188ncLCDbX/TSTDTU01012101140002', qos=1)
self.mqtt.subscribe(self.topic, qos=1)
self.logger.debug('MqTT.host: %s' % self.mqtt._host)
self.logger.debug('MqTT.port: %s' % self.mqtt._port)
self.logger.debug('MqTT.client_id: %s' % self.mqtt._client_id)
self.logger.debug('MqTT.username: %s' % self.mqtt._username)
self.logger.debug('MqTT.password: %s' % self.mqtt._password)
except Exception:
self.logger.error(traceback.format_exc())
def on_reconnect(self):
try:
self.logger.debug('on_reconnect')
self.connect()
except Exception:
self.logger.error(traceback.format_exc())
def dis_connect(self, client, userdata, rc):
try:
self.logger.debug('dis_connect %s %s' % (userdata, rc)) # str
self.mqtt.connect(self.host, self.port)
self.logger.debug('MqTT.host: %s' % self.mqtt._host)
self.logger.debug('MqTT.port: %s' % self.mqtt._port)
self.logger.debug('MqTT.client_id: %s' % self.mqtt._client_id)
self.logger.debug('MqTT.username: %s' % self.mqtt._username)
self.logger.debug('MqTT.password: %s' % self.mqtt._password)
except Exception:
self.logger.error(traceback.format_exc())
def on_log(self, client, userdata, level, buf):
# self.logger.debug('mq tt : %s' % self.host)
# self.logger.debug('on_log %s %s' % (level, buf))
pass
def on_publish(self, topic, publish_type, message_dict):
if publish_type == 'publish_test':
self.mqtt.publish(topic, json.dumps(message_dict), qos=1)
self.logger.debug('------------------>publish_test')
else:
pass
def on_message(self, client, userdata, message):
try:
self.logger.info("on_message")
topic = str(message.topic)
payload = str(message.payload.decode("utf-8"))
self.logger.debug("topic : %s " % topic)
self.logger.debug("payload: %s" % payload)
# if topic == self.topic:
# message_dict = json.loads(payload)
#
# self.logger.debug("message_dict %s" % message_dict)
# # 消息进队
# self.msg_queue.put(message_dict)
except:
self.logger.error("message-----> %s" % message.payload)
self.logger.error(traceback.format_exc())
# 消息队列处理
def mq_msg_process(self):
try:
while True:
if self.msg_queue.empty() is not True:
receive_dict = self.msg_queue.get()
try:
self.logger.debug("receive_dict %s" % receive_dict)
except Exception:
self.logger.error(traceback.format_exc())
time.sleep(0.001)
self.msg_queue.task_done()
time.sleep(0.001)
except Exception:
self.logger.error(traceback.format_exc())
# -*- coding:utf-8 -*-
import time
from datetime import datetime as Datetime
# from datetime import datetime as Datetime
import json
import traceback
from app import db
from .default import *
from .logger import *
# from .mqtt import *
from .models import BatterySystemTable
from datetime import datetime as Datetime
class MetalMysql:
def __init__(self):
# super.__init__()
self.local_db = None
self.local_para_dict = None
def create_table(self):
db.create_all()
print('MetalMysql create_table ok')
def get_sort_order_number(self, table_name):
if table_name == BatterySystemTable.__tablename__:
data = BatterySystemTable.query.filter().order_by(BatterySystemTable.dtu_uptime)
return data
def read_local_db_data(self, table_name):
if table_name == BatterySystemTable.__tablename__:
data = BatterySystemTable.query.filter().all()
return data
else:
return None
def write_local_db_data(self, table_name, write_dict):
if table_name == BatterySystemTable.__tablename__:
battery_profile = BatterySystemTable(battery_status_info_id=write_dict['battery_status_info_id'],
dtu_uptime=write_dict['dtu_uptime'],
pkg_id=write_dict['pkg_id'],
dtu_id=write_dict['dtu_id'],
bms_charge_status=write_dict['bms_charge_status'],
bms_soc=write_dict['bms_soc'],
bms_err_status=write_dict['bms_err_status'],
bms_err_nbr=write_dict['bms_err_nbr'],
bms_err_code=write_dict['bms_err_code'],
bms_voltage=write_dict['bms_voltage'],
bms_current=write_dict['bms_current'],
bms_max_cell_voltage=write_dict['bms_max_cell_voltage'],
bms_min_cell_voltage=write_dict['bms_min_cell_voltage'],
bms_average_cell_voltage=write_dict['bms_average_cell_voltage'],
bms_max_temperature=write_dict['bms_max_temperature'],
bms_min_temperature=write_dict['bms_min_temperature'],
bms_mos_temperature=write_dict['bms_mos_temperature'],
bms_balance_resistance=write_dict['bms_balance_resistance'],
bms_charge_mos_status=write_dict['bms_charge_mos_status'],
bms_discharge_mos_status=write_dict['bms_discharge_mos_status'],
bms_ota_buf_status=write_dict['bms_ota_buf_status'],
bms_magnetic_check=write_dict['bms_magnetic_check'],
update_by=write_dict['update_by'],
created_at=write_dict['created_at']
)
db.session.add(battery_profile)
db.session.commit()
return True
else:
return False
def delete_local_db_data(self, table_name):
if table_name == BatterySystemTable.__tablename__:
data = BatterySystemTable.query.filter().delete()
return data
else:
return None
def is_need_to_write_device_table(self, table_name, device_table):
if table_name == BatterySystemTable.__tablename__:
update_profile = BatterySystemTable.query.filter(
BatterySystemTable.device_id == device_table['dtu_id']).first()
if update_profile is None:
return False
else:
return True
return False
def update_local_db_with_dtu_id(self, table_name, dtu_id, write_dict):
if table_name == BatterySystemTable.__tablename__:
update_profile = BatterySystemTable.query.filter(
BatterySystemTable.dtu_id == dtu_id).first()
if update_profile is None:
self.write_local_db_data(table_name, write_dict)
else:
update_profile.battery_status_info_id = write_dict['battery_status_info_id']
update_profile.dtu_uptime = write_dict['dtu_uptime']
update_profile.pkg_id = write_dict['pkg_id']
update_profile.dtu_id = write_dict['dtu_id']
update_profile.bms_charge_status = write_dict['bms_charge_status']
update_profile.bms_soc = write_dict['bms_soc']
update_profile.bms_err_status = write_dict['bms_err_status']
update_profile.bms_err_nbr = write_dict['bms_err_nbr']
update_profile.bms_err_code = write_dict['bms_err_code']
update_profile.bms_voltage = write_dict['bms_voltage']
update_profile.bms_current = write_dict['bms_current']
update_profile.bms_max_cell_voltage = write_dict['bms_max_cell_voltage']
update_profile.bms_min_cell_voltage = write_dict['bms_min_cell_voltage']
update_profile.bms_average_cell_voltage = write_dict['bms_average_cell_voltage']
update_profile.bms_max_temperature = write_dict['bms_max_temperature']
update_profile.bms_min_temperature = write_dict['bms_min_temperature']
update_profile.bms_mos_temperature = write_dict['bms_mos_temperature']
update_profile.bms_balance_resistance = write_dict['bms_balance_resistance']
update_profile.bms_charge_mos_status = write_dict['bms_charge_mos_status']
update_profile.bms_discharge_mos_status = write_dict['bms_discharge_mos_status']
update_profile.bms_ota_buf_status = write_dict['bms_ota_buf_status']
update_profile.bms_magnetic_check = write_dict['bms_magnetic_check']
update_profile.update_by = write_dict['update_by']
update_profile.updated_at = write_dict['updated_at']
db.session.commit()
return True
# coding=utf-8
import time
from threading import Timer
# class RepeatingTimer(Timer):
# def run(self):
# self.count = 10
# while not self.finished.is_set() or self.count:
# self.count = self.function(*self.args, **self.kwargs)
# if self.count:
# self.finished.wait(self.interval)
#
# class TimeOut():
# def __init__(self):
# self.timer = None
# pass
#
# def set_timer(self, time_out):
# self.timer = RepeatingTimer(1.0, self.time_timeout, args=())
# pass
#
# def reset_timer(self, time_out):
# pass
#
# def time_timeout(self):
# pass
#
# def on_time_out(self):
# pass
from typing import Callable
class PerpetualTimer:
"""A Timer class that does not stop, unless you want it to."""
def __init__(self, seconds, target):
# self.logger = MyLogging(name=__class__, path="", level=10)
self._should_continue = False
self.is_running = False
self.seconds = seconds
self.target = target
self.thread = None
# self.start()
def _handle_target(self):
# self.logger.debug('_handle_target')
print('_handle_target')
self.is_running = True
if self.target is not None:
self.target()
else:
print('target is none')
# self.logger.debug('target is none')
self.is_running = False
# print('handled target')
# self._start_timer()
def _start_timer(self):
# Code could have been running when cancel was called.
if self._should_continue:
self.thread = Timer(self.seconds, self._handle_target)
self.thread.start()
def start(self):
if not self._should_continue and not self.is_running:
self._should_continue = True
self._start_timer()
def cancel(self):
if self.thread is not None:
# Just in case thread is running and cancel fails.
self._should_continue = False
self.thread.cancel()
def on_timeout(self):
# type: () -> Callable
"""Decorator.
Decorator to handle the event when the broker responds to a connection
request. Only the last decorated function will be called.
"""
def decorator(handler):
# type: (Callable) -> Callable
self.target = handler
# self.logger.debug('on_timeout type=%s'% type(handler) )
print('on_timeout type = ', type(handler))
return handler
return decorator
\ No newline at end of file
# -*- coding:utf-8 -*-
from __future__ import division
from flask import render_template, jsonify, request, redirect, url_for, flash, get_flashed_messages
from . import august
from .logger import MyLogging
from .wm_config import WaterMConfig
from .default import *
from datetime import datetime as Datetime
from app import local_ip
from .mysql import MetalMysql
from .genmsg import GenMsg
from .amqp import AMQP
from .mqtt import MqTTClient
from .models import BatterySystemTable
import os
import logging
import sys
import re
import json
import time
import uuid
import socket
import subprocess
import threading
import traceback
# instance logger config
wm_config = WaterMConfig()
logger = MyLogging(name='main', path=wm_config.logger_path, level=wm_config.logger_level)
wm_config.set_logger(logger)
# instance mysql
user_mysql = MetalMysql()
# instance GenMsg
gen_msg = GenMsg(logger, user_mysql)
# instance mqtt
# master_mqtt_host, m_host_ok = wm_config.get_system_config_key_value(MqTT_MASTER_HOST)
# master_mqtt_port, m_port_ok = wm_config.get_system_config_key_value(MqTT_MASTER_PORT)
# master_mqtt_topic, m_topic_ok = wm_config.get_system_config_key_value(MqTT_MASTER_TOPIC)
# master_mqtt_dict = {'host': master_mqtt_host, 'port': master_mqtt_port, 'topic': master_mqtt_topic}
# master_mqtt = MqTTClient(master_mqtt_dict, logger)
# master_mqtt.connect()
mqtt_dict = {'host': 'a1uuY5icewu.iot-as-mqtt.cn-shanghai.aliyuncs.com',
'port': 1883,
'username': 'august_test&a1uuY5icewu',
'password': 'F5255EAF4F6FBABFDFD94D10EEB8F6AB8EFDD921',
'client_id': '12345|securemode=3,signmethod=hmacsha1|',
'topic': '/sys/a1uuY5icewu/august_test/thing/event/property/post'}
Mqtt_ins = MqTTClient(mqtt_dict, logger)
Mqtt_ins.connect()
amqp_ins = AMQP(logger, Mqtt_ins, user_mysql)
logger.debug("views run")
def gen_time():
return "%.0f" % time.time()
def gen_uuid():
return uuid.uuid1()
@august.route('/')
def setting():
logger.debug(">>>>>>>>>>>>>>>>>>>>>>index<<<<<<<<<<<<<<<<<<<<<<")
user_mysql.create_table()
return render_template('index.html')
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.15.5
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
@charset "UTF-8";.bootstrap-table .fixed-table-toolbar::after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-toolbar .bs-bars,.bootstrap-table .fixed-table-toolbar .search,.bootstrap-table .fixed-table-toolbar .columns{position:relative;margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group>.btn{border-radius:0}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .dropdown-menu{text-align:left;max-height:300px;overflow:auto;-ms-overflow-style:scrollbar;z-index:1001}.bootstrap-table .fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.428571429}.bootstrap-table .fixed-table-toolbar .columns-left{margin-right:5px}.bootstrap-table .fixed-table-toolbar .columns-right{margin-left:5px}.bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu{right:0;left:auto}.bootstrap-table .fixed-table-container{position:relative;clear:both}.bootstrap-table .fixed-table-container .table{width:100%;margin-bottom:0!important}.bootstrap-table .fixed-table-container .table th,.bootstrap-table .fixed-table-container .table td{vertical-align:middle;box-sizing:border-box}.bootstrap-table .fixed-table-container .table thead th{vertical-align:bottom;padding:0;margin:0}.bootstrap-table .fixed-table-container .table thead th:focus{outline:0 solid transparent}.bootstrap-table .fixed-table-container .table thead th.detail{width:30px}.bootstrap-table .fixed-table-container .table thead th .th-inner{padding:.75rem;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bootstrap-table .fixed-table-container .table thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px}.bootstrap-table .fixed-table-container .table thead th .both{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC")}.bootstrap-table .fixed-table-container .table thead th .asc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==")}.bootstrap-table .fixed-table-container .table thead th .desc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ")}.bootstrap-table .fixed-table-container .table tbody tr.selected td{background-color:rgba(0,0,0,0.075)}.bootstrap-table .fixed-table-container .table tbody tr.no-records-found{text-align:center}.bootstrap-table .fixed-table-container .table tbody tr .card-view{display:flex}.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title{font-weight:bold;display:inline-block;min-width:30%;text-align:left!important}.bootstrap-table .fixed-table-container .table .bs-checkbox{text-align:center}.bootstrap-table .fixed-table-container .table .bs-checkbox label{margin-bottom:0}.bootstrap-table .fixed-table-container .table input[type=radio],.bootstrap-table .fixed-table-container .table input[type=checkbox]{margin:0 auto!important}.bootstrap-table .fixed-table-container .table.table-sm .th-inner{padding:.3rem}.bootstrap-table .fixed-table-container.fixed-height:not(.has-footer){border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height.has-card-view{border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .fixed-table-border{border-left:1px solid #dee2e6;border-right:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table thead th{border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table-dark thead th{border-bottom:1px solid #32383e}.bootstrap-table .fixed-table-container .fixed-table-header{overflow:hidden}.bootstrap-table .fixed-table-container .fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading{align-items:center;background:#fff;display:none;justify-content:center;position:absolute;bottom:0;width:100%;z-index:1000}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap{align-items:baseline;display:flex;justify-content:center}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text{font-size:2rem;margin-right:6px}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap{align-items:center;display:flex;justify-content:center}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before{content:"";animation-duration:1.5s;animation-iteration-count:infinite;animation-name:LOADING;background:#212529;border-radius:50%;display:block;height:5px;margin:0 4px;opacity:0;width:5px}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot{animation-delay:.3s}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after{animation-delay:.6s}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark{background:#212529}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before{background:#fff}.bootstrap-table .fixed-table-container .fixed-table-footer{overflow:hidden}.bootstrap-table .fixed-table-pagination::after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-pagination>.pagination-detail,.bootstrap-table .fixed-table-pagination>.pagination{margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-pagination>.pagination-detail .pagination-info{line-height:34px;margin-right:5px}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list{display:inline-block}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group{position:relative;display:inline-block;vertical-align:middle}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group .dropdown-menu{margin-bottom:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination{margin:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination a{padding:6px 12px;line-height:1.428571429}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a{color:#c8c8c8}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a::before{content:"⬅"}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a::after{content:"➡"}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.disabled a{pointer-events:none;cursor:default}.bootstrap-table.fullscreen{position:fixed;top:0;left:0;z-index:1050;width:100%!important;background:#fff;height:calc(100vh);overflow-y:scroll}div.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}@keyframes LOADING{0%{opacity:0}50%{opacity:1}to{opacity:0}}
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
@media (max-width: 1200px) {
.blank_div {
display: none;
}
}
/*body, html {*/
/*overflow-x: hidden;*/
/*overflow-y: hidden;*/
/*}*/
/*add august*/
#live_image img{
max-height:400px;
max-width: 100%;
vertical-align:middle;
}
.setting_ensure {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.setting_ensure:focus,
.setting_ensure.focus {
color: #333;
background-color: #e6e6e6;
border-color: #8c8c8c;
}
.setting_ensure:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.status_blank{
width: 11px;
height: 100%;
float: left;
background-color: white;
}
.status_body{
width: 150px;
height: 100%;
float: left;
background-color: white;
border-radius: 5px;
/*border: 1px solid gray;*/
}
.status_body_header{
height: 30px;
font-size: 20px;
text-align: center;
background-color: white;
/*border-radius: 5px;*/
}
.status_body_q{
border-radius: 5px;
height: 37px;
font-size: 14px;
text-align: center;
background-color: whitesmoke;
}
.status_body_pass{
border-radius: 5px;
height: 37px;
font-size: 14px;
text-align: center;
background-color: green;
}
.status_body_fail{
border-radius: 5px;
height: 37px;
font-size: 14px;
text-align: center;
background-color: red;
}
.status_body_blank{
height: 2px;
border: 1px solid white;
}
.status_body_result{
border-radius: 5px;
height: 30px;
font-size: 18px;
text-align: center;
font-weight: bold;
background-color: whitesmoke;
/*background-color: green;*/
}
.mui-switch {
width: 52px;
height: 31px;
position: relative;
border: 1px solid #dfdfdf;
background-color: #fdfdfd;
box-shadow: #dfdfdf 0 0 0 0 inset;
border-radius: 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-clip: content-box;
display: inline-block;
-webkit-appearance: none;
user-select: none;
outline: none;
}
.mui-switch:before {
content: '';
width: 29px;
height: 29px;
position: absolute;
top: 0px;
left: 0;
border-radius: 20px;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
border-bottom-left-radius: 20px;
border-bottom-right-radius: 20px;
background-color: #fff;
/*box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);*/
}
.mui-switch:checked {
border-color: #64bd63;
box-shadow: #64bd63 0 0 0 16px inset;
background-color: #64bd63;
}
.mui-switch:checked:before {
left: 21px;
}
.mui-switch.mui-switch-animbg {
transition: background-color ease 0.4s;
}
.mui-switch.mui-switch-animbg:before {
transition: left 0.3s;
}
.mui-switch.mui-switch-animbg:checked {
box-shadow: #dfdfdf 0 0 0 0 inset;
background-color: #64bd63;
transition: border-color 0.4s, background-color ease 0.4s;
}
.mui-switch.mui-switch-animbg:checked:before {
transition: left 0.3s;
}
.mui-switch.mui-switch-anim {
transition: border cubic-bezier(0, 0, 0, 1) 0.4s, box-shadow cubic-bezier(0, 0, 0, 1) 0.4s; }
.mui-switch.mui-switch-anim:before {
transition: left 0.3s;
}
.mui-switch.mui-switch-anim:checked {
box-shadow: #64bd63 0 0 0 16px inset;
background-color: #64bd63;
transition: border ease 0.4s, box-shadow ease 0.4s, background-color ease 1.2s;
}
.mui-switch.mui-switch-anim:checked:before {
transition: left 0.3s;
}
.fixed-table-header {
font-size: 12px;
/*border: solid 1px #ddd;*/
/*border-right: solid 2px #ddd;*/
}
\ No newline at end of file
/**
* bootstrap-table - An extended table to integration with some of the most widely used CSS frameworks. (Supports Bootstrap, Semantic UI, Bulma, Material Design, Foundation)
*
* @version v1.15.5
* @homepage https://bootstrap-table.com
* @author wenzhixin <wenzhixin2010@gmail.com> (http://wenzhixin.net.cn/)
* @license MIT
*/
!function(t,n){"object"==typeof exports&&"undefined"!=typeof module?n(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],n):n((t=t||self).jQuery)}(this,(function(t){"use strict";t=t&&t.hasOwnProperty("default")?t.default:t;var n="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function r(t,n){return t(n={exports:{}},n.exports),n.exports}var e,o,u,i,f="object",c=function(t){return t&&t.Math==Math&&t},a=c(typeof globalThis==f&&globalThis)||c(typeof window==f&&window)||c(typeof self==f&&self)||c(typeof n==f&&n)||Function("return this")(),l=function(t){try{return!!t()}catch(t){return!0}},s=!l((function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})),p={}.propertyIsEnumerable,y=Object.getOwnPropertyDescriptor,g={f:y&&!p.call({1:2},1)?function(t){var n=y(this,t);return!!n&&n.enumerable}:p},d=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}},h={}.toString,m=function(t){return h.call(t).slice(8,-1)},v="".split,b=l((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==m(t)?v.call(t,""):Object(t)}:Object,w=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t},S=function(t){return b(w(t))},O=function(t){return"object"==typeof t?null!==t:"function"==typeof t},P=function(t,n){if(!O(t))return t;var r,e;if(n&&"function"==typeof(r=t.toString)&&!O(e=r.call(t)))return e;if("function"==typeof(r=t.valueOf)&&!O(e=r.call(t)))return e;if(!n&&"function"==typeof(r=t.toString)&&!O(e=r.call(t)))return e;throw TypeError("Can't convert object to primitive value")},T={}.hasOwnProperty,j=function(t,n){return T.call(t,n)},x=a.document,E=O(x)&&O(x.createElement),M=!s&&!l((function(){return 7!=Object.defineProperty((t="div",E?x.createElement(t):{}),"a",{get:function(){return 7}}).a;var t})),A=Object.getOwnPropertyDescriptor,_={f:s?A:function(t,n){if(t=S(t),n=P(n,!0),M)try{return A(t,n)}catch(t){}if(j(t,n))return d(!g.f.call(t,n),t[n])}},C=function(t){if(!O(t))throw TypeError(String(t)+" is not an object");return t},N=Object.defineProperty,R={f:s?N:function(t,n,r){if(C(t),n=P(n,!0),C(r),M)try{return N(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported");return"value"in r&&(t[n]=r.value),t}},k=s?function(t,n,r){return R.f(t,n,d(1,r))}:function(t,n,r){return t[n]=r,t},F=function(t,n){try{k(a,t,n)}catch(r){a[t]=n}return n},I=r((function(t){var n=a["__core-js_shared__"]||F("__core-js_shared__",{});(t.exports=function(t,r){return n[t]||(n[t]=void 0!==r?r:{})})("versions",[]).push({version:"3.1.3",mode:"global",copyright:"© 2019 Denis Pushkarev (zloirock.ru)"})})),L=I("native-function-to-string",Function.toString),z=a.WeakMap,D="function"==typeof z&&/native code/.test(L.call(z)),q=0,B=Math.random(),G=function(t){return"Symbol("+String(void 0===t?"":t)+")_"+(++q+B).toString(36)},W=I("keys"),J={},K=a.WeakMap;if(D){var Q=new K,U=Q.get,V=Q.has,Y=Q.set;e=function(t,n){return Y.call(Q,t,n),n},o=function(t){return U.call(Q,t)||{}},u=function(t){return V.call(Q,t)}}else{var H=W[i="state"]||(W[i]=G(i));J[H]=!0,e=function(t,n){return k(t,H,n),n},o=function(t){return j(t,H)?t[H]:{}},u=function(t){return j(t,H)}}var X,Z={set:e,get:o,has:u,enforce:function(t){return u(t)?o(t):e(t,{})},getterFor:function(t){return function(n){var r;if(!O(n)||(r=o(n)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return r}}},$=r((function(t){var n=Z.get,r=Z.enforce,e=String(L).split("toString");I("inspectSource",(function(t){return L.call(t)})),(t.exports=function(t,n,o,u){var i=!!u&&!!u.unsafe,f=!!u&&!!u.enumerable,c=!!u&&!!u.noTargetGet;"function"==typeof o&&("string"!=typeof n||j(o,"name")||k(o,"name",n),r(o).source=e.join("string"==typeof n?n:"")),t!==a?(i?!c&&t[n]&&(f=!0):delete t[n],f?t[n]=o:k(t,n,o)):f?t[n]=o:F(n,o)})(Function.prototype,"toString",(function(){return"function"==typeof this&&n(this).source||L.call(this)}))})),tt=a,nt=function(t){return"function"==typeof t?t:void 0},rt=Math.ceil,et=Math.floor,ot=function(t){return isNaN(t=+t)?0:(t>0?et:rt)(t)},ut=Math.min,it=function(t){return t>0?ut(ot(t),9007199254740991):0},ft=Math.max,ct=Math.min,at=function(t){return function(n,r,e){var o,u=S(n),i=it(u.length),f=function(t,n){var r=ot(t);return r<0?ft(r+n,0):ct(r,n)}(e,i);if(t&&r!=r){for(;i>f;)if((o=u[f++])!=o)return!0}else for(;i>f;f++)if((t||f in u)&&u[f]===r)return t||f||0;return!t&&-1}},lt={includes:at(!0),indexOf:at(!1)}.indexOf,st=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"].concat("length","prototype"),pt={f:Object.getOwnPropertyNames||function(t){return function(t,n){var r,e=S(t),o=0,u=[];for(r in e)!j(J,r)&&j(e,r)&&u.push(r);for(;n.length>o;)j(e,r=n[o++])&&(~lt(u,r)||u.push(r));return u}(t,st)}},yt={f:Object.getOwnPropertySymbols},gt=function(t,n){return arguments.length<2?nt(tt[t])||nt(a[t]):tt[t]&&tt[t][n]||a[t]&&a[t][n]}("Reflect","ownKeys")||function(t){var n=pt.f(C(t)),r=yt.f;return r?n.concat(r(t)):n},dt=function(t,n){for(var r=gt(n),e=R.f,o=_.f,u=0;u<r.length;u++){var i=r[u];j(t,i)||e(t,i,o(n,i))}},ht=/#|\.prototype\./,mt=function(t,n){var r=bt[vt(t)];return r==St||r!=wt&&("function"==typeof n?l(n):!!n)},vt=mt.normalize=function(t){return String(t).replace(ht,".").toLowerCase()},bt=mt.data={},wt=mt.NATIVE="N",St=mt.POLYFILL="P",Ot=mt,Pt=_.f,Tt=Array.isArray||function(t){return"Array"==m(t)},jt=function(t){return Object(w(t))},xt=function(t,n,r){var e=P(n);e in t?R.f(t,e,d(0,r)):t[e]=r},Et=!!Object.getOwnPropertySymbols&&!l((function(){return!String(Symbol())})),Mt=a.Symbol,At=I("wks"),_t=function(t){return At[t]||(At[t]=Et&&Mt[t]||(Et?Mt:G)("Symbol."+t))},Ct=_t("species"),Nt=function(t,n){var r;return Tt(t)&&("function"!=typeof(r=t.constructor)||r!==Array&&!Tt(r.prototype)?O(r)&&null===(r=r[Ct])&&(r=void 0):r=void 0),new(void 0===r?Array:r)(0===n?0:n)},Rt=_t("species"),kt=_t("isConcatSpreadable"),Ft=!l((function(){var t=[];return t[kt]=!1,t.concat()[0]!==t})),It=(X="concat",!l((function(){var t=[];return(t.constructor={})[Rt]=function(){return{foo:1}},1!==t[X](Boolean).foo}))),Lt=function(t){if(!O(t))return!1;var n=t[kt];return void 0!==n?!!n:Tt(t)};!function(t,n){var r,e,o,u,i,f=t.target,c=t.global,l=t.stat;if(r=c?a:l?a[f]||F(f,{}):(a[f]||{}).prototype)for(e in n){if(u=n[e],o=t.noTargetGet?(i=Pt(r,e))&&i.value:r[e],!Ot(c?e:f+(l?".":"#")+e,t.forced)&&void 0!==o){if(typeof u==typeof o)continue;dt(u,o)}(t.sham||o&&o.sham)&&k(u,"sham",!0),$(r,e,u,t)}}({target:"Array",proto:!0,forced:!Ft||!It},{concat:function(t){var n,r,e,o,u,i=jt(this),f=Nt(i,0),c=0;for(n=-1,e=arguments.length;n<e;n++)if(u=-1===n?i:arguments[n],Lt(u)){if(c+(o=it(u.length))>9007199254740991)throw TypeError("Maximum allowed index exceeded");for(r=0;r<o;r++,c++)r in u&&xt(f,c,u[r])}else{if(c>=9007199254740991)throw TypeError("Maximum allowed index exceeded");xt(f,c++,u)}return f.length=c,f}}),t.fn.bootstrapTable.locales["zh-CN"]={formatLoadingMessage:function(){return"正在努力地加载数据中,请稍候"},formatRecordsPerPage:function(t){return"每页显示 ".concat(t," 条记录")},formatShowingRows:function(t,n,r,e){return void 0!==e&&e>0&&e>r?"显示第 ".concat(t," 到第 ").concat(n," 条记录,总共 ").concat(r," 条记录(从 ").concat(e," 总记录中过滤)"):"显示第 ".concat(t," 到第 ").concat(n," 条记录,总共 ").concat(r," 条记录")},formatSRPaginationPreText:function(){return"上一页"},formatSRPaginationPageText:function(t){return"第".concat(t,"页")},formatSRPaginationNextText:function(){return"下一页"},formatDetailPagination:function(t){return"总共 ".concat(t," 条记录")},formatClearSearch:function(){return"清空过滤"},formatSearch:function(){return"搜索"},formatNoMatches:function(){return"没有找到匹配的记录"},formatPaginationSwitch:function(){return"隐藏/显示分页"},formatPaginationSwitchDown:function(){return"显示分页"},formatPaginationSwitchUp:function(){return"隐藏分页"},formatRefresh:function(){return"刷新"},formatToggle:function(){return"切换"},formatToggleOn:function(){return"显示卡片视图"},formatToggleOff:function(){return"隐藏卡片视图"},formatColumns:function(){return"列"},formatColumnsToggleAll:function(){return"切换所有"},formatFullscreen:function(){return"全屏"},formatAllRows:function(){return"所有"},formatAutoRefresh:function(){return"自动刷新"},formatExport:function(){return"导出数据"},formatJumpTo:function(){return"跳转"},formatAdvancedSearch:function(){return"高级搜索"},formatAdvancedCloseButton:function(){return"关闭"}},t.extend(t.fn.bootstrapTable.defaults,t.fn.bootstrapTable.locales["zh-CN"])}));
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.
require('../../js/transition.js')
require('../../js/alert.js')
require('../../js/button.js')
require('../../js/carousel.js')
require('../../js/collapse.js')
require('../../js/dropdown.js')
require('../../js/modal.js')
require('../../js/tooltip.js')
require('../../js/popover.js')
require('../../js/scrollspy.js')
require('../../js/tab.js')
require('../../js/affix.js')
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
function addScript(url){
document.write("<script language=javascript src='/static/august/js/jquery/jquery-min-1-9-1.js'></script>");
}
function js_modify_config(json_order_str){
let json_config_str = JSON.stringify(json_order_str);
// console.log('js_modify_config:' + json_config_str);
let filter_data= {'value': json_config_str};
$.get("/handle_modify_config",filter_data, function(result){
// console.log('js handle_modify_config() result = ' + result);
if(result.result === "None")
{
alert("修改订单失败,订单内容不能为空,请再次确认");
}
$("#table_page").bootstrapTable('refresh');
});
}
function js_delete_config(json_order_str){
// console.log('js_delete_config:' + json_order_str);
let filter_data= {'value': json_order_str};
$.get("/delete_config",filter_data, function(result){
// console.log('js delete_config() result = ' + result);
if(result.result === "Fail")
{
alert("当前订单正在使用,不可删除");
}
else if(result.result === "Success")
{
alert("订单删除成功");
}
else if(result.result === "None")
{
alert("订单不存在,请刷新页面");
}
$("#table_page").bootstrapTable('refresh');
});
}
\ No newline at end of file
function addScript(url){
document.write("<script language=javascript src='/static/august/js/jquery/jquery-1.4.2.js'></script>");
document.write("<script language=javascript src='/static/august/js/socket_io_min_1.3.5.js'></script>");
document.write("<script language=javascript src='/static/august/js/jquery/jquery-3.1.1.js'></script>");
document.write("<script language=javascript src='/static/august/js/socket_io_min_1.5.1.js'></script>");
// document.write("<script language=javascript src='/static/august/js/bootstrap-table.js'></script>");
// document.write("<script language=javascript src='/static/august/js/bootstrap-table-zh-CN.js'></script>");
}
function addScript(url){
document.write("<script language='JavaScript' src='/static/august/js/jquery/jquery-min-1-9-1.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/jquery/jquery-1.4.2.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/jquery/jquery-3.1.1.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/socket_io_min_1.5.1.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/bootstrap/js/bootstrap.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/socket_io_min_1.3.5.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/bootstrap-table.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/bootstrap-table-zh-CN.js'></script>");
document.write("<script language='JavaScript' src='/static/august/js/user/user_custom.js'></script>");
document.write("<link rel='stylesheet' href='/static/august/css/table.css'>");
document.write("<link rel='stylesheet' href='/static/august/css/bootstrap-min.css'>");
document.write("<link rel='stylesheet' href='/static/august/css/bootstrap-table.css'>");
document.write("<link rel='stylesheet' href='/static/august/js/bootstrap/css/bootstrap.css'>");
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Not Found</title>
</head>
<body>
<h1>Can't find request page!</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>test</title>
<link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}">
</head>
<body>
<div id="test_window">
<h1>只是个页面</h1>
</div>
</body>
</html>
import os
working_dir = os.path.abspath(os.path.dirname(__file__))
content_dir = os.path.abspath(os.path.dirname(os.getcwd()))
button_to_send_stop_cmd = False
class config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'this is a secret string'
SQLALCHEMY_TRACK_MODIFICATIONS = True
@staticmethod
def init_app(app):
pass
class DevelopmentConfig(config):
DEBUG = True
# SQL_ALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL') or 'sqlite:///' + os.path.join(basedir, 'dev')
SQLALCHEMY_DATABASE_URI = \
'mysql+pymysql://root:-6J4MGDj4M_S_3b@localhost:3306/DTU00020_Database'
class TestingConfig(config):
TESTING = True
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@106.53.68.252:3306/AM100050_Database'
class ProductionConfig(config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:root@106.53.68.252:3306/AM100050_Database'
config = {
'development': DevelopmentConfig,
'testing': TestingConfig,
'production': ProductionConfig,
'default': DevelopmentConfig
}
from app import app, create_app, db
from flask import Flask
from flask_script import Manager, Shell
from flask_migrate import Migrate, MigrateCommand
app = create_app('development')
manager = Manager(app)
migrate = Migrate(app, db)
def make_shell_context():
return dict(app=app, db=db)
manager.add_command("shell", Shell(make_context=make_shell_context))
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
port = 5000
Flask.run(app, debug=False, host="0.0.0.0", port=port)
alembic==1.4.3
altgraph==0.17
appdirs==1.4.4
asgiref==3.3.1
asyncio==3.4.3
bsdiff4==1.1.5
certifi==2020.11.8
chardet==3.0.4
click==7.1.2
Django==3.1.3
dsdev-utils==1.0.4
ed25519==1.5
evdev==1.3.0
Flask==1.1.2
Flask-Migrate==2.5.3
Flask-Script==2.0.6
Flask-SocketIO==4.3.1
Flask-SQLAlchemy==2.4.4
idna==2.10
image==1.5.33
itsdangerous==1.1.0
Jinja2==2.11.2
Mako==1.1.3
MarkupSafe==1.1.1
paho-mqtt==1.5.1
pbr==5.5.1
pexpect==4.8.0
Pillow==8.0.1
ptyprocess==0.6.0
pyinstaller==4.1
pyinstaller-hooks-contrib==2020.10
PyMySQL==0.10.1
python-dateutil==2.8.1
python-editor==1.0.4
python-engineio==3.13.2
python-socketio==4.6.0
pytz==2020.4
PyUpdater==3.1.1
requests==2.25.0
RPi.GPIO==0.7.0
six==1.15.0
SQLAlchemy==1.3.20
sqlparse==0.4.1
stevedore==1.32.0
urllib3==1.26.2
Werkzeug==1.0.1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment