Selaa lähdekoodia

second commit

Benson 3 vuotta sitten
vanhempi
commit
1a8fe39839
100 muutettua tiedostoa jossa 13761 lisäystä ja 0 poistoa
  1. 8 0
      CoffeeProject/.idea/.gitignore
  2. 21 0
      CoffeeProject/.idea/Coffee Project.iml
  3. 4 0
      CoffeeProject/.idea/encodings.xml
  4. 6 0
      CoffeeProject/.idea/inspectionProfiles/profiles_settings.xml
  5. 10 0
      CoffeeProject/.idea/misc.xml
  6. 8 0
      CoffeeProject/.idea/modules.xml
  7. BIN
      CoffeeProject/__pycache__/coffee_manage.cpython-35.pyc
  8. 292 0
      CoffeeProject/app/__init__.py
  9. BIN
      CoffeeProject/app/__pycache__/__init__.cpython-35.pyc
  10. BIN
      CoffeeProject/app/__pycache__/__init__.cpython-36.pyc
  11. BIN
      CoffeeProject/app/__pycache__/models.cpython-35.pyc
  12. BIN
      CoffeeProject/app/__pycache__/models.cpython-36.pyc
  13. 5 0
      CoffeeProject/app/main/__init__.py
  14. BIN
      CoffeeProject/app/main/__pycache__/__init__.cpython-35.pyc
  15. BIN
      CoffeeProject/app/main/__pycache__/__init__.cpython-36.pyc
  16. BIN
      CoffeeProject/app/main/__pycache__/mqtt.cpython-35.pyc
  17. BIN
      CoffeeProject/app/main/__pycache__/views.cpython-35.pyc
  18. BIN
      CoffeeProject/app/main/__pycache__/views.cpython-36.pyc
  19. 133 0
      CoffeeProject/app/main/mqtt.py
  20. 1700 0
      CoffeeProject/app/main/views.py
  21. 274 0
      CoffeeProject/app/models.py
  22. 112 0
      CoffeeProject/app/static/css/registration.css
  23. 103 0
      CoffeeProject/app/static/css/reset_pwd1.css
  24. 106 0
      CoffeeProject/app/static/css/reset_pwd2.css
  25. 116 0
      CoffeeProject/app/static/css/sign_in.css
  26. BIN
      CoffeeProject/app/static/img/PV.jpg
  27. BIN
      CoffeeProject/app/static/img/coffee.jpg
  28. 100 0
      CoffeeProject/app/static/js/registration.js
  29. 3 0
      CoffeeProject/app/static/js/reset_pwd1.js
  30. 3 0
      CoffeeProject/app/static/js/reset_pwd2.js
  31. 3 0
      CoffeeProject/app/static/js/sign_in.js
  32. 236 0
      CoffeeProject/app/templates/cargo1.html
  33. 1592 0
      CoffeeProject/app/templates/cargo1_schedule.html
  34. 236 0
      CoffeeProject/app/templates/cargo2.html
  35. 1167 0
      CoffeeProject/app/templates/cargo2_actuator.html
  36. 279 0
      CoffeeProject/app/templates/cargo2_actuator_tanks.html
  37. 1597 0
      CoffeeProject/app/templates/cargo2_schedule.html
  38. 279 0
      CoffeeProject/app/templates/cargo2_schedule_tanks.html
  39. 714 0
      CoffeeProject/app/templates/cargo2_sensor.html
  40. 279 0
      CoffeeProject/app/templates/cargo2_sensor_tanks.html
  41. 236 0
      CoffeeProject/app/templates/cargo3.html
  42. 801 0
      CoffeeProject/app/templates/cargo3_schedule.html
  43. 232 0
      CoffeeProject/app/templates/cargo_list.html
  44. 246 0
      CoffeeProject/app/templates/index.html
  45. 229 0
      CoffeeProject/app/templates/learn.html
  46. 96 0
      CoffeeProject/app/templates/registration.html
  47. 66 0
      CoffeeProject/app/templates/reset_pwd1.html
  48. 72 0
      CoffeeProject/app/templates/reset_pwd2.html
  49. 72 0
      CoffeeProject/app/templates/sign_in.html
  50. 252 0
      CoffeeProject/app/templates/test1.html
  51. 252 0
      CoffeeProject/app/templates/test3.html
  52. 134 0
      CoffeeProject/app/templates/test5.html
  53. 76 0
      CoffeeProject/app/templates/test6.html
  54. 294 0
      CoffeeProject/app/templates/video.html
  55. 6 0
      CoffeeProject/app/user/__init__.py
  56. BIN
      CoffeeProject/app/user/__pycache__/__init__.cpython-35.pyc
  57. BIN
      CoffeeProject/app/user/__pycache__/__init__.cpython-36.pyc
  58. BIN
      CoffeeProject/app/user/__pycache__/views.cpython-35.pyc
  59. BIN
      CoffeeProject/app/user/__pycache__/views.cpython-36.pyc
  60. 6 0
      CoffeeProject/app/user/views.py
  61. 30 0
      CoffeeProject/coffee_manage.py
  62. 1 0
      CoffeeProject/migrations/README
  63. BIN
      CoffeeProject/migrations/__pycache__/env.cpython-35.pyc
  64. 45 0
      CoffeeProject/migrations/alembic.ini
  65. 96 0
      CoffeeProject/migrations/env.py
  66. 24 0
      CoffeeProject/migrations/script.py.mako
  67. 34 0
      CoffeeProject/migrations/versions/3cd641e789b7_.py
  68. 37 0
      CoffeeProject/migrations/versions/3faa6d09ff44_.py
  69. 28 0
      CoffeeProject/migrations/versions/69d28c0997da_.py
  70. 242 0
      CoffeeProject/migrations/versions/7e912759589c_.py
  71. 30 0
      CoffeeProject/migrations/versions/9f72f41f27ab_.py
  72. BIN
      CoffeeProject/migrations/versions/__pycache__/3cd641e789b7_.cpython-35.pyc
  73. BIN
      CoffeeProject/migrations/versions/__pycache__/3faa6d09ff44_.cpython-35.pyc
  74. BIN
      CoffeeProject/migrations/versions/__pycache__/69d28c0997da_.cpython-35.pyc
  75. BIN
      CoffeeProject/migrations/versions/__pycache__/7e912759589c_.cpython-35.pyc
  76. BIN
      CoffeeProject/migrations/versions/__pycache__/9f72f41f27ab_.cpython-35.pyc
  77. 1 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/INSTALLER
  78. 28 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/LICENSE.rst
  79. 137 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/METADATA
  80. 48 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/RECORD
  81. 6 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/WHEEL
  82. 3 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/entry_points.txt
  83. 1 0
      CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/top_level.txt
  84. 1 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/INSTALLER
  85. 28 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/LICENSE.rst
  86. 106 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/METADATA
  87. 59 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/RECORD
  88. 6 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/WHEEL
  89. 3 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/entry_points.txt
  90. 1 0
      CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/top_level.txt
  91. 1 0
      CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER
  92. 28 0
      CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst
  93. 103 0
      CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/METADATA
  94. 15 0
      CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/RECORD
  95. 5 0
      CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL
  96. 1 0
      CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt
  97. 1 0
      CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/INSTALLER
  98. 28 0
      CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/LICENSE.rst
  99. 128 0
      CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/METADATA
  100. 0 0
      CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/RECORD

+ 8 - 0
CoffeeProject/.idea/.gitignore

@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/

+ 21 - 0
CoffeeProject/.idea/Coffee Project.iml

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module type="PYTHON_MODULE" version="4">
+  <component name="Flask">
+    <option name="enabled" value="true" />
+  </component>
+  <component name="NewModuleRootManager">
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/venv" />
+    </content>
+    <orderEntry type="jdk" jdkName="Python 3.5" jdkType="Python SDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+  <component name="TemplatesService">
+    <option name="TEMPLATE_CONFIGURATION" value="Jinja2" />
+    <option name="TEMPLATE_FOLDERS">
+      <list>
+        <option value="$MODULE_DIR$/../Coffee Project\templates" />
+      </list>
+    </option>
+  </component>
+</module>

+ 4 - 0
CoffeeProject/.idea/encodings.xml

@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="Encoding" addBOMForNewFiles="with NO BOM" />
+</project>

+ 6 - 0
CoffeeProject/.idea/inspectionProfiles/profiles_settings.xml

@@ -0,0 +1,6 @@
+<component name="InspectionProjectProfileManager">
+  <settings>
+    <option name="USE_PROJECT_PROFILE" value="false" />
+    <version value="1.0" />
+  </settings>
+</component>

+ 10 - 0
CoffeeProject/.idea/misc.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+  <component name="ProjectRootManager" version="2" project-jdk-name="Python 3.5" project-jdk-type="Python SDK" />
+  <component name="PyCharmProfessionalAdvertiser">
+    <option name="shown" value="true" />
+  </component>
+</project>

+ 8 - 0
CoffeeProject/.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/Coffee Project.iml" filepath="$PROJECT_DIR$/.idea/Coffee Project.iml" />
+    </modules>
+  </component>
+</project>

BIN
CoffeeProject/__pycache__/coffee_manage.cpython-35.pyc


+ 292 - 0
CoffeeProject/app/__init__.py

@@ -0,0 +1,292 @@
+#對整個應用做初始化操作
+#主要工作:
+# 1.構建Flask的應用以及各種配置
+#2.構建SQLAlchemy的應用
+
+from flask import Flask
+from flask_sqlalchemy import SQLAlchemy
+import pymysql
+import eventlet
+from flask_mqtt import Mqtt
+from flask_migrate import Migrate, MigrateCommand
+
+
+#綠化(綠色線程)所有系統模組,實現IO多路複用
+# eventlet.monkey_patch()
+
+pymysql.install_as_MySQLdb()
+
+# db = SQLAlchemy()
+
+def create_app():
+    app = Flask(__name__)
+    #配置啟動模式為調適模式
+    # app.config['DEBUG'] = True
+    #配置數據庫的連接字符串
+    app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://coffee:skyeye@52.69.200.169:3306/Coffee'
+    #配置數據庫內容再更新時自動提交
+    app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
+    #配置session所需要的秘鑰
+    app.config['SECRET_KEY'] = 'you guess'
+    # template 有修改後,會自動去更新
+    app.config['TEMPLATES_AUTO_RELOAD'] = True
+    #如果设置成True(默认情况),Flask - SQLAlchemy将会追踪对象的修改并且发送信号。这需要额外的内存, 如果不必要的可以禁用它
+    app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True
+    #資料库连接池的大小。默认是数据库引擎的默认值 (通常是5)
+    app.config['SQLALCHEMY_POOL_SIZE'] = 100
+    #指定資料库连接池的超时时间。默认是 10
+    app.config['SQLALCHEMY_POOL_TIMEOUT'] = 60 * 60
+    #自动回收连接的秒数。这对 MySQL 是必须的,默认 情况下 MySQL 会自动移除闲置 8 小时或者以上的连接。 需要注意地是如果使用 MySQL 的话, Flask-SQLAlchemy 会自动地设置这个值为 2 小时
+    app.config['SQLALCHEMY_MAX_OVERFLOW'] = 15
+
+    # app.config['SECRET'] = 'my secret key'
+    #MQTT相關設置
+    app.config['MQTT_BROKER_URL'] = '60.250.156.234'
+    app.config['MQTT_BROKER_PORT'] = 1883
+    app.config['MQTT_USERNAME'] = 'aisky-client'
+    app.config['MQTT_PASSWORD'] = 'aiskyc'
+    #將發送ping到代理的時間間隔設置60秒
+    app.config['MQTT_KEEPALIVE'] = 60
+    #出於測試目的將TLS設置為禁用
+    app.config['MQTT_TLS_ENABLED'] = False
+
+    #資料庫的初始化
+    db = SQLAlchemy(app)
+    db.init_app(app)
+    mqtt = Mqtt(app)
+
+    # 初始化Flask-Migrate擴展
+    migrate = Migrate(app, db)
+
+
+
+    #用來使用flask-migrate數據遷移使用,如要用在把下面模型類註釋消掉,並且將main裡的from coffee_manage import mqtt,db註釋掉(因會報導入錯誤)
+    # # 用戶表
+    # class User(db.Model):
+    #     __tablename__ = 'user'
+    #
+    #     userID = db.Column(db.Integer, primary_key=True)
+    #     firstname = db.Column(db.String(30), nullable=False)
+    #     lastname = db.Column(db.String(30), nullable=False)
+    #     mail = db.Column(db.String(50), nullable=False)
+    #     phone = db.Column(db.String(20), nullable=False)
+    #     username = db.Column(db.String(30), nullable=False, unique=True)
+    #     password = db.Column(db.String(40), nullable=False)
+    #     status = db.Column(db.Integer, nullable=False, info='0:admin;1:new;9:disable')
+    #
+    # # 發酵槽溫度感測器表
+    # class TankTemSensor(db.Model):
+    #     __tablename__ = 'tank_tem_sensor'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     tem = db.Column(db.Text, nullable=False)
+    #
+    # # 發酵槽二氧化碳感測器表
+    # class TankCO2Sensor(db.Model):
+    #     __tablename__ = 'tank_co2_sensor'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     co2 = db.Column(db.Text, nullable=False)
+    #
+    # # 發酵槽酸鹼值感測器表
+    # class TankPHSensor(db.Model):
+    #     __tablename__ = 'tank_ph_sensor'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     ph = db.Column(db.Text, nullable=False)
+    #
+    # class BeanValve(db.Model):
+    #     __tablename__ = 'bean_valve'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class WashMachine(db.Model):
+    #     __tablename__ = 'wash_machine'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ConveyorBelt1(db.Model):
+    #     __tablename__ = 'conveyor_belt1'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Cargo1Disinfect(db.Model):
+    #     __tablename__ = 'cargo1_disinfect'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ColorMachine(db.Model):
+    #     __tablename__ = 'color_machine'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ConveyorBelt2(db.Model):
+    #     __tablename__ = 'conveyor_belt2'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class PeelingMachine(db.Model):
+    #     __tablename__ = 'peeling_machine'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class ConveyorBelt3(db.Model):
+    #     __tablename__ = 'conveyor_belt3'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Bacteria(db.Model):
+    #     __tablename__ = 'bacteria'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Cargo2Disinfect(db.Model):
+    #     __tablename__ = 'cargo2_disinfect'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Heating(db.Model):
+    #     __tablename__ = 'heating'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Stir(db.Model):
+    #     __tablename__ = 'stir'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class WaterInjection(db.Model):
+    #     __tablename__ = 'water_injection'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class TopValve(db.Model):
+    #     __tablename__ = 'top_valve'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class BottomValve(db.Model):
+    #     __tablename__ = 'bottom_valve'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Temperature(db.Model):
+    #     __tablename__ = 'temperature'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Hoist(db.Model):
+    #     __tablename__ = 'hoist'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Dryer(db.Model):
+    #     __tablename__ = 'dryer'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     duration = db.Column(db.Text, nullable=False)
+    #     start = db.Column(db.Text, nullable=False)
+    #     end = db.Column(db.Text, nullable=False)
+    #
+    # class Relay(db.Model):
+    #     __tablename__ = 'relay'
+    #
+    #     sn = db.Column(db.Integer, primary_key=True)
+    #     datetime = db.Column(db.DateTime, nullable=False)
+    #     tank_num = db.Column(db.Integer, nullable=False)
+    #     status = db.Column(db.Text, nullable=False)
+
+
+
+
+    #將main藍圖程序與app關聯到一起
+    from .main import main as main_blueprint
+    app.register_blueprint(main_blueprint)
+    #將user藍圖程序與app關聯到一起
+    from .user import user as user_blueprint
+    app.register_blueprint(user_blueprint)
+
+    return app, db, mqtt

BIN
CoffeeProject/app/__pycache__/__init__.cpython-35.pyc


BIN
CoffeeProject/app/__pycache__/__init__.cpython-36.pyc


BIN
CoffeeProject/app/__pycache__/models.cpython-35.pyc


BIN
CoffeeProject/app/__pycache__/models.cpython-36.pyc


+ 5 - 0
CoffeeProject/app/main/__init__.py

@@ -0,0 +1,5 @@
+#main 目錄: 包含主要的業務邏輯的路由和視圖
+# __init__.py : 對主業務邏輯程序的初始化操作
+from flask import Blueprint
+main = Blueprint('main',__name__)
+from . import views

BIN
CoffeeProject/app/main/__pycache__/__init__.cpython-35.pyc


BIN
CoffeeProject/app/main/__pycache__/__init__.cpython-36.pyc


BIN
CoffeeProject/app/main/__pycache__/mqtt.cpython-35.pyc


BIN
CoffeeProject/app/main/__pycache__/views.cpython-35.pyc


BIN
CoffeeProject/app/main/__pycache__/views.cpython-36.pyc


+ 133 - 0
CoffeeProject/app/main/mqtt.py

@@ -0,0 +1,133 @@
+import pymysql
+import paho.mqtt.client as mqtt
+import json
+import threading
+from time import sleep as sl
+from datetime import datetime as dt
+from concurrent.futures import ThreadPoolExecutor
+
+
+class MQTT(object):
+    # def __init__(self, username, password, ip, port, time, sub_topic):
+    #     self.client = mqtt.Client()
+    #     self.pool = ThreadPoolExecutor(10)
+    #     self.username = username
+    #     self.password = password
+    #     self.ip = ip
+    #     self.port = port
+    #     self.time = time
+    #     self.sub_topic = sub_topic
+    #     self.D = {}
+    #     for i in range(0, len(self.sub_topic)):
+    #         self.D[self.sub_topic] = 0
+    #     self.res = 0
+    def __init__(self):
+        self.res = 0
+        # 當地端程式連線伺服器得到回應時,要做的動作
+        def on_connect(client, userdata, flags, rc):
+            # print("Waiting for MQTT message...")
+            # 將訂閱主題寫在on_connet中
+            # 如果我們失去連線或重新連線時
+            # 地端程式將會重新訂閱
+            # 判斷是否為元祖,有多個訂閱主題
+            # if isinstance(self.sub_topic, tuple):
+            #     for i in range(0, len(self.sub_topic)):
+            #         client.subscribe(self.sub_topic[i])
+            # client.subscribe(self.sub_topic)
+            client.subscribe('AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e/Log')
+
+        # 當接收到從伺服器發送的訊息時要進行的動作
+        def on_message(client, userdata, msg):
+            msg = msg
+
+            payload = json.loads(msg.payload.decode('utf-8'))
+            self.res = payload
+            print(payload)
+            # if payload:
+            #     self.D[self.sub_topic] = 1
+            #     self.res = payload
+
+        self.client = mqtt.Client()
+        self.command = {'tank-number':'1', 'command':'butterfly-valve', 'value':'on'}
+
+        def thread_job(self):
+            self.client.on_connect = on_connect
+            # 設定接收訊息的動作
+            self.client.on_message = on_message
+            # 設定登入帳號密碼
+            self.client.username_pw_set("aisky-client", "aiskyc")
+            # self.client.username_pw_set(self.username, self.password)
+            # 設定連線資訊(IP, Port, 連線時間)
+            self.client.connect("60.250.156.234", 1883, 60)
+            # self.client.connect(self.ip, self.port, self.time)
+            # 開始連線,執行設定的動作和處理重新連線問題
+            # 也可以手動使用其他loop函式來進行連接
+            self.client.loop_forever()
+
+        mqtt_subscribe_thread = threading.Thread(target=thread_job, args=(self,))
+        mqtt_subscribe_thread.daemon = True
+        mqtt_subscribe_thread.start()
+        # 睡1秒等執行敘跑完才跑主程式
+        sl(1)
+        # while True:
+        #     pass
+
+    def mqttPublish(self, topic, command):
+        self.client.publish(topic, json.dumps(command))
+        # print('done')
+        return True
+        # while True:
+        #     if self.D[self.sub_topic] == 1:
+        #         return self.res
+
+
+    # def workOn(self):
+    #     self = self
+
+
+
+
+
+
+    # def thread_job(self):
+    #     # 設定連線的動作
+    #     self.client.on_connect = on_connect
+    #     # 設定接收訊息的動作
+    #     self.client.on_message = on_message
+    #     # 設定登入帳號密碼
+    #     self.client.username_pw_set("aisky-client", "aiskyc")
+    #     # self.client.username_pw_set(self.username, self.password)
+    #     # 設定連線資訊(IP, Port, 連線時間)
+    #     self.client.connect("60.250.156.234", 1883, 60)
+    #     # self.client.connect(self.ip, self.port, self.time)
+    #     # 開始連線,執行設定的動作和處理重新連線問題
+    #     # 也可以手動使用其他loop函式來進行連接
+    #     self.client.loop_forever()
+    #
+    #     mqtt_subscribe_thread = threading.Thread(target=thread_job, args=(self,))
+    #     mqtt_subscribe_thread.daemon = True
+    #     mqtt_subscribe_thread.start()
+    #     # 睡1秒等執行敘跑完才跑主程式
+    #     sl(1)
+        # return "success"
+        # self.queryMySQL()
+        # self.cursor.close()
+        # self.db.close()
+        # self.pool.shutdown(wait=True)
+        # self.mqttPublish('AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e', self.command)
+        # while True:
+        #     pass
+
+
+if __name__ == '__main__':
+    mqtt = MQTT()
+    try:
+        # mqtt.workOn()
+        mqtt.mqttPublish('AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e', mqtt.command)
+        print('test')
+        while True:
+            pass
+    except KeyboardInterrupt:
+        mqtt.pool.shutdown(wait=True)
+        mqtt.cursor.close()
+        mqtt.db.close()

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1700 - 0
CoffeeProject/app/main/views.py


+ 274 - 0
CoffeeProject/app/models.py

@@ -0,0 +1,274 @@
+# coding: utf-8
+from sqlalchemy import Column, Date, DateTime, Float, Index, Integer, String, Text
+from sqlalchemy.schema import FetchedValue
+from flask_sqlalchemy import SQLAlchemy
+
+
+# db = SQLAlchemy()
+
+#與當前項目相關的模型文件,即所有的實體類在此編寫
+from coffee_manage import db
+
+#用戶表
+class User(db.Model):
+    __tablename__ = 'user'
+
+    userID = db.Column(db.Integer, primary_key=True)
+    firstname = db.Column(db.String(30), nullable=False)
+    lastname = db.Column(db.String(30), nullable=False)
+    mail = db.Column(db.String(50), nullable=False)
+    phone = db.Column(db.String(20), nullable=False)
+    username = db.Column(db.String(30), nullable=False, unique=True)
+    password = db.Column(db.String(40), nullable=False)
+    status = db.Column(db.Integer, nullable=False, info='0:admin;1:new;9:disable')
+
+#發酵槽溫度感測器表
+class TankTemSensor(db.Model):
+    __tablename__ = 'tank_tem_sensor'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    tem = db.Column(db.Text, nullable=False)
+
+#發酵槽二氧化碳感測器表
+class TankCO2Sensor(db.Model):
+    __tablename__ = 'tank_co2_sensor'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    co2 = db.Column(db.Text, nullable=False)
+
+#發酵槽酸鹼值感測器表
+class TankPHSensor(db.Model):
+    __tablename__ = 'tank_ph_sensor'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    ph = db.Column(db.Text, nullable=False)
+
+#發酵槽酸鹼值感測器表
+class TankECSensor(db.Model):
+    __tablename__ = 'tank_ec_sensor'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    ec = db.Column(db.Text, nullable=False)
+
+#發酵槽超音波感測器表
+class TankSonicSensor(db.Model):
+    __tablename__ = 'tank_sonic_sensor'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    sonic = db.Column(db.Text, nullable=False)
+
+
+class BeanValve(db.Model):
+    __tablename__ = 'bean_valve'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class WashMachine(db.Model):
+    __tablename__ = 'wash_machine'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class ConveyorBelt1(db.Model):
+    __tablename__ = 'conveyor_belt1'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Cargo1Disinfect(db.Model):
+    __tablename__ = 'cargo1_disinfect'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class ColorMachine(db.Model):
+    __tablename__ = 'color_machine'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class ConveyorBelt2(db.Model):
+    __tablename__ = 'conveyor_belt2'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class PeelingMachine(db.Model):
+    __tablename__ = 'peeling_machine'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+
+
+class ConveyorBelt3(db.Model):
+    __tablename__ = 'conveyor_belt3'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+
+
+class Bacteria(db.Model):
+    __tablename__ = 'bacteria'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Cargo2Disinfect(db.Model):
+    __tablename__ = 'cargo2_disinfect'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Heating(db.Model):
+    __tablename__ = 'heating'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Stir(db.Model):
+    __tablename__ = 'stir'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class WaterInjection(db.Model):
+    __tablename__ = 'water_injection'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+
+
+class TopValve(db.Model):
+    __tablename__ = 'top_valve'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class BottomValve(db.Model):
+    __tablename__ = 'bottom_valve'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Temperature(db.Model):
+    __tablename__ = 'temperature'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Hoist(db.Model):
+    __tablename__ = 'hoist'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Dryer(db.Model):
+    __tablename__ = 'dryer'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    duration = db.Column(db.Text, nullable=False)
+    start = db.Column(db.Text, nullable=False)
+    end = db.Column(db.Text, nullable=False)
+
+class Relay(db.Model):
+    __tablename__ = 'relay'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    status= db.Column(db.Text, nullable=False)
+
+
+class PeelingMachineRPM(db.Model):
+    __tablename__ = 'peeling_machine_rpm'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    rpm = db.Column(db.Text, nullable=False)
+
+class StirRPM(db.Model):
+    __tablename__ = 'stir_rpm'
+
+    sn = db.Column(db.Integer, primary_key=True)
+    datetime = db.Column(db.DateTime, nullable=False)
+    tank_num = db.Column(db.Integer, nullable=False)
+    rpm = db.Column(db.Text, nullable=False)
+
+
+
+db.create_all()

+ 112 - 0
CoffeeProject/app/static/css/registration.css

@@ -0,0 +1,112 @@
+        .img-fluid {
+            margin-top: 50px;
+        }
+
+        .text-center {
+            margin-top: 50px;
+        }
+
+        form {
+            margin-top: 50px;
+        }
+
+        form > div:last-child {
+            margin-top: 40px;
+        }
+
+        form > div:last-child input:last-child {
+            margin-left: 120px;
+        }
+
+        .btn-info {
+            width: 105px;
+            height: 43px;
+            background: #85BF31;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            color: #000000;
+        }
+
+        .wrong-info {
+            height: 20px;
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 14px;
+            color: #FF0505;
+        }
+
+        @media(max-width:373px){
+            .col-2 {
+                display: none;
+            }
+        }
+
+        @media(max-width:577px){
+            form > div:last-child input:last-child {
+                margin-left: 0px;
+            }
+        }
+
+        @media(min-width:576px){
+
+        }
+
+         @media(min-width:768px){
+            .form-inline {
+                margin-left: 60px;
+            }
+            form > div:last-child {
+                margin-left: 60px;
+            }
+            .wrong-info {
+                margin-left: 50px;
+            }
+            #first {
+                margin-left: 70px;
+            }
+            #last {
+                margin-left: 71px;
+            }
+            #email {
+                margin-left: 108px;
+            }
+            #phone {
+                margin-left: 103px;
+            }
+            #usr {
+                margin-left: 68px;
+            }
+            #pwd {
+                margin-left: 81px;
+            }
+            #cpwd {
+                margin-left: 22px;
+            }
+
+         }
+
+         @media(min-width:991px){
+            .form-inline {
+                margin-left: 140px;
+            }
+            form > div:last-child {
+                margin-left: 150px;
+            }
+            .wrong-info {
+                margin-left: 140px;
+            }
+         }
+
+         @media(min-width:1200px){
+            .form-inline {
+                margin-left: 180px;
+            }
+             form > div:last-child {
+                margin-left: 190px;
+            }
+            .wrong-info {
+                margin-left: 170px;
+            }
+         }

+ 103 - 0
CoffeeProject/app/static/css/reset_pwd1.css

@@ -0,0 +1,103 @@
+        .img-fluid {
+            margin-top: 50px;
+        }
+
+        h1 {
+            margin-top: 30px;
+        }
+
+        .descripe {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 18px;
+            line-height: 21px;
+        }
+
+        form {
+            margin-top: 50px;
+        }
+
+        form > div:last-child {
+            margin-top: 40px;
+        }
+
+        form > div:last-child input:last-child {
+            margin-left: 100px;
+        }
+
+        .btn-info {
+            width: 105px;
+            height: 43px;
+            background: #85BF31;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            color: #000000;
+        }
+
+        .wrong-info {
+            height: 20px;
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 14px;
+            color: #FF0505;
+        }
+
+        @media(max-width:373px){
+            .col-2 {
+                display: none;
+            }
+        }
+
+        @media(max-width:577px){
+            form > div:last-child input:last-child {
+                margin-left: 0px;
+            }
+        }
+
+        @media(min-width:576px){
+            #email {
+                margin-left: 70px;
+            }
+            .form div:not(:first-child) {
+                margin-top: 20px;
+            }
+
+        }
+         @media(min-width:768px){
+            .form-inline {
+                margin-left: 50px;
+            }
+            form > div:last-child {
+                margin-left: 60px;
+            }
+            .wrong-info {
+                margin-left: 50px;
+            }
+         }
+
+         @media(min-width:991px){
+            .form-inline {
+                margin-left: 140px;
+            }
+            form > div:last-child {
+                margin-left: 150px;
+            }
+            .wrong-info {
+                margin-left: 140px;
+            }
+         }
+
+         @media(min-width:1200px){
+            .form-inline {
+                margin-left: 180px;
+            }
+             form > div:last-child {
+                margin-left: 190px;
+            }
+            .wrong-info {
+                margin-left: 170px;
+            }
+         }

+ 106 - 0
CoffeeProject/app/static/css/reset_pwd2.css

@@ -0,0 +1,106 @@
+        .img-fluid {
+            margin-top: 50px;
+        }
+
+        h1 {
+            margin-top: 30px;
+        }
+
+        .descripe {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 18px;
+            line-height: 21px;
+        }
+
+        form {
+            margin-top: 50px;
+        }
+
+        form > div:last-child {
+            margin-top: 40px;
+        }
+
+        form > div:last-child input:last-child {
+            margin-left: 100px;
+        }
+
+        .btn-info {
+            width: 105px;
+            height: 43px;
+            background: #85BF31;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            color: #000000;
+        }
+
+        .wrong-info {
+            height: 20px;
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 14px;
+            color: #FF0505;
+        }
+
+        @media(max-width:373px){
+            .col-2 {
+                display: none;
+            }
+        }
+
+        @media(max-width:577px){
+            form > div:last-child input:last-child {
+                margin-left: 0px;
+            }
+        }
+
+        @media(min-width:576px){
+            #new-pwd {
+                margin-left: 70px;
+            }
+            #confirm-pwd {
+                margin-left: 46px;
+            }
+            .form div:not(:first-child) {
+                margin-top: 20px;
+            }
+
+        }
+         @media(min-width:768px){
+            .form-inline {
+                margin-left: 50px;
+            }
+            form > div:last-child {
+                margin-left: 60px;
+            }
+            .wrong-info {
+                margin-left: 50px;
+            }
+         }
+
+         @media(min-width:991px){
+            .form-inline {
+                margin-left: 140px;
+            }
+            form > div:last-child {
+                margin-left: 150px;
+            }
+            .wrong-info {
+                margin-left: 140px;
+            }
+         }
+
+         @media(min-width:1200px){
+            .form-inline {
+                margin-left: 180px;
+            }
+             form > div:last-child {
+                margin-left: 190px;
+            }
+            .wrong-info {
+                margin-left: 170px;
+            }
+         }

+ 116 - 0
CoffeeProject/app/static/css/sign_in.css

@@ -0,0 +1,116 @@
+        .img-fluid {
+            margin-top: 50px;
+        }
+
+        .text-center {
+            margin-top: 30px;
+        }
+
+        form {
+            margin-top: 50px;
+        }
+
+         .radio a {
+            text-decoration: none;
+            margin-left: 75px;
+        }
+
+        form > div:last-child {
+            margin-top: 40px;
+        }
+
+        form > div:last-child input:last-child {
+            margin-left: 100px;
+        }
+
+        .btn-info {
+            width: 105px;
+            height: 43px;
+            background: #85BF31;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            color: #000000;
+        }
+
+        .wrong-info {
+            height: 20px;
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 14px;
+            color: #FF0505;
+        }
+
+        @media(max-width:373px){
+            .col-2 {
+                display: none;
+            }
+        }
+
+        @media(max-width:577px){
+            .radio a {
+                margin-left: 0px;
+                display: block;
+            }
+            form > div:last-child input:last-child {
+                margin-left: 0px;
+            }
+        }
+
+        @media(min-width:576px){
+            #usr {
+                margin-left: 70px;
+            }
+            #pwd {
+                margin-left: 43px;
+            }
+            .form div:not(:first-child) {
+                margin-top: 20px;
+            }
+
+        }
+         @media(min-width:768px){
+            .form-inline {
+                margin-left: 50px;
+            }
+            .radio {
+                margin-left: 50px;
+            }
+            form > div:last-child {
+                margin-left: 60px;
+            }
+            .wrong-info {
+                margin-left: 50px;
+            }
+         }
+
+         @media(min-width:991px){
+            .form-inline {
+                margin-left: 140px;
+            }
+            .radio {
+                margin-left: 140px;
+            }
+            form > div:last-child {
+                margin-left: 150px;
+            }
+            .wrong-info {
+                margin-left: 140px;
+            }
+         }
+
+         @media(min-width:1200px){
+            .form-inline {
+                margin-left: 180px;
+            }
+            .radio {
+                margin-left: 180px;
+            }
+             form > div:last-child {
+                margin-left: 190px;
+            }
+            .wrong-info {
+                margin-left: 170px;
+            }
+         }

BIN
CoffeeProject/app/static/img/PV.jpg


BIN
CoffeeProject/app/static/img/coffee.jpg


+ 100 - 0
CoffeeProject/app/static/js/registration.js

@@ -0,0 +1,100 @@
+        function Login(){
+            window.location.href='/login';
+        };
+
+        $(function (){
+            var firstname = $("input[name='firstname']");
+            var lastname = $("input[name='lastname']");
+            var email = $("input[name='email']");
+            var phone = $("input[name='phone']");
+            var username = $("input[name='username']");
+            var password = $("input[name='password']");
+            var confirmpwd = $("input[name='confirmpwd']");
+            var status = false;
+            var form = $("form");
+
+            firstname.blur(function(){
+                var span = $("#firstname-span");
+                if(firstname.val() == ''){
+                    span.text("Field is requied");
+                    status = false;
+                }else{
+                    span.text("");
+                    status = true;
+                };
+            });
+
+            lastname.blur(function(){
+                var span = $("#lastname-span");
+                if(lastname.val() == ''){
+                    span.text("Field is requied");
+                    status = false;
+                }else{
+                    span.text("");
+                    status = true;
+                };
+            });
+
+            email.blur(function(){
+                var span = $("#email-span");
+                if(email.val().indexOf('@') == -1){
+                    span.text("Incorrect email address");
+                    status = false;
+                }else{
+                    span.text("");
+                    status = true;
+                    $.get('/check_email','email='+email.val(),function(resText){
+                        if(resText.errMsg){
+                            $("#firstname_span").text("This email is already registered");
+                            status = false;
+                        }else{
+                            $("#firstname_span").text("");
+                            status = true;
+                        };
+                    },'json');
+                };
+            });
+
+            phone.blur(function(){
+                var span = $("#phone-span");
+                if(phone.val().length < 8 || isNaN(phone.val()) == true){
+                    span.text("Wrong phone number");
+                    status = false;
+                }else{
+                    span.text("");
+                    status = true;
+                };
+            });
+
+            username.blur(function(){
+                $.get("/check_username","username="+username.val(),function(resText){
+                    if(resText.errMsg){
+                        $("#firstname-span").text("This username is already registered");
+                        status = false;
+                    }else{
+                        $("#firstname-span").text("");
+                        status = true;
+                    };
+                },'json');
+            });
+
+            confirmpwd.blur(function(){
+                var span = $("#password-span");
+                if(password.val() != confirmpwd.val()){
+                    span.text("Passwords does not match");
+                    status = false;
+                }else{
+                    span.text("");
+                    status = true;
+                };
+            });
+
+            form.submit(function(){
+                if((status == true) && (password.val() != '') && (confirmpwd.val() != '')){
+                    return true;
+                }else{
+                    alert("Please type your infomation");
+                    return false;
+                };
+            });
+        });

+ 3 - 0
CoffeeProject/app/static/js/reset_pwd1.js

@@ -0,0 +1,3 @@
+function Login(){
+    window.location.href='/login';
+};

+ 3 - 0
CoffeeProject/app/static/js/reset_pwd2.js

@@ -0,0 +1,3 @@
+function ResetPassword(){
+    window.location.href='/reset_password';
+};

+ 3 - 0
CoffeeProject/app/static/js/sign_in.js

@@ -0,0 +1,3 @@
+function Registration(){
+    window.location.href='/register';
+};

+ 236 - 0
CoffeeProject/app/templates/cargo1.html

@@ -0,0 +1,236 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃1</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row" style="margin-top:100px;">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">感測器</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo1_schedule">排程</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">制動器</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">參數設置</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;"></div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1592 - 0
CoffeeProject/app/templates/cargo1_schedule.html


+ 236 - 0
CoffeeProject/app/templates/cargo2.html

@@ -0,0 +1,236 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃2</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row" style="margin-top:100px;">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor_tanks">感測器</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule_tanks">排程</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator_tanks">制動器</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">參數設置</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;"></div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1167 - 0
CoffeeProject/app/templates/cargo2_actuator.html


+ 279 - 0
CoffeeProject/app/templates/cargo2_actuator_tanks.html

@@ -0,0 +1,279 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 300px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃2</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>發酵槽</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid" style="margin-top:100px;">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/1">1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/2">2</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/3">3</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/4">4</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/5">5</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/6">6</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/7">7</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/8">8</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/9">9</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/10">10</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/11">11</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_actuator/12">12</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 1597 - 0
CoffeeProject/app/templates/cargo2_schedule.html


+ 279 - 0
CoffeeProject/app/templates/cargo2_schedule_tanks.html

@@ -0,0 +1,279 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 300px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃2</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>發酵槽</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid" style="margin-top:100px;">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/1">1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/2">2</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/3">3</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/4">4</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/5">5</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/6">6</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/7">7</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/8">8</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/9">9</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/10">10</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/11">11</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_schedule/12">12</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 714 - 0
CoffeeProject/app/templates/cargo2_sensor.html

@@ -0,0 +1,714 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+    <!-- 引入 echarts.js -->
+    <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script>
+
+    <script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js'></script>
+	<script src='https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js'></script>
+	<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/0.3.0/Chart.Zoom.min.js"></script>
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+            color: #000000;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+
+        .item-title {
+          display: inline-block;
+          margin-top: 20px;
+          margin-left: 20px;
+          font-family: Roboto;
+          font-style: normal;
+          font-weight: bold;
+          font-size: 24px;
+          color: #000000;
+        }
+
+        .set-schedule {
+            width: 200px;
+            height: 45px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 5px;
+            font-size: 17px;
+            margin-left: 20px;
+
+        }
+        .set-link {
+            width: 300px;
+            height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 5px;
+            font-size: 36px;
+            margin-left:5px;
+            margin-right:5px;
+        }
+        .sensor_status {
+            width: 300px;
+            height: 250px;
+            background: #FFFFFF;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #000000;
+            border-radius: 5px;
+            font-size: 24px;
+            margin:auto;
+
+        }
+
+
+      .div_title {
+        width:100%;
+        height:80px;
+        font-size:1em;
+        font-weight:bold;
+        color:black;
+        margin: 0 auto;
+        display: table;
+        text-align: center;
+        transform: translate(0, 10%);
+      }
+      .td_in {
+        font-size:30px;
+        margin-top:10%;
+        border-radius: 15px;
+        text-align: center;
+        background-color:#C4C4C4;
+        width:250px;
+        height: 150px;
+        margin:auto;
+        line-height: 150px;
+        cursor: pointer;
+      }
+
+      .show-info{
+            position: absolute;
+            background-color: #FFFFFF;
+            border: 1px solid #949494;
+            box-sizing: border-box;
+            z-index: 3;
+            left: 8%;
+        }
+
+        .show-info > h1 {
+            text-align: center;
+        }
+
+        .show-chart {
+            height: 500px;
+            border: 2px solid #FFF;
+            background: #C4C4C4;
+        }
+
+        .btn-input input{
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            width: 120px;
+            height: 58px;
+            text-align: center;
+            line-height: 58px;
+            font-size: 20px;
+            margin-top: 50px;
+            color: #FFFFFF;
+        }
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .col {
+                padding-left: 0px;
+                padding-right: 0px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+
+    <script>
+
+    </script>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">發酵槽{{params.tid}}</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>感測器狀態</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid" style="margin-top:100px;">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>溫溼度</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('溫濕度')">{{params.tank_tem.tem}} &#8451; </div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>二氧化碳</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('二氧化碳')"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>酸鹼值</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('酸鹼值')">{{params.tank_ph.ph}}</div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>攝影機</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('攝影機')"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>大氣壓力</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('大氣壓力')"></div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>超音波</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('超音波')">{{params.tank_sonic.sonic}}</div>
+                                </div>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <div class="sensor_status">
+                                    <div class="div_title" style="">
+                                        <label>EC值</label>
+                                    </div>
+                                    <div class="td_in" style="" onclick="ShowInfo('EC值')">{{params.tank_ec.ec}}</div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div id="" class="show-info col-xl-10 col-lg-10 col-md-10 col-sm-10 col-xs-10" style="display: none;">
+                            <br>
+                            <h1></h1>
+                            <center>
+                                資料類型:
+                                <label><input type="checkbox" name="data-type" value="max">最大值</label>
+                                <label><input type="checkbox" name="data-type" value="avg">平均值</label>
+                                <label><input type="checkbox" name="data-type" value="min">最小值</label>
+                                <br>
+                                時間間隔:
+                                <select name="time-interval" class="text-right">
+                                    <option value="month">逐月</option>
+                                    <option value="day">逐日</option>
+                                    <option value="hour">逐時</option>
+                                </select>
+                                <span>從</span>
+                                <label for="querydate-start"></label><input id="querydate-start" type="date">
+                                <span>到</span>
+                                <label for="querydate-end"></label><input id="querydate-end" type="date">
+                                <span>為止</span>
+                                <input type="button" value="查詢" onclick="Echart('');">
+                            </center>
+                            <div class="row">
+                                <div class="col-1"></div>
+                                <div class="col-10 show-chart" style="margin-top: 10px;text-align:center;"></div>
+                                <div class="col-1"></div>
+                            </div>
+                            <div class="btn-input" style="text-align:center;">
+                                <input type="button" value="關閉" style="margin-left:0px;" onclick="CloseInfo()">
+                                <input class="" type="button" value="匯出">
+                            </div>
+                        </div>
+
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+    <script>
+         var all_datetime = 0;
+         var all_data = 0;
+         var data_name = 0;
+         var xAxis_data = 0;
+         var max_data = 0;
+         var min_data = 0;
+         var avg_data = 0;
+
+        function Echart(evt){
+            if(Number({{params.tid}}) < 10){
+                data_name = evt.substring(2);
+            }else{
+                data_name = evt.substring(3);
+            };
+
+            //將echarts圖形銷毀
+            $(".show-chart").removeAttr("_echarts_instance_").empty();
+
+            var sensor = evt.substring(2);
+            if(!$("input[value=avg]").prop('checked') && !$("input[value=min]").prop('checked') && !$("input[value=max]").prop('checked')){
+                alert("請至少選擇一種資料類型!");
+                return false;
+            };
+
+            if($("#querydate-start").val() == '' || $("#querydate-end").val() == ''){
+                alert("請選擇日期範圍!");
+				return false;
+            };
+            //基於準備好的dom,初始化echarts例項
+            var myChart = echarts.init(document.getElementsByClassName('show-chart')[0]);
+
+            var date_start = $("#querydate-start").val();
+            var date_end = $("#querydate-end").val();
+            var avg = 0;
+            var max = 0;
+            var min = 0;
+            var time_interval = $("select[name=time-interval]").val();
+            var legend = new Array();
+            var color = new Array();
+            var series = new Array();
+
+
+            if($("input[value=max]").prop('checked')){
+                max = 1;
+                legend.push("最大值");
+                color.push("#1e88e5");
+            };
+
+            if($("input[value=avg]").prop('checked')){
+                avg = 1;
+                legend.push("平均值");
+                color.push("#43a047");
+            };
+
+            if($("input[value=min]").prop('checked')){
+                min = 1;
+                legend.push("最小值");
+                color.push("#e64a19");
+            };
+
+
+
+            var json = {'evt': evt, 'avg': avg, 'max': max, 'min': min, 'time-interval': time_interval, 'date-start': date_start, 'date-end': date_end};
+
+            $.get('/history_data',json,function(resText){
+
+                if(resText.max){
+                    var max_series = {'name':'最大值', 'type':'line', 'data':resText.max.map(function(item){return item[1];}), 'itemStyle':{'normal':{'lineStyle':{'color':'#1e88e5'}}},};
+                    series.push(max_series);
+                    xAxis_data = resText.max.map(function(item){return item[0];});
+                    max_data = resText.max.map(function(item){return item[1];});
+                };
+                if(resText.avg){
+                    var avg_series = {'name':'平均值', 'type':'line', 'data':resText.avg.map(function(item){return item[1];}), 'itemStyle':{'normal':{'lineStyle':{'color':'#43a047'}}},};
+                    series.push(avg_series);
+                    xAxis_data = resText.avg.map(function(item){return item[0];});
+                    avg_data = resText.avg.map(function(item){return item[1];});
+                };
+                if(resText.min){
+                    var min_series = {'name':'最小值', 'type':'line', 'data':resText.min.map(function(item){return item[1];}), 'itemStyle':{'normal':{'lineStyle':{'color':'#e64a19'}}},};
+                    series.push(min_series);
+                    xAxis_data = resText.min.map(function(item){return item[0];});
+                    min_data = resText.min.map(function(item){return item[1];});
+                };
+
+                //獲取日期內所有數據
+                all_datetime = resText.all.map(function(item){return item[0];});
+                all_data = resText.all.map(function(item){return item[1];});
+
+            <!--//指定圖表的配置項和資料-->
+
+            option = {
+                title: {
+                    text: 'Data History',
+                    left: '1%'
+                },
+                tooltip: {
+                    trigger: 'axis'
+                },
+                color: color,
+                legend: {
+                    data: legend,
+                },
+                <!--xAxis: {-->
+                    <!--data: resText.map(function (item) {-->
+                        <!--return item[0];-->
+                    <!--})-->
+                <!--},-->
+                xAxis: {
+                    data: xAxis_data,
+                },
+                yAxis: {
+                    splitLine: {
+                        show: true,
+                        lineStyle:{
+                            <!--color:''-->
+                        }
+                    }
+                },
+                toolbox: {
+                    show: true,
+                    feature: {
+                        dataZoom: {
+                            yAxisIndex: 'none'
+                        },
+                        dataView: {readOnly: false},
+                        magicType: {type: ['line', 'bar']},
+                        restore: {},
+                        saveAsImage: {}
+                    }
+                },
+                dataZoom: [{
+                    startValue: '2021-01-01'
+                }, {
+                    type: 'inside'
+                }],
+                series: series,
+
+                <!--series: [-->
+                    <!--{-->
+                        <!--name: '最大值',-->
+                        <!--type: 'line',-->
+                        <!--data: resText.map(function (item) {-->
+                            <!--return item[1];-->
+                        <!--}),-->
+                        <!--itemStyle:{-->
+                            <!--normal:{-->
+                                <!--lineStyle:{-->
+                                    <!--color:'#1e88e5'-->
+                                <!--}-->
+                            <!--}-->
+                        <!--},-->
+                    <!--},-->
+                    <!--{-->
+                        <!--name: '平均值',-->
+                        <!--type: 'line',-->
+                        <!--data: [20.0,20.0,20.0,20.0,20.0,20.0],-->
+                        <!--itemStyle:{-->
+                            <!--normal:{-->
+                                <!--lineStyle:{-->
+                                    <!--color:'#43a047'-->
+                                <!--}-->
+                            <!--}-->
+                        <!--},-->
+                    <!--},-->
+                    <!--{-->
+                        <!--name: '最小值',-->
+                        <!--type: 'line',-->
+                        <!--data: [15.0,15.0,15.0,15.0,15.0,15.0],-->
+                        <!--itemStyle:{-->
+                            <!--normal:{-->
+                                <!--lineStyle:{-->
+                                    <!--color:'#e64a19'-->
+                                <!--}-->
+                            <!--}-->
+                        <!--},-->
+                    <!--},-->
+                <!--]-->
+            };
+
+                //使用剛指定的配置項和資料顯示圖表
+                myChart.setOption(option);
+
+
+            }, 'json');
+
+        };
+
+
+        //下載檔案函數
+        function downloadFile() {
+          //藉型別陣列建構的 blob 來建立 URL
+          let fileName = "fileName.csv";
+          //"\ufeff"解決打開CSV中文亂碼問題
+          const data = "\ufeff" + getData();
+          let blob = new Blob([data], {
+            type: 'text/csv,charset=UTF-8'
+          });
+          var href = URL.createObjectURL(blob);
+          // 從 Blob 取出資料
+          var link = document.createElement("a");
+          document.body.appendChild(link);
+          link.href = href;
+          link.download = fileName;
+          link.click();
+        };
+
+        //所有資料函數
+        <!--function getData() {-->
+          <!--var header = "日期," + data_name + "\n";-->
+          <!--var data = "";-->
+          <!--var length = all_datetime.length;-->
+
+          <!--for(var i=0; i<length; i++){-->
+            <!--data = data + all_datetime[i] + ',' + all_data[i] + '\n';-->
+          <!--};-->
+
+          <!--return header + data;-->
+        <!--};-->
+
+
+        //最大最小平均資料函數
+        function getData() {
+            var header = data_name + "\n日期,";
+            if(max_data){
+                console.log(max_data);
+                header = header + "最大值,";
+            };
+            if(avg_data){
+                header = header + "平均值,";
+            };
+            if(min_data){
+                header = header + "最小值,";
+            };
+            header = header + "\n";
+            var data = "";
+            var length = xAxis_data.length;
+
+            for(var i=0; i<length; i++){
+                data = data + xAxis_data[i] + ',';
+                if(max_data){
+                    data = data + max_data[i] + ',';
+                };
+                if(avg_data){
+                    data = data + avg_data[i] + ',';
+                };
+                if(min_data){
+                    data = data + min_data[i] + ',';
+                };
+                data = data + '\n';
+            };
+
+            return header + data;
+        };
+
+
+
+        function ShowInfo(sensor){
+            $(".show-info").css('display','block');
+            $(".show-info h1").text(sensor);
+            $("input[value=查詢]").attr('onclick', 'Echart(\'{{params.tid}}' + '-' + sensor + '\')');
+            $("input[value=匯出]").attr('class','DownloadBtn');
+
+            let DownloadBtn = document.querySelector(".DownloadBtn");
+            DownloadBtn.addEventListener("click", downloadFile);
+
+        };
+
+        function CloseInfo(){
+            //將echarts圖形銷毀
+            $(".show-chart").removeAttr("_echarts_instance_").empty();
+            //將複選框已選定的移除
+            $("input[value=avg]").prop('checked', false);
+            $("input[value=min]").prop('checked', false);
+            $("input[value=max]").prop('checked', false);
+            //將時間間隔回到月
+            $("select[name=time-interval]").val('month');
+            //將已選好的日期移除
+            $("#querydate-start").val('');
+            $("#querydate-end").val('');
+            $(".show-info").css('display','none');
+        };
+
+    </script>
+</html>

+ 279 - 0
CoffeeProject/app/templates/cargo2_sensor_tanks.html

@@ -0,0 +1,279 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 300px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃2</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>發酵槽</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid" style="margin-top:100px;">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/1">1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/2">2</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/3">3</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/4">4</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/5">5</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/6">6</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/7">7</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/8">8</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/9">9</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/10">10</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/11">11</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2_sensor/12">12</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 236 - 0
CoffeeProject/app/templates/cargo3.html

@@ -0,0 +1,236 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃3</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row" style="margin-top:100px;">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">感測器</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo3_schedule">排程</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">制動器</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">參數設置</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;"></div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 801 - 0
CoffeeProject/app/templates/cargo3_schedule.html

@@ -0,0 +1,801 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+        <script>
+            $(function(){
+                 //提升機
+                 {% if params.hoists %}
+                    var hoist_num = 0;
+                    {% for hoist in params.hoists %}
+                        if('{{hoist.start}}' != '00:00' && '{{hoist.end}}' != '00:00' && hoist_num == 0){
+                            var ho = $(".set-schedule")[0];
+                            var ho_div = $("#hoist_div");
+                            ho.style.display = 'none';
+                            ho_div.css('visibility','visible');
+
+                            $('select[name=hoist_duration1]').val('{{hoist.duration}}');
+                            $('select[name=hoist_from_hr1]').val('{{hoist.start}}'.split(':')[0]);
+                            $('select[name=hoist_from_min1]').val('{{hoist.start}}'.split(':')[1]);
+                            $('select[name=hoist_to_hr1]').val('{{hoist.end}}'.split(':')[0]);
+                            $('select[name=hoist_to_min1]').val('{{hoist.end}}'.split(':')[1]);
+
+                            hoist_num ++;
+                        }else if(hoist_num > 0){
+                            if(hoist_num == 1){
+                                var add = document.getElementById('hoist_add1');
+                                hoist_num ++;
+                            }else{
+                                var add = document.getElementById('hoist_add' + i);
+                            };
+                            Add(add);
+                            $('select[name=hoist_duration' + i + ']').val('{{hoist.duration}}');
+                            $('select[name=' + 'hoist_from_hr' + i + ']').val('{{hoist.start}}'.split(':')[0]);
+                            $('select[name=' + 'hoist_from_min' + i + ']').val('{{hoist.start}}'.split(':')[1]);
+                            $('select[name=' + 'hoist_to_hr' + i + ']').val('{{hoist.end}}'.split(':')[0]);
+                            $('select[name=' + 'hoist_to_min' + i + ']').val('{{hoist.end}}'.split(':')[1]);
+                        };
+                    {% endfor %}
+                {% endif %}
+
+                //烘乾機
+                 {% if params.dryers %}
+                    var dryer_num = 0;
+                    {% for dryer in params.dryers %}
+                        if('{{dryer.start}}' != '00:00' && '{{dryer.end}}' != '00:00' && dryer_num == 0){
+                            var dry = $(".set-schedule")[1];
+                            var dry_div = $("#dryer_div");
+                            dry.style.display = 'none';
+                            dry_div.css('visibility','visible');
+
+                            $('select[name=dryer_duration1]').val('{{dryer.duration}}');
+                            $('select[name=dryer_from_hr1]').val('{{dryer.start}}'.split(':')[0]);
+                            $('select[name=dryer_from_min1]').val('{{dryer.start}}'.split(':')[1]);
+                            $('select[name=dryer_to_hr1]').val('{{dryer.end}}'.split(':')[0]);
+                            $('select[name=dryer_to_min1]').val('{{dryer.end}}'.split(':')[1]);
+
+                            dryer_num ++;
+                        }else if(dryer_num > 0){
+                            if(dryer_num == 1){
+                                var add = document.getElementById('dryer_add1');
+                                dryer_num ++;
+                            }else{
+                                var add = document.getElementById('dryer_add' + i);
+                            };
+                            Add(add);
+                            $('select[name=dryer_duration' + i + ']').val('{{dryer.duration}}');
+                            $('select[name=' + 'dryer_from_hr' + i + ']').val('{{dryer.start}}'.split(':')[0]);
+                            $('select[name=' + 'dryer_from_min' + i + ']').val('{{dryer.start}}'.split(':')[1]);
+                            $('select[name=' + 'dryer_to_hr' + i + ']').val('{{dryer.end}}'.split(':')[0]);
+                            $('select[name=' + 'dryer_to_min' + i + ']').val('{{dryer.end}}'.split(':')[1]);
+                        };
+                    {% endfor %}
+                {% endif %}
+            });
+        </script>
+
+        <script>
+        var i = 1;
+
+        function Cancel(){
+            window.location.href='/cargo3';
+        };
+
+        function Add(evt){
+            evt.style.display="none";
+            i ++;
+            var div = document.createElement('div');
+            var from_hr = 'from_hr' + i;
+            var from_min = 'from_min' + i;
+            var to_hr = 'to_hr' + i;
+            var to_min = 'to_min' + i;
+            var id = evt.getAttribute('id');
+            var len = id.length;
+            var add = id.split('_')[0] + '_add' + i;
+            var del = id.split('_')[0] + '_del' + i;
+            var html = '';
+            var begin = id.split('_')[0];
+            div.className = "col-12 row";
+            div.style.marginTop = "10px";
+
+                html += '<div class="col-xl-5 col-lg-5 col-md-4"  style="margin-top:10px;">';
+                html += '<span>Duration</span>';
+                if(begin == 'hoist'){
+                    html += ' <select name="hoist_duration' + i + '" class="duration">';
+                }else if(begin == 'dryer'){
+                    html += ' <select name="dryer_duration' + i + '" class="duration">';
+                }else{
+
+                };
+
+                html += '<option selected value="30min">30 min</option><option value="60min">60 min</option><option value="90min">90 min</option><option value="120min">120 min</option><option value="150min">150 min</option></select>';
+                html += '</div>';
+			    html += '<div class="from-to col-xl-7 col-lg-7 col-md-8"  style="margin-top:10px;">';
+			    html += '<div>';
+          	    html +=	'<div class="from row">';
+
+                html +=	'<div class="col-3">';
+                html +=	'<span>From</span>';
+                html +=	'</div>';
+                html +=	'<div  class="col-xs-6">';
+                if(id.split('_')[0] == 'hoist'){
+                    html +=	'<select name="hoist_from_hr' + i + '">';
+                }else if(id.split('_')[0] == 'dryer'){
+                    html +=	'<select name="dryer_from_hr' + i + '">';
+                }else{
+
+                };
+                for(var hr = 0; hr < 24; hr++){
+                    if(hr < 10){
+                        html +=	'<option value="0' + hr + '">0' + hr + '</option>';
+                    }else{
+                        html +=	'<option value="' + hr + '">' + hr + '</option>';
+                    };
+                };
+                    html += '</select>';
+                if(id.split('_')[0] == 'hoist'){
+                    html +=	' : <select name="hoist_from_min' + i + '">';
+                }else if(id.split('_')[0] == 'dryer'){
+                    html +=	' : <select name="dryer_from_min' + i + '">';
+                }else{
+
+                };
+                for(var min = 0; min < 60; min++){
+                    if(min < 10){
+                        html +=	'<option value="0' + min + '">0' + min + '</option>';
+                    }else{
+                        html +=	'<option value="' + min + '">' + min + '</option>';
+                    };
+                };
+                    html +=	'</select>';
+                html +=	'</div>';
+                html +=	'<div  class="col-xs-3">';
+                    html +=	'<input  id=' + del + ' class="delete" type="button" value="Delete" onclick="Delete(' + del + ');">';
+                html +=	'</div>';
+            html +=	'</div>';
+            html +=	'<div class="to row">';
+                html +=	'<div  class="col-3">';
+                html +=	'<span>To</span>';
+                html +=	'</div>';
+                html +=	'<div  class="col-xs-6">';
+                if(id.split('_')[0] == 'hoist'){
+                    html +=	'<select name="hoist_to_hr' + i + '">';
+                }else if(id.split('_')[0] == 'dryer'){
+                    html +=	'<select name="dryer_to_hr' + i + '">';
+                }else{
+
+                };
+                for(var hr = 0; hr < 24; hr++){
+                    if(hr < 10){
+                        html +=	'<option value="0' + hr + '">0' + hr + '</option>';
+                    }else{
+                        html +=	'<option value="' + hr + '">' + hr + '</option>';
+                    };
+                };
+                    html +=	'</select>';
+                if(id.split('_')[0] == 'hoist'){
+                    html +=	' : <select name="hoist_to_min' + i + '">';
+                }else if(id.split('_')[0] == 'dryer'){
+                    html +=	' : <select name="dryer_to_min' + i + '">';
+                }else{
+
+                };
+                for(var min = 0; min < 60; min++){
+                    if(min < 10){
+                        html +=	'<option value="0' + min + '">0' + min + '</option>';
+                    }else{
+                        html +=	'<option value="' + min + '">' + min + '</option>';
+                    };
+                };
+                    html +=	'</select><br>';
+                    html +=	'<input  id=' + add + ' class="add" type="button" value="Add" onclick="Add(' + add + ');">';
+                html +=	'</div>';
+                html +=	'<div  class="col-xs-3"></div>';
+            html +=	'</div>';
+            html += '</div>';
+            html += '</div>';
+
+
+            div.innerHTML = html;
+            div.style.marginTop = '15px';
+            div.style.zIndex = '100';
+            evt.parentNode.parentNode.parentNode.parentNode.parentNode.parentNode.appendChild(div);
+
+        };
+
+        function Delete(evt){
+            var id = evt.getAttribute('id');
+            var add = id.split('_')[0] + '_' + 'add';
+            var clo_xs_3 = evt.parentNode;
+            var from = clo_xs_3.parentNode;
+            var begin = id.split('_')[0];
+            var div = from.parentNode.parentNode.parentNode;
+            var next_div = div.nextElementSibling;
+            var pre_div = div.previousElementSibling;
+
+
+            if(next_div && pre_div == null){
+                    div.parentNode.removeChild(div);
+                    next_div.style.marginTop = '0px';
+            }else if(next_div && pre_div){
+                    div.parentNode.removeChild(div);
+            }else if(next_div == null && pre_div == null){
+                 div.parentNode.parentNode.children[1].style.display = 'inline-block';
+                 div.parentNode.style.visibility = 'hidden';
+                 var name = id.split('_')[0];
+                 var from_hr = name + '_from_hr' + 1;
+                 var from_min = name + '_from_min' + 1;
+                 var to_hr = name + '_to_hr' + 1;
+                 var to_min = name + '_to_min' + 1;
+                 $('select[name=' + from_hr + ']').val('00');
+                 $('select[name=' + from_min + ']').val('00');
+                 $('select[name=' + to_hr + ']').val('00');
+                 $('select[name=' + to_min + ']').val('00');
+            }else{
+                div.parentNode.removeChild(div);
+                i --;
+                add = add + i;
+                add = document.getElementById(add);
+                if(add == null){
+                    add = pre_div.children[1].children[0].children[1].children[1].children[3];
+                };
+                add.style.display = 'block';
+            };
+        };
+
+        $(function(){
+            var hoist = $(".set-schedule")[0];
+            var hoist_div = $("#hoist_div");
+            var dryer = $(".set-schedule")[1];
+            var dryer_div = $("#dryer_div");
+
+            hoist.onclick = function(){
+                hoist.style.display = 'none';
+                hoist_div.css('visibility','visible');
+            };
+
+            dryer.onclick = function(){
+                dryer.style.display = 'none';
+                dryer_div.css('visibility','visible');
+            };
+
+
+        });
+    </script>
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+            color: #000000;
+        }
+
+        form {
+            margin-top: 70px;
+
+        }
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .flex span {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 18px;
+            margin-left: 20px;
+            color: #000000;
+        }
+
+        .duration {
+            background: #FFFFFF;
+            border: 1px solid #000000;
+            box-sizing: border-box;
+            border-radius: 5px;
+            width: 110px;
+            height: 40px;
+            font-size: 20px;
+            margin-left: 15px;
+            text-align: center;
+        }
+
+        .from select, .to select {
+            width: 65px;
+            height: 35px;
+
+            margin-left: 2px;
+        }
+
+        .to {
+          margin-top: 10px;
+          margin-left: 10px;
+        }
+
+        .from {
+            margin-left: 10px;
+        }
+
+        .from > div:first-child, .to > div:first-child {
+            padding-right: 0px;
+            text-align: right;
+            margin-right: 5px;
+        }
+
+
+
+        .hoist, .dryer {
+          height: 400px;
+          border: 2px solid #E5E5E5;
+          border-radius: 5px;
+          margin-top:35px;
+          margin-left:35px;
+        }
+
+        .item-title {
+          display: inline-block;
+          margin-top: 20px;
+          margin-left: 20px;
+          font-family: Roboto;
+          font-style: normal;
+          font-weight: bold;
+          font-size: 24px;
+          color: #000000;
+        }
+
+        .set-schedule {
+            width: 200px;
+            height: 45px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 5px;
+            font-size: 17px;
+            margin-left: 10px;
+
+        }
+
+
+
+        .delete {
+            background: #E43030;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            margin-left: 5px;
+            width: 65px;
+            height: 33px;
+            font-size: 16px;
+            text-align: center;
+            line-height: 16px;
+            color: #FFFFFF;
+        }
+
+        .add {
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            margin-top: 10px;
+            margin-left: 82px;;
+            width: 65px;
+            height: 33px;
+            font-size: 16px;
+            text-align: center;
+            line-height: 16px;
+            color: #FFFFFF;
+        }
+
+        .page-bottom {
+            margin-top: 100px;
+        }
+
+        .form-control {
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 5px;
+            width: 120px;
+            height: 58px;
+            text-align: center;
+            line-height: 50px;
+            color: #FFFFFF;
+            display: inline-block;
+        }
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .hoist, .dryer {
+                margin-left: 0px;
+            }
+            .col {
+                padding-right: 0px;
+                padding-left: 0px;
+            }
+            .from,.to {
+                margin-left: 0px;
+            }
+            .flex span {
+                margin-left: 0px;
+            }
+            .from select, .to select {
+                width: 45px;
+            }
+            .add {
+                width: 50px;
+                margin-left: 62px;
+            }
+            .delete {
+                width: 58px;
+            }
+            .col-xs-8:not(:first-child) {
+                margin-top: 150px;
+            }
+            .form-group {
+                margin-top: 50px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+            .page-bottom input:last-child {
+                margin-left: 100px;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+            .page-bottom input:last-child {
+                margin-left: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+            .page-bottom input:last-child {
+                margin-left: 100px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+            .page-bottom input:last-child {
+                margin-left: 100px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">貨櫃3</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="page-title text-center">
+
+        </div>
+        <form method="post" action="/b_cargo3">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                         <div class="hoist col-xl-5 col-lg-5 col-md-5 col-sm-8 col-xs-8">
+                            <h2 class="item-title">提升機</h2>
+                            <input class="set-schedule" type="button" value="Set up the schedule">
+                            <br>
+                            <div id="hoist_div" class="row" style="visibility:hidden;">
+                                <div class="col-12 row">
+                                    <div class="col-xl-5 col-lg-5 col-md-4 col-sm-12 col-xs-12"  style="margin-top:10px;">
+                                        <span>Duration</span>
+                                        <select name="hoist_duration1" class="duration">
+                                            <option selected value="30min">30 min</option>
+                                            <option value="60min">60 min</option>
+                                            <option  value="90min">90 min</option>
+                                            <option  value="120min">120 min</option>
+                                            <option  value="150min">150 min</option>
+                                        </select>
+                                    </div>
+                                    <div class="from-to col-xl-7 col-lg-7 col-md-8 col-sm-12 col-xs-12"  style="margin-top:10px;">
+                                        <div>
+                                            <div class="from row">
+                                                <div class="col-3">
+                                                    <span>From</span>
+                                                </div>
+                                                <div  class="col-xs-6">
+                                                    <select name="hoist_from_hr1">
+                                                        {% for hr in range(0, 24) %}
+                                                            {% if hr < 10 %}
+                                                                <option value="0{{hr}}">0{{hr}}</option>
+                                                            {% else %}
+                                                                <option value="{{hr}}">{{hr}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select>
+                                                    : <select name="hoist_from_min1">
+                                                        {% for min in range(0, 60) %}
+                                                            {% if min < 10 %}
+                                                                <option value="0{{min}}">0{{min}}</option>
+                                                            {% else %}
+                                                                <option value="{{min}}">{{min}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select>
+                                                </div>
+                                                <div class="col-xs-3">
+                                                    <input  id="hoist_del1" class="delete" type="button" value="Delete" onclick="Delete(hoist_del1);">
+                                                </div>
+                                            </div>
+                                            <div class="to row">
+                                                <div class="col-3">
+                                                    <span>To</span>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <select name="hoist_to_hr1">
+                                                        {% for hr in range(0, 24) %}
+                                                            {% if hr < 10 %}
+                                                                <option value="0{{hr}}">0{{hr}}</option>
+                                                            {% else %}
+                                                                <option value="{{hr}}">{{hr}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select>
+                                                    : <select name="hoist_to_min1">
+                                                        {% for min in range(0, 60) %}
+                                                            {% if min < 10 %}
+                                                                <option value="0{{min}}">0{{min}}</option>
+                                                            {% else %}
+                                                                <option value="{{min}}">{{min}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select><br>
+                                                    <input id="hoist_add1" class="add" type="button" value="Add" onclick="Add(hoist_add1);">
+                                                </div>
+                                                <div  class="col-xs-3"></div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                        </div>
+
+                        <div class="dryer col-xl-5 col-lg-5 col-md-5 col-sm-8 col-xs-8">
+                            <h2 class="item-title">烘乾機</h2>
+                            <input class="set-schedule" type="button" value="Set up the schedule">
+                            <br>
+                            <div id="dryer_div" class="row" style="visibility:hidden;">
+                                <div class="col-12 row">
+                                    <div class="col-xl-5 col-lg-5 col-md-4 col-sm-12 col-xs-12"  style="margin-top:10px;">
+                                        <span>Duration</span>
+                                        <select name="dryer_duration1" class="duration">
+                                            <option selected value="30min">30 min</option>
+                                            <option value="60min">60 min</option>
+                                            <option  value="90min">90 min</option>
+                                            <option  value="120min">120 min</option>
+                                            <option  value="150min">150 min</option>
+                                        </select>
+                                    </div>
+                                    <div class="from-to col-xl-7 col-lg-7 col-md-8 col-sm-12 col-xs-12"  style="margin-top:10px;">
+                                        <div>
+                                            <div class="from row">
+                                                <div class="col-3">
+                                                    <span>From</span>
+                                                </div>
+                                                <div  class="col-xs-6">
+                                                    <select name="dryer_from_hr1">
+                                                        {% for hr in range(0, 24) %}
+                                                            {% if hr < 10 %}
+                                                                <option value="0{{hr}}">0{{hr}}</option>
+                                                            {% else %}
+                                                                <option value="{{hr}}">{{hr}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select>
+                                                    : <select name="dryer_from_min1">
+                                                        {% for min in range(0, 60) %}
+                                                            {% if min < 10 %}
+                                                                <option value="0{{min}}">0{{min}}</option>
+                                                            {% else %}
+                                                                <option value="{{min}}">{{min}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select>
+                                                </div>
+                                                <div class="col-xs-3">
+                                                    <input  id="dryer_del1" class="delete" type="button" value="Delete" onclick="Delete(dryer_del1);">
+                                                </div>
+                                            </div>
+                                            <div class="to row">
+                                                <div class="col-3">
+                                                    <span>To</span>
+                                                </div>
+                                                <div class="col-xs-6">
+                                                    <select name="dryer_to_hr1">
+                                                        {% for hr in range(0, 24) %}
+                                                            {% if hr < 10 %}
+                                                                <option value="0{{hr}}">0{{hr}}</option>
+                                                            {% else %}
+                                                                <option value="{{hr}}">{{hr}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select>
+                                                    : <select name="dryer_to_min1">
+                                                        {% for min in range(0, 60) %}
+                                                            {% if min < 10 %}
+                                                                <option value="0{{min}}">0{{min}}</option>
+                                                            {% else %}
+                                                                <option value="{{min}}">{{min}}</option>
+                                                            {% endif %}
+                                                        {% endfor %}
+                                                    </select><br>
+                                                    <input id="dryer_add1" class="add" type="button" value="Add" onclick="Add(dryer_add1);">
+                                                </div>
+                                                <div  class="col-xs-3"></div>
+                                            </div>
+                                        </div>
+                                    </div>
+                                </div>
+                            </div>
+                         </div>
+                    </div>
+                </div>
+            </div>
+            <div class="row page-bottom">
+                <div class="col"></div>
+                    <div class="col-xl-4 col-lg-6 col-md-8 col-sm-10 col-xs-10" style="text-align:center;">
+                        <div class="form-group">
+                            <input type="button" class="form-control" value="Cancel" onclick="Cancel();">
+                            <input type="submit" class="form-control" value="Confirm">
+                        </div>
+                    </div>
+                <div class="col"></div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 232 - 0
CoffeeProject/app/templates/cargo_list.html

@@ -0,0 +1,232 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">咖啡貨櫃</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo1">貨櫃1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo2">貨櫃2</a>
+                           </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo3">貨櫃3</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 246 - 0
CoffeeProject/app/templates/index.html

@@ -0,0 +1,246 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+          .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+
+        }
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+
+            .set-link {
+                width: 250px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">首頁</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/vedio">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex" style="margin: auto; ">
+                        <div class="col-xl-3  col-lg-4 col-md-5 col-sm-8 col-xs-8" style="margin-right: 20px ;margin-left: 20px; margin-top:50px; margin-bottom:50px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/">首頁</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-4 col-md-5 col-sm-8 col-xs-8" style="margin-right: 20px ;margin-left: 20px; margin-top:50px; margin-bottom:50px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">關於我們</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-4 col-md-5 col-sm-8 col-xs-8" style="margin-right: 20px ;margin-left: 20px; margin-top:50px; margin-bottom:50px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">資訊</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-4 col-md-5 col-sm-8 col-xs-8" style="margin-right: 20px ;margin-left: 20px; margin-top:50px; margin-bottom:50px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="#">聯絡方法</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-4 col-md-5 col-sm-8 col-xs-8" style="margin-right: 20px ;margin-left: 20px; margin-top:50px; margin-bottom:50px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/cargo_list">咖啡貨櫃</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-4 col-md-5 col-sm-8 col-xs-8" style="margin-right: 20px ;margin-left: 20px; margin-top:50px; margin-bottom:50px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="/video">影像串流</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 229 - 0
CoffeeProject/app/templates/learn.html

@@ -0,0 +1,229 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+            height: 50px;
+            line-height: 50px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            border-radius: 10px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            color: #FFFFFF;
+            font-size: 36px;
+        }
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">CNN影像識別</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>影像</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-12  col-lg-12 col-md-12 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="text-center">
+                                <img src="../static/img/coffee.jpg" width="60%" height="30%" style="max-width:100%;height: auto;">
+                            </div>
+                        </div>
+                        <div class="col-xl-4 col-lg-4 col-md-4 col-sm-12 col-xs-12 text-center" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center" style="display: inline-block">
+                                <a class="set-link" type="button" href="/img">
+                                    開始
+                                </a>
+                            </div>
+                            <div  class="page-title text-center" style="display: inline-block">
+                                <a class="set-link" type="button" href="/img">
+                                    返回
+                                </a>
+                           </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 96 - 0
CoffeeProject/app/templates/registration.html

@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+</head>
+<body>
+
+</body>
+</html><!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <script src="../static/js/registration.js"></script>
+
+    <link rel="stylesheet" href="../static/css/registration.css">
+
+
+</head>
+<body>
+    <div class="container">
+        <div class="row">
+            <div class="col-2"></div>
+            <div class="col">
+                <div class="row">
+                    <div class="col-4"></div>
+                    <div class="col-4">
+                        <img src="../static/img/coffee.jpg" class="img-fluid">
+                    </div>
+                    <div class="col-4"></div>
+                </div>
+                <h1 class="text-center">Registration</h1>
+                <form method="post" action="/register">
+                    <div class="form">
+                        <div class="wrong-info"><span id="firstname-span"></span></div>
+                        <div class="form-inline">
+                            <label for="first">First Name</label>
+                            <input type="text" class="form-control" id="first" name="firstname">
+                        </div>
+                        <div class="wrong-info"><span id="lastname-span"></span></div>
+                        <div class="form-inline">
+                            <label for="last">Last Name</label>
+                            <input type="text" class="form-control" id="last" name="lastname">
+                        </div>
+                        <div class="wrong-info"><span id="email-span"></span></div>
+                        <div class="form-inline">
+                            <label for="email">Email</label>
+                            <input type="email" class="form-control" id="email" name="email">
+                        </div>
+                        <div class="wrong-info"><span id="phone-span"></span></div>
+                        <div class="form-inline">
+                            <label for="phone">Phone</label>
+                            <input type="number" class="form-control" id="phone" name="phone">
+                        </div>
+                        <div class="wrong-info"><span id="username-span"></span></div>
+                        <div class="form-inline">
+                            <label for="usr">User Name</label>
+                            <input type="text" class="form-control" id="usr" name="username">
+                        </div>
+                        <div class="wrong-info"><span id="password-span"></span></div>
+                        <div class="form-inline">
+                            <label for="pwd">Password</label>
+                            <input type="password" class="form-control" id="pwd" name="password">
+                        </div>
+                        <div class="wrong-info"><span></span></div>
+                        <div class="form-inline">
+                            <label for="cpwd">Confirm Password</label>
+                            <input type="password" class="form-control" id="cpwd" name="confirmpwd">
+                        </div>
+                    </div>
+                    <div>
+                        <input type="submit" class="btn btn-info" value="Register">
+                        <input type="button"  class="btn btn-info" value="Cancel" onclick="Login()">
+                    </div>
+                </form>
+            </div>
+            <div class="col-2"></div>
+        </div>
+    </div>
+</body>
+</html>

+ 66 - 0
CoffeeProject/app/templates/reset_pwd1.html

@@ -0,0 +1,66 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <script src="../static/js/reset_pwd1.js"></script>
+
+    <link rel="stylesheet" href="../static/css/reset_pwd1.css">
+
+
+    {% if errMsg %}
+        <script>
+            $(function(){
+                $(".wrong-span").text("{{errMsg}}");
+            });
+        </script>
+    {% endif %}
+
+</head>
+<body>
+    <div class="container">
+        <div class="row">
+            <div class="col-2"></div>
+            <div class="col">
+                <div class="row">
+                    <div class="col-4"></div>
+                    <div class="col-4">
+                        <img src="../static/img/coffee.jpg" class="img-fluid">
+                    </div>
+                    <div class="col-4"></div>
+                </div>
+                <h1 class="text-center">Reset password</h1>
+                <div class="descripe text-center">write your email address</div>
+                <form method="post" action="/reset_password">
+                    <div class="wrong-info"><span class="wrong-span"></span></div>
+                    <div class="form">
+                        <div class="form-inline">
+                            <label for="email">Email</label>
+                            <input type="text" class="form-control" id="email" name="email">
+                        </div>
+                    </div>
+                    <div>
+                        <input type="button" class="btn btn-info" value="Cancel" onclick="Login();">
+                        <input type="submit"  class="btn btn-info" value="Confirm">
+                    </div>
+                </form>
+            </div>
+            <div class="col-2"></div>
+        </div>
+    </div>
+</body>
+</html>

+ 72 - 0
CoffeeProject/app/templates/reset_pwd2.html

@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <script src="../static/js/reset_pwd2.js"></script>
+
+    <link rel="stylesheet" href="../static/css/reset_pwd2.css">
+
+
+
+    {% if errMsg %}
+        <script>
+            $(function(){
+                $(".wrong-span").text("{{errMsg}}");
+            });
+        </script>
+    {% endif %}
+
+
+</head>
+<body>
+    <div class="container">
+        <div class="row">
+            <div class="col-2"></div>
+            <div class="col">
+                <div class="row">
+                    <div class="col-4"></div>
+                    <div class="col-4">
+                        <img src="../static/img/coffee.jpg" class="img-fluid">
+                    </div>
+                    <div class="col-4"></div>
+                </div>
+                <h1 class="text-center">Reset password</h1>
+                <div class="descripe text-center">create a new password</div>
+                <form method="post" action="/reset_password">
+                    <div class="wrong-info"><span class="wrong-span"></span></div>
+                    <div class="form">
+                        <div class="form-inline">
+                            <label for="new-pwd">New password</label>
+                            <input type="password" class="form-control" id="new-pwd" name="new_pwd">
+                        </div>
+                        <div class="form-inline">
+                            <label for="confirm-pwd">Confirm password</label>
+                            <input type="password" class="form-control" id="confirm-pwd" name="confirm_pwd">
+                        </div>
+                    </div>
+                    <div>
+                        <input type="button" class="btn btn-info" value="Cancel" onclick="ResetPassword();">
+                        <input type="submit"  class="btn btn-info" value="Confirm">
+                    </div>
+                </form>
+            </div>
+            <div class="col-2"></div>
+        </div>
+    </div>
+</body>
+</html>

+ 72 - 0
CoffeeProject/app/templates/sign_in.html

@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <script src="../static/js/sign_in.js"></script>
+
+    <link rel="stylesheet" href="../static/css/sign_in.css">
+
+    {% if errMsg %}
+        <script>
+            $(function(){
+                $(".wrong-span").text("{{errMsg}}");
+            });
+        </script>
+    {% endif %}
+
+</head>
+<body>
+    <div class="container">
+        <div class="row">
+            <div class="col-2"></div>
+            <div class="col">
+                <div class="row">
+                    <div class="col-4"></div>
+                    <div class="col-4">
+                        <img src="../static/img/coffee.jpg" class="img-fluid">
+                    </div>
+                    <div class="col-4"></div>
+                </div>
+                <h1 class="text-center">Sign in</h1>
+                <form method="post" action="/login">
+                    <div class="wrong-info"><span class="wrong-span"></span></div>
+                    <div class="form">
+                        <div class="form-inline">
+                            <label for="usr">Login</label>
+                            <input type="text" class="form-control" id="usr" name="username">
+                        </div>
+                        <div class="form-inline">
+                            <label for="pwd">Password</label>
+                            <input type="password" class="form-control" id="pwd" name="password">
+                        </div>
+                        <div class="radio">
+                            <label><input type="checkbox" name="rem">  Remember me</label>
+                            <a href="/reset_password">Reset password</a>
+                        </div>
+                    </div>
+                    <div>
+                        <input type="submit" class="btn btn-info" value="Log in">
+                        <input type="button"  class="btn btn-info" value="Registration" onclick="Registration();">
+                    </div>
+                </form>
+            </div>
+            <div class="col-2"></div>
+        </div>
+    </div>
+</body>
+</html>

+ 252 - 0
CoffeeProject/app/templates/test1.html

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 100px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">咖啡貨櫃</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="index.html">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="coffee.html">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="img.html">影像識別</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="">User</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>感測器</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="s_cargo1.html">貨櫃1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="s_cargo2.html">貨櫃2</a>
+                           </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="s_cargo3.html">貨櫃3</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="text-center" style="margin-top:100px;">
+                <h1>致動器</h1>
+            </div>
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="b_cargo1.html">貨櫃1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="b_cargo2.html">貨櫃2</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="b_cargo3.html">貨櫃3</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 252 - 0
CoffeeProject/app/templates/test3.html

@@ -0,0 +1,252 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 100px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+
+         }
+
+
+    </style>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">咖啡貨櫃</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="index.html">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/coffee">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/img">影像識別</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="">User</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <div class="text-center">
+            <h1>感測器</h1>
+        </div>
+        <form method="" action="">
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="s_cargo1.html">貨櫃1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="s_cargo2.html">貨櫃2</a>
+                           </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="s_cargo3.html">貨櫃3</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div class="text-center" style="margin-top:100px;">
+                <h1>致動器</h1>
+            </div>
+            <div class="container-fluid">
+                <div class="row">
+                    <div class="col flex">
+                        <div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="b_cargo1.html">貨櫃1</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="b_cargo2.html">貨櫃2</a>
+                            </div>
+                        </div>
+                        <div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">
+                            <div class="page-title text-center">
+                                <a class="set-link" type="button" href="b_cargo3.html">貨櫃3</a>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </form>
+    </div>
+</body>
+</html>

+ 134 - 0
CoffeeProject/app/templates/test5.html

@@ -0,0 +1,134 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <style>
+        /*多選下拉框樣式(根據自己的樣式調整)*/
+        .dropdown_item{
+            width: 100%;
+        }
+
+        .dropdown_item>li:HOVER{
+            background-color: #eee;
+            cursor: pointer;
+        }
+
+        .dropdown_item>li {
+            display: block;
+            padding: 3px 10px;
+            clear: both;
+            font-weight: normal;
+            line-height: 1.428571429;
+            color: #333;
+            white-space: nowrap;
+        }
+
+        .dropdown_item>li>.check_box{
+            width: 18px;
+            height: 18px;
+            vertical-align: middle;
+            margin: 0px;
+        }
+
+
+        .dropdown_item>li>span{
+            vertical-align: middle;
+        }
+
+        .select_multiple .caret{
+            border-top: 4px solid!important;
+            border-bottom: 0;
+        }
+    </style>
+
+    <script>
+        //多選下拉框實現
+    $(document).on("click",".check_box",function(event){
+		event.stopPropagation();//阻止事件冒泡,防止觸發li的點選事件
+		//勾選的項
+		var $selectTextDom=$(this).parent().parent("ul").siblings("button").children(".select_text");
+		//勾選項的值
+		var $selectValDom=$(this).parent().parent("ul").siblings(".select_val");
+		//是否有選擇項了
+		var isSelected=$selectTextDom[0].getAttribute("data-is-select");
+		var selectText="";//文字值,用於顯示
+		var selectVal=$selectValDom.val();//實際值,會提交到後臺的
+		var selected_text=$(this).siblings("span").text();//當次勾選的文字值
+		var selected_val=$(this).val();//當次勾選的實際值
+		//判斷是否選擇過
+		if(isSelected=="true"){
+			selectText=$selectTextDom.text();
+		}
+		if(selectText!=""){
+			if(selectText.indexOf(selected_text)>=0){//判斷是否已經勾選過
+				selectText=selectText.replace(selected_text,"").replace(",,",",");//替換掉
+				selectVal=selectVal.replace(selected_val,"").replace(",,",",");//替換掉
+				//判斷最後一個字元是否是逗號
+				if(selectText.charAt(selectText.length - 1)==","){
+					//去除末尾逗號
+					selectText=selectText.substring(0,selectText.length - 1);
+					selectVal=selectVal.substring(0,selectVal.length - 1);
+				}
+			}else{
+				selectText+=","+selected_text;
+				selectVal+=","+selected_val;
+			}
+		}else{
+			selectText=selected_text;
+			selectVal=selected_val;
+		}
+		$selectTextDom.text(selectText);
+		$selectValDom.val(selectVal);
+		if(selectText==""){
+			$selectTextDom.text("請選擇");
+			$selectTextDom[0].setAttribute("data-is-select","false");
+		}else{
+			$selectTextDom[0].setAttribute("data-is-select","true");
+		}
+	})
+    </script>
+
+</head>
+<body>
+<div class="dropup" style="position: relative;">
+	<button class="btn btn-default dropdown-toggle form-control select_multiple" style="width: 20%;margin-left: 0px;" type="button" id="dropdownMenu21" data-toggle="dropdown">
+    	<span class="select_text" data-is-select="false">Dro pup</span>
+    	<span class="caret"></span>
+  	</button>
+  	<ul class="dropdown-menu dropdown_item" style="bottom: auto;">
+    	<li><input type="checkbox" class="check_box" value="aa" /> <span>Action</span></li>
+    	<li><input type="checkbox" class="check_box" value="bb"/> <span>Another action</span></li>
+    	<li><input type="checkbox" class="check_box" value="cc"/> <span>Something else here</span></li>
+    	<li><input type="checkbox" class="check_box" value="dd"/> <span>Separated link</span></li>
+  	</ul><!-- 為了方便演示,type設定text了,實際中可以設定成hidden -->
+	<input type="hidden" name="" class="select_val"/>
+</div>
+
+<select>
+    <!--<option>-->
+    <!--<ul class="dropdown-menu dropdown_item" style="bottom: auto;">-->
+    	<!--<li><input type="checkbox" class="check_box" value="aa" /> <span>Action</span></li>-->
+    	<!--<li><input type="checkbox" class="check_box" value="bb"/> <span>Another action</span></li>-->
+    	<!--<li><input type="checkbox" class="check_box" value="cc"/> <span>Something else here</span></li>-->
+    	<!--<li><input type="checkbox" class="check_box" value="dd"/> <span>Separated link</span></li>-->
+  	<!--</ul>&lt;!&ndash; 為了方便演示,type設定text了,實際中可以設定成hidden &ndash;&gt;-->
+    <!--</option>-->
+    <option>red</option>
+</select>
+</body>
+</html>

+ 76 - 0
CoffeeProject/app/templates/test6.html

@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Title</title>
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
+    <script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js'></script>
+	<script src='https://cdnjs.cloudflare.com/ajax/libs/hammer.js/2.0.8/hammer.js'></script>
+	<script src="https://cdnjs.cloudflare.com/ajax/libs/chartjs-plugin-zoom/0.3.0/Chart.Zoom.min.js"></script>
+</head>
+<body>
+    <div id="div_linechart">
+		<button id="reset_zoom" style="float:right;color:black;">Reset</button>
+		<canvas id="linechart"></canvas>
+	</div>
+</body>
+    <script>
+        		var ctx = document.getElementById("linechart").getContext("2d");
+					window.myChart = new Chart(ctx, {
+						type: 'line',
+						data: window.chartdata,
+						options: {
+							responsive: true,
+							animation: false,
+							tooltips: {
+								mode: 'nearest', //'label'
+								intersect: false,
+								position: 'nearest',
+							},
+							legend: {
+								display: false,
+								labels: {
+									fontColor: "#FFFFFF",
+									fontSize: 12
+								}
+							},
+							hover: {
+								mode: 'x'
+							},
+							scales: {
+								xAxes: [{
+									ticks: {
+										fontColor: "#FFFFFF",
+										fontSize: 12
+									},
+									display: true,
+									type: 'time',
+									time: {
+										tooltipFormat:'ddd MMM DD YYYY hh A',
+									},
+									gridLines: {
+										color: "#595959",
+									}
+								}],
+								yAxes: [{
+									ticks: {
+										fontColor: "#FFFFFF",
+										fontSize: 14
+									},
+									gridLines: {
+										color: "#999999",
+									}
+								}],
+							},
+							pan: {
+								enabled: true,
+								mode: 'x',
+							},
+							zoom: {
+								enabled: true,
+								mode: 'x',
+							}
+						}
+					});
+    </script>
+</html>

+ 294 - 0
CoffeeProject/app/templates/video.html

@@ -0,0 +1,294 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Aisky-coffee</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
+
+    <!-- 新 Bootstrap4 核心 CSS 文件 -->
+    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
+
+    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
+    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
+
+    <!-- popper.min.js 用于弹窗、提示、下拉菜单 -->
+    <script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
+
+    <!-- 最新的 Bootstrap4 核心 JavaScript 文件 -->
+    <script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
+
+    <!--可用來建立使用者小圖示-->
+    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
+
+
+    <style>
+        body {
+	        margin:0;
+        }
+
+        .navbar-dark .navbar-nav .nav-link {
+            color: white;
+            cursor: pointer;
+	        text-decoration:none;
+            width: 110px;
+            height: 46px;
+        }
+
+        .nav-top {
+	        line-height:40px;
+	        background-color: #C4C4C4;
+        }
+
+        .website_title{
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: normal;
+            font-size: 30px;
+            color: #000000;
+        }
+
+        .navbar-nav > li{
+	        float: none;
+	        display: inline-block;
+	        width: 100px;
+            margin: 0 auto;
+            text-align: center;
+        }
+
+        .navbar-nav > li a{
+            font-size: 20px;
+        }
+
+        .main-page {
+            margin-top: 200px;
+        }
+
+        .page-title {
+            font-family: Roboto;
+            font-style: normal;
+            font-weight: bold;
+            font-size: 36px;
+        }
+
+
+        .flex {
+            display: flex;
+            flex-direction: row;
+            flex-wrap: wrap;
+            justify-content: center;
+        }
+
+        .set-link {
+            display: inline-block;
+            width: 350px;
+            height: 100px;
+            line-height: 100px;
+            background: #008CBA;
+            border: 1px solid #CFCFCF;
+            box-sizing: border-box;
+            color: #FFFFFF;
+            border-radius: 10px;
+            font-size: 36px;
+        }
+
+        @media(max-width:373px){
+            .card {
+                margin-right: 0px;
+            }
+        }
+
+        @media(max-width:577px){
+
+        }
+
+        @media(min-width:576px){
+
+
+        }
+         @media(min-width:768px){
+            .navbar-nav > li {
+                 margin-left: 0px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:991px){
+            .navbar-nav > li {
+                 margin-left: 20px;
+            }
+            .navbar-nav .li-block {
+                display:none;
+            }
+         }
+
+         @media(min-width:1200px){
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 100px;
+            }
+         }
+
+         @media(min-width:1400px){
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 200px;
+            }
+
+         }
+
+
+         @media(min-width:1689px) {
+            .navbar-nav > li {
+                 margin-left: 50px;
+            }
+            .navbar-nav .li-block {
+                display: inline-block;
+                width: 500px;
+            }
+         }
+
+
+    </style>
+
+        <script>
+                <!--//影像串流-->
+                <!--function Btx() {-->
+                    <!--console.log('test');-->
+                    <!--console.log(document.getElementById("img3"));-->
+                    <!--document.getElementById("img3").src = "{{url_for('main.video_feed_views')}}";-->
+                        <!--$.get("/udp_client",'OK' , function(resText){-->
+                            <!--console.log(resText);-->
+                        <!--}, 'text');-->
+                <!--};-->
+
+
+                <!--function Btn() {-->
+                    <!--document.getElementById("img3").src = "../static/img/PV.jpg";-->
+                    <!--$.post("/udp_client", "OK", function(){-->
+                        <!--console.log(resText);-->
+                    <!--}, 'text');-->
+                    <!--$.post('/video_feed', "OK", function(){-->
+                        <!--console.log(resText);-->
+                    <!--}, 'text');-->
+                <!--};-->
+
+        </script>
+</head>
+<body>
+    <nav class="fixed-top">
+        <nav class="navbar navbar-expand-md nav-top justify-content-center">
+            <div>
+                <span class="website_title">影像串流</span>
+            </div>
+        </nav>
+        <nav class="navbar navbar-expand-md bg-dark navbar-dark nav-bottom">
+            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
+                <span class="navbar-toggler-icon"></span>
+            </button>
+            <div class="collapse navbar-collapse" id="collapsibleNavbar">
+                <ul class="navbar-nav">
+                    <li class="nav-item">
+                        <a class="nav-link" href="/">首頁</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">關於我們</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">資訊</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#">聯絡方法</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/cargo_list">咖啡貨櫃</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/video">影像串流</a>
+                    </li>
+                    <li class="li-block"></li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="#"><i class="fa fa-user-o"></i> {{params.username}}</a>
+                    </li>
+                    <li class="nav-item">
+                        <a class="nav-link" href="/logout">Logout</a>
+                    </li>
+                </ul>
+            </div>
+        </nav>
+    </nav>
+    <div class="main-page">
+        <!--<div class="text-center">-->
+            <!--<h1>模型選擇</h1>-->
+        <!--</div>-->
+        <!--<form method="" action="">-->
+            <div class="container-fluid">
+                <div class="row" style="margin-top:100px;">
+                    <div class="col flex">
+                        <!--<div class="col-xl-3  col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">-->
+                            <!--<div class="page-title text-center">-->
+                                <!--<a class="set-link" type="button" href="/learn">1.CNN</a>-->
+                            <!--</div>-->
+                        <!--</div>-->
+                        <!--<div class="col-xl-3 col-lg-6 col-md-6 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;">-->
+                            <!--<div class="page-title text-center">-->
+                                <!--<a class="set-link" type="button" href="/learn">2.KNN</a>-->
+                            <!--</div>-->
+                        <!--</div>-->
+                        <!--<div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-xs-12" style="margin-right: 20px ;margin-left: 20px; margin-top:20px; margin-bottom:20px;"></div>-->
+
+
+                        <!--<div class="col-md-12" style="text-align:center;margin-top:5px;">-->
+							<!--<img id="img3" src="../static/img/PV.jpg" style="max-width:100%;height:auto;">-->
+						<!--</div>-->
+						<!--<div class="col-md-12 row" style="text-align:center;margin-top:5px;">-->
+							<!--<div class="col-md-6" style="text-align:center;margin-top:5px;">-->
+								<!--<button id="btn" style="font-size:20px" onclick="Btn()">關閉</button>-->
+							<!--</div>-->
+							<!--<div class="col-md-6" style="text-align:center;margin-top:5px;">-->
+								<!--<button id="btx" style="font-size:20px" onclick="Btx()">影像串流</button>-->
+							<!--</div>-->
+						<!--</div>-->
+
+                        <img src="" id = "one"width = "320" height = "240">
+                        <img src="" id = "two" width = "320" height = "240">
+
+                    </div>
+                </div>
+            </div>
+        <!--</form>-->
+    </div>
+</body>
+    <script>
+            const img = document.querySelector('#one');
+            const WS_URL = 'ws:///60.250.156.230:8088';
+            const ws = new WebSocket(WS_URL);
+            let urlObject;
+            ws.onopen = () => console.log(`Connected to ${WS_URL}`);
+            ws.onmessage = message => {
+                const arrayBuffer = message.data;
+                if(urlObject){
+                    URL.revokeObjectURL(urlObject);
+                }
+                urlObject = URL.createObjectURL(new Blob([arrayBuffer]));
+                img.src = urlObject;
+            }
+            const img1 = document.querySelector('#two');
+            const WS_URL1 = 'ws:///60.250.156.230:8089';
+            const ws1 = new WebSocket(WS_URL1);
+            let urlObject1;
+            ws1.onopen = () => console.log(`Connected to ${WS_URL1}`);
+            ws1.onmessage = message1 => {
+                const arrayBuffer1 = message1.data;
+                if(urlObject1){
+                    URL.revokeObjectURL(urlObject1);
+                }
+                urlObject1 = URL.createObjectURL(new Blob([arrayBuffer1]));
+                img1.src = urlObject1;
+            }
+    </script>
+</html>

+ 6 - 0
CoffeeProject/app/user/__init__.py

@@ -0,0 +1,6 @@
+#user目錄:針對用戶業務邏輯處理的目錄
+#針對用戶業務邏輯處理的初始化行為
+
+from flask import Blueprint
+user = Blueprint('user',__name__)
+from . import views

BIN
CoffeeProject/app/user/__pycache__/__init__.cpython-35.pyc


BIN
CoffeeProject/app/user/__pycache__/__init__.cpython-36.pyc


BIN
CoffeeProject/app/user/__pycache__/views.cpython-35.pyc


BIN
CoffeeProject/app/user/__pycache__/views.cpython-36.pyc


+ 6 - 0
CoffeeProject/app/user/views.py

@@ -0,0 +1,6 @@
+#針對用戶業務邏輯處理的視圖和路由的定義
+from . import user
+
+@user.route('/user')
+def user_index():
+    return "這是user中的首頁"

+ 30 - 0
CoffeeProject/coffee_manage.py

@@ -0,0 +1,30 @@
+#啟動和管理項目
+from app import create_app
+from flask import request
+from gevent import pywsgi
+
+app, db, mqtt = create_app()
+
+#mqtt訂閱
+@mqtt.on_connect()
+def handle_connect(client, userdata, flags, rc):
+    mqtt.subscribe('AISKY/Coffee/MK-G/b8:27:eb:b4:59:3e/Log')
+
+
+#調用日誌訊息
+@mqtt.on_log()
+def handle_logging(client, userdata, level, buf):
+    print(level, buf)
+
+#自動關閉所有未使用、掛著的連接
+@app.teardown_appcontext
+def shutdown_session(exception=None):
+        db.session.remove()
+
+
+
+if __name__ == '__main__':
+    app.run(debug=False, threaded=True, port=5006, host='0.0.0.0')
+    #使用WSGI開關,避免出現WARNING: This is a development server. Do not use it in a production deployment.Use a production WSGI server instead.
+    # server = pywsgi.WSGIServer(('0.0.0.0', 5006), app)
+    # server.serve_forever()

+ 1 - 0
CoffeeProject/migrations/README

@@ -0,0 +1 @@
+Generic single-database configuration.

BIN
CoffeeProject/migrations/__pycache__/env.cpython-35.pyc


+ 45 - 0
CoffeeProject/migrations/alembic.ini

@@ -0,0 +1,45 @@
+# A generic, single database configuration.
+
+[alembic]
+# template used to generate migration files
+# file_template = %%(rev)s_%%(slug)s
+
+# set to 'true' to run the environment during
+# the 'revision' command, regardless of autogenerate
+# revision_environment = false
+
+
+# Logging configuration
+[loggers]
+keys = root,sqlalchemy,alembic
+
+[handlers]
+keys = console
+
+[formatters]
+keys = generic
+
+[logger_root]
+level = WARN
+handlers = console
+qualname =
+
+[logger_sqlalchemy]
+level = WARN
+handlers =
+qualname = sqlalchemy.engine
+
+[logger_alembic]
+level = INFO
+handlers =
+qualname = alembic
+
+[handler_console]
+class = StreamHandler
+args = (sys.stderr,)
+level = NOTSET
+formatter = generic
+
+[formatter_generic]
+format = %(levelname)-5.5s [%(name)s] %(message)s
+datefmt = %H:%M:%S

+ 96 - 0
CoffeeProject/migrations/env.py

@@ -0,0 +1,96 @@
+from __future__ import with_statement
+
+import logging
+from logging.config import fileConfig
+
+from sqlalchemy import engine_from_config
+from sqlalchemy import pool
+from flask import current_app
+
+from alembic import context
+
+# this is the Alembic Config object, which provides
+# access to the values within the .ini file in use.
+config = context.config
+
+# Interpret the config file for Python logging.
+# This line sets up loggers basically.
+fileConfig(config.config_file_name)
+logger = logging.getLogger('alembic.env')
+
+# add your model's MetaData object here
+# for 'autogenerate' support
+# from myapp import mymodel
+# target_metadata = mymodel.Base.metadata
+config.set_main_option(
+    'sqlalchemy.url',
+    str(current_app.extensions['migrate'].db.engine.url).replace('%', '%%'))
+target_metadata = current_app.extensions['migrate'].db.metadata
+
+# other values from the config, defined by the needs of env.py,
+# can be acquired:
+# my_important_option = config.get_main_option("my_important_option")
+# ... etc.
+
+
+def run_migrations_offline():
+    """Run migrations in 'offline' mode.
+
+    This configures the context with just a URL
+    and not an Engine, though an Engine is acceptable
+    here as well.  By skipping the Engine creation
+    we don't even need a DBAPI to be available.
+
+    Calls to context.execute() here emit the given string to the
+    script output.
+
+    """
+    url = config.get_main_option("sqlalchemy.url")
+    context.configure(
+        url=url, target_metadata=target_metadata, literal_binds=True
+    )
+
+    with context.begin_transaction():
+        context.run_migrations()
+
+
+def run_migrations_online():
+    """Run migrations in 'online' mode.
+
+    In this scenario we need to create an Engine
+    and associate a connection with the context.
+
+    """
+
+    # this callback is used to prevent an auto-migration from being generated
+    # when there are no changes to the schema
+    # reference: http://alembic.zzzcomputing.com/en/latest/cookbook.html
+    def process_revision_directives(context, revision, directives):
+        if getattr(config.cmd_opts, 'autogenerate', False):
+            script = directives[0]
+            if script.upgrade_ops.is_empty():
+                directives[:] = []
+                logger.info('No changes in schema detected.')
+
+    connectable = engine_from_config(
+        config.get_section(config.config_ini_section),
+        prefix='sqlalchemy.',
+        poolclass=pool.NullPool,
+    )
+
+    with connectable.connect() as connection:
+        context.configure(
+            connection=connection,
+            target_metadata=target_metadata,
+            process_revision_directives=process_revision_directives,
+            **current_app.extensions['migrate'].configure_args
+        )
+
+        with context.begin_transaction():
+            context.run_migrations()
+
+
+if context.is_offline_mode():
+    run_migrations_offline()
+else:
+    run_migrations_online()

+ 24 - 0
CoffeeProject/migrations/script.py.mako

@@ -0,0 +1,24 @@
+"""${message}
+
+Revision ID: ${up_revision}
+Revises: ${down_revision | comma,n}
+Create Date: ${create_date}
+
+"""
+from alembic import op
+import sqlalchemy as sa
+${imports if imports else ""}
+
+# revision identifiers, used by Alembic.
+revision = ${repr(up_revision)}
+down_revision = ${repr(down_revision)}
+branch_labels = ${repr(branch_labels)}
+depends_on = ${repr(depends_on)}
+
+
+def upgrade():
+    ${upgrades if upgrades else "pass"}
+
+
+def downgrade():
+    ${downgrades if downgrades else "pass"}

+ 34 - 0
CoffeeProject/migrations/versions/3cd641e789b7_.py

@@ -0,0 +1,34 @@
+"""empty message
+
+Revision ID: 3cd641e789b7
+Revises: 9f72f41f27ab
+Create Date: 2021-02-20 16:45:37.001556
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '3cd641e789b7'
+down_revision = '9f72f41f27ab'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.create_table('test',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('status', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_table('test')
+    # ### end Alembic commands ###

+ 37 - 0
CoffeeProject/migrations/versions/3faa6d09ff44_.py

@@ -0,0 +1,37 @@
+"""empty message
+
+Revision ID: 3faa6d09ff44
+Revises: 3cd641e789b7
+Create Date: 2021-02-20 16:47:34.627443
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects import mysql
+
+# revision identifiers, used by Alembic.
+revision = '3faa6d09ff44'
+down_revision = '3cd641e789b7'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_table('test')
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.create_table('test',
+    sa.Column('sn', mysql.INTEGER(display_width=11), autoincrement=True, nullable=False),
+    sa.Column('datetime', mysql.DATETIME(), nullable=False),
+    sa.Column('tank_num', mysql.INTEGER(display_width=11), autoincrement=False, nullable=False),
+    sa.Column('status', mysql.TEXT(collation='utf8mb4_unicode_ci'), nullable=False),
+    sa.PrimaryKeyConstraint('sn'),
+    mysql_collate='utf8mb4_unicode_ci',
+    mysql_default_charset='utf8mb4',
+    mysql_engine='InnoDB'
+    )
+    # ### end Alembic commands ###

+ 28 - 0
CoffeeProject/migrations/versions/69d28c0997da_.py

@@ -0,0 +1,28 @@
+"""empty message
+
+Revision ID: 69d28c0997da
+Revises: 7e912759589c
+Create Date: 2021-02-20 16:43:13.121335
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '69d28c0997da'
+down_revision = '7e912759589c'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('relay', sa.Column('test5', sa.Text(), nullable=False))
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('relay', 'test5')
+    # ### end Alembic commands ###

+ 242 - 0
CoffeeProject/migrations/versions/7e912759589c_.py

@@ -0,0 +1,242 @@
+"""empty message
+
+Revision ID: 7e912759589c
+Revises: 
+Create Date: 2021-02-20 16:42:13.616735
+
+"""
+from alembic import op
+import sqlalchemy as sa
+
+
+# revision identifiers, used by Alembic.
+revision = '7e912759589c'
+down_revision = None
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.create_table('bacteria',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('bean_valve',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('bottom_valve',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('cargo1_disinfect',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('cargo2_disinfect',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('color_machine',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('conveyor_belt1',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('conveyor_belt2',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('conveyor_belt3',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('dryer',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('heating',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('hoist',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('peeling_machine',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('relay',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('status', sa.Text(), nullable=False),
+    sa.Column('test4', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('stir',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('tank_co2_sensor',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('co2', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('tank_ph_sensor',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('ph', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('tank_tem_sensor',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('tem', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('temperature',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('top_valve',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('user',
+    sa.Column('userID', sa.Integer(), nullable=False),
+    sa.Column('firstname', sa.String(length=30), nullable=False),
+    sa.Column('lastname', sa.String(length=30), nullable=False),
+    sa.Column('mail', sa.String(length=50), nullable=False),
+    sa.Column('phone', sa.String(length=20), nullable=False),
+    sa.Column('username', sa.String(length=30), nullable=False),
+    sa.Column('password', sa.String(length=40), nullable=False),
+    sa.Column('status', sa.Integer(), nullable=False),
+    sa.PrimaryKeyConstraint('userID'),
+    sa.UniqueConstraint('username')
+    )
+    op.create_table('wash_machine',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    op.create_table('water_injection',
+    sa.Column('sn', sa.Integer(), nullable=False),
+    sa.Column('datetime', sa.DateTime(), nullable=False),
+    sa.Column('tank_num', sa.Integer(), nullable=False),
+    sa.Column('duration', sa.Text(), nullable=False),
+    sa.Column('start', sa.Text(), nullable=False),
+    sa.Column('end', sa.Text(), nullable=False),
+    sa.PrimaryKeyConstraint('sn')
+    )
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_table('water_injection')
+    op.drop_table('wash_machine')
+    op.drop_table('user')
+    op.drop_table('top_valve')
+    op.drop_table('temperature')
+    op.drop_table('tank_tem_sensor')
+    op.drop_table('tank_ph_sensor')
+    op.drop_table('tank_co2_sensor')
+    op.drop_table('stir')
+    op.drop_table('relay')
+    op.drop_table('peeling_machine')
+    op.drop_table('hoist')
+    op.drop_table('heating')
+    op.drop_table('dryer')
+    op.drop_table('conveyor_belt3')
+    op.drop_table('conveyor_belt2')
+    op.drop_table('conveyor_belt1')
+    op.drop_table('color_machine')
+    op.drop_table('cargo2_disinfect')
+    op.drop_table('cargo1_disinfect')
+    op.drop_table('bottom_valve')
+    op.drop_table('bean_valve')
+    op.drop_table('bacteria')
+    # ### end Alembic commands ###

+ 30 - 0
CoffeeProject/migrations/versions/9f72f41f27ab_.py

@@ -0,0 +1,30 @@
+"""empty message
+
+Revision ID: 9f72f41f27ab
+Revises: 69d28c0997da
+Create Date: 2021-02-20 16:44:13.287908
+
+"""
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects import mysql
+
+# revision identifiers, used by Alembic.
+revision = '9f72f41f27ab'
+down_revision = '69d28c0997da'
+branch_labels = None
+depends_on = None
+
+
+def upgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.drop_column('relay', 'test5')
+    op.drop_column('relay', 'test4')
+    # ### end Alembic commands ###
+
+
+def downgrade():
+    # ### commands auto generated by Alembic - please adjust! ###
+    op.add_column('relay', sa.Column('test4', mysql.TEXT(collation='utf8mb4_unicode_ci'), nullable=False))
+    op.add_column('relay', sa.Column('test5', mysql.TEXT(collation='utf8mb4_unicode_ci'), nullable=False))
+    # ### end Alembic commands ###

BIN
CoffeeProject/migrations/versions/__pycache__/3cd641e789b7_.cpython-35.pyc


BIN
CoffeeProject/migrations/versions/__pycache__/3faa6d09ff44_.cpython-35.pyc


BIN
CoffeeProject/migrations/versions/__pycache__/69d28c0997da_.cpython-35.pyc


BIN
CoffeeProject/migrations/versions/__pycache__/7e912759589c_.cpython-35.pyc


BIN
CoffeeProject/migrations/versions/__pycache__/9f72f41f27ab_.cpython-35.pyc


+ 1 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 28 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/LICENSE.rst

@@ -0,0 +1,28 @@
+Copyright 2010 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1.  Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+2.  Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+3.  Neither the name of the copyright holder nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 137 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/METADATA

@@ -0,0 +1,137 @@
+Metadata-Version: 2.1
+Name: Flask
+Version: 1.1.2
+Summary: A simple framework for building complex web applications.
+Home-page: https://palletsprojects.com/p/flask/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
+Maintainer: Pallets
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Documentation, https://flask.palletsprojects.com/
+Project-URL: Code, https://github.com/pallets/flask
+Project-URL: Issue tracker, https://github.com/pallets/flask/issues
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Framework :: Flask
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
+Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Requires-Dist: Werkzeug (>=0.15)
+Requires-Dist: Jinja2 (>=2.10.1)
+Requires-Dist: itsdangerous (>=0.24)
+Requires-Dist: click (>=5.1)
+Provides-Extra: dev
+Requires-Dist: pytest ; extra == 'dev'
+Requires-Dist: coverage ; extra == 'dev'
+Requires-Dist: tox ; extra == 'dev'
+Requires-Dist: sphinx ; extra == 'dev'
+Requires-Dist: pallets-sphinx-themes ; extra == 'dev'
+Requires-Dist: sphinxcontrib-log-cabinet ; extra == 'dev'
+Requires-Dist: sphinx-issues ; extra == 'dev'
+Provides-Extra: docs
+Requires-Dist: sphinx ; extra == 'docs'
+Requires-Dist: pallets-sphinx-themes ; extra == 'docs'
+Requires-Dist: sphinxcontrib-log-cabinet ; extra == 'docs'
+Requires-Dist: sphinx-issues ; extra == 'docs'
+Provides-Extra: dotenv
+Requires-Dist: python-dotenv ; extra == 'dotenv'
+
+Flask
+=====
+
+Flask is a lightweight `WSGI`_ web application framework. It is designed
+to make getting started quick and easy, with the ability to scale up to
+complex applications. It began as a simple wrapper around `Werkzeug`_
+and `Jinja`_ and has become one of the most popular Python web
+application frameworks.
+
+Flask offers suggestions, but doesn't enforce any dependencies or
+project layout. It is up to the developer to choose the tools and
+libraries they want to use. There are many extensions provided by the
+community that make adding new functionality easy.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+    pip install -U Flask
+
+
+A Simple Example
+----------------
+
+.. code-block:: python
+
+    from flask import Flask
+
+    app = Flask(__name__)
+
+    @app.route("/")
+    def hello():
+        return "Hello, World!"
+
+.. code-block:: text
+
+    $ env FLASK_APP=hello.py flask run
+     * Serving Flask app "hello"
+     * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
+
+
+Contributing
+------------
+
+For guidance on setting up a development environment and how to make a
+contribution to Flask, see the `contributing guidelines`_.
+
+.. _contributing guidelines: https://github.com/pallets/flask/blob/master/CONTRIBUTING.rst
+
+
+Donate
+------
+
+The Pallets organization develops and supports Flask and the libraries
+it uses. In order to grow the community of contributors and users, and
+allow the maintainers to devote more time to the projects, `please
+donate today`_.
+
+.. _please donate today: https://psfmember.org/civicrm/contribute/transact?reset=1&id=20
+
+
+Links
+-----
+
+* Website: https://palletsprojects.com/p/flask/
+* Documentation: https://flask.palletsprojects.com/
+* Releases: https://pypi.org/project/Flask/
+* Code: https://github.com/pallets/flask
+* Issue tracker: https://github.com/pallets/flask/issues
+* Test status: https://dev.azure.com/pallets/flask/_build
+* Official chat: https://discord.gg/t6rrQZH
+
+.. _WSGI: https://wsgi.readthedocs.io
+.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/
+.. _Jinja: https://www.palletsprojects.com/p/jinja/
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+

+ 48 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/RECORD

@@ -0,0 +1,48 @@
+../../Scripts/flask.exe,sha256=yMBk8Z2asicCwrgd3YXEZjvy_KxpVfVGRMXc0wYM4PA,106378
+Flask-1.1.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+Flask-1.1.2.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
+Flask-1.1.2.dist-info/METADATA,sha256=3INpPWH6nKfZ33R2N-bQZy4TOe1wQCMweZc9mwcNrtc,4591
+Flask-1.1.2.dist-info/RECORD,,
+Flask-1.1.2.dist-info/WHEEL,sha256=8zNYZbwQSXoB9IfXOjPfeNwvAsALAjffgk27FqvCWbo,110
+Flask-1.1.2.dist-info/entry_points.txt,sha256=gBLA1aKg0OYR8AhbAfg8lnburHtKcgJLDU52BBctN0k,42
+Flask-1.1.2.dist-info/top_level.txt,sha256=dvi65F6AeGWVU0TBpYiC04yM60-FX1gJFkK31IKQr5c,6
+flask/__init__.py,sha256=YnA9wkwbJcnb_jTT-nMsMFeFE_UWt33khKzdHmMSuyI,1894
+flask/__main__.py,sha256=fjVtt3QTANXlpJCOv3Ha7d5H-76MwzSIOab7SFD9TEk,254
+flask/__pycache__/__init__.cpython-35.pyc,,
+flask/__pycache__/__main__.cpython-35.pyc,,
+flask/__pycache__/_compat.cpython-35.pyc,,
+flask/__pycache__/app.cpython-35.pyc,,
+flask/__pycache__/blueprints.cpython-35.pyc,,
+flask/__pycache__/cli.cpython-35.pyc,,
+flask/__pycache__/config.cpython-35.pyc,,
+flask/__pycache__/ctx.cpython-35.pyc,,
+flask/__pycache__/debughelpers.cpython-35.pyc,,
+flask/__pycache__/globals.cpython-35.pyc,,
+flask/__pycache__/helpers.cpython-35.pyc,,
+flask/__pycache__/logging.cpython-35.pyc,,
+flask/__pycache__/sessions.cpython-35.pyc,,
+flask/__pycache__/signals.cpython-35.pyc,,
+flask/__pycache__/templating.cpython-35.pyc,,
+flask/__pycache__/testing.cpython-35.pyc,,
+flask/__pycache__/views.cpython-35.pyc,,
+flask/__pycache__/wrappers.cpython-35.pyc,,
+flask/_compat.py,sha256=8KPT54Iig96TuLipdogLRHNYToIcg-xPhnSV5VRERnw,4099
+flask/app.py,sha256=tmEhx_XrIRP24vZg39dHMWFzJ2jj-YxIcd51LaIT5cE,98059
+flask/blueprints.py,sha256=vkdm8NusGsfZUeIfPdCluj733QFmiQcT4Sk1tuZLUjw,21400
+flask/cli.py,sha256=SIb22uq9wYBeB2tKMl0pYdhtZ1MAQyZtPL-3m6es4G0,31035
+flask/config.py,sha256=3dejvQRYfNHw_V7dCLMxU8UNFpL34xIKemN7gHZIZ8Y,10052
+flask/ctx.py,sha256=cks-omGedkxawHFo6bKIrdOHsJCAgg1i_NWw_htxb5U,16724
+flask/debughelpers.py,sha256=-whvPKuAoU8AZ9c1z_INuOeBgfYDqE1J2xNBsoriugU,6475
+flask/globals.py,sha256=OgcHb6_NCyX6-TldciOdKcyj4PNfyQwClxdMhvov6aA,1637
+flask/helpers.py,sha256=IHa578HU_3XAAo1wpXQv24MYRYO5TzaiDQQwvUIcE6Q,43074
+flask/json/__init__.py,sha256=6nITbZYiYOPB8Qfi1-dvsblwn01KRz8VOsMBIZyaYek,11988
+flask/json/__pycache__/__init__.cpython-35.pyc,,
+flask/json/__pycache__/tag.cpython-35.pyc,,
+flask/json/tag.py,sha256=vq9GOllg_0kTWKuVFrwmkeOQzR-jdBD23x-89JyCCQI,8306
+flask/logging.py,sha256=WcY5UkqTysGfmosyygSlXyZYGwOp3y-VsE6ehoJ48dk,3250
+flask/sessions.py,sha256=G0KsEkr_i1LG_wOINwFSOW3ts7Xbv4bNgEZKc7TRloc,14360
+flask/signals.py,sha256=yYLOed2x8WnQ7pirGalQYfpYpCILJ0LJhmNSrnWvjqw,2212
+flask/templating.py,sha256=F8E_IZXn9BGsjMzUJ5N_ACMyZdiFBp_SSEaUunvfZ7g,4939
+flask/testing.py,sha256=WXsciCQbHBP7xjHqNvOA4bT0k86GvSNpgzncfXLDEEg,10146
+flask/views.py,sha256=eeWnadLAj0QdQPLtjKipDetRZyG62CT2y7fNOFDJz0g,5802
+flask/wrappers.py,sha256=kgsvtZuMM6RQaDqhRbc5Pcj9vqTnaERl2pmXcdGL7LU,4736

+ 6 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/WHEEL

@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.33.6)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+

+ 3 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/entry_points.txt

@@ -0,0 +1,3 @@
+[console_scripts]
+flask = flask.cli:main
+

+ 1 - 0
CoffeeProject/venv/Lib/site-packages/Flask-1.1.2.dist-info/top_level.txt

@@ -0,0 +1 @@
+flask

+ 1 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 28 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/LICENSE.rst

@@ -0,0 +1,28 @@
+Copyright 2007 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1.  Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+2.  Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+3.  Neither the name of the copyright holder nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 106 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/METADATA

@@ -0,0 +1,106 @@
+Metadata-Version: 2.1
+Name: Jinja2
+Version: 2.11.2
+Summary: A very fast and expressive template engine.
+Home-page: https://palletsprojects.com/p/jinja/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
+Maintainer: Pallets
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Documentation, https://jinja.palletsprojects.com/
+Project-URL: Code, https://github.com/pallets/jinja
+Project-URL: Issue tracker, https://github.com/pallets/jinja/issues
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Text Processing :: Markup :: HTML
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Description-Content-Type: text/x-rst
+Requires-Dist: MarkupSafe (>=0.23)
+Provides-Extra: i18n
+Requires-Dist: Babel (>=0.8) ; extra == 'i18n'
+
+Jinja
+=====
+
+Jinja is a fast, expressive, extensible templating engine. Special
+placeholders in the template allow writing code similar to Python
+syntax. Then the template is passed data to render the final document.
+
+It includes:
+
+-   Template inheritance and inclusion.
+-   Define and import macros within templates.
+-   HTML templates can use autoescaping to prevent XSS from untrusted
+    user input.
+-   A sandboxed environment can safely render untrusted templates.
+-   AsyncIO support for generating templates and calling async
+    functions.
+-   I18N support with Babel.
+-   Templates are compiled to optimized Python code just-in-time and
+    cached, or can be compiled ahead-of-time.
+-   Exceptions point to the correct line in templates to make debugging
+    easier.
+-   Extensible filters, tests, functions, and even syntax.
+
+Jinja's philosophy is that while application logic belongs in Python if
+possible, it shouldn't make the template designer's job difficult by
+restricting functionality too much.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+    $ pip install -U Jinja2
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+In A Nutshell
+-------------
+
+.. code-block:: jinja
+
+    {% extends "base.html" %}
+    {% block title %}Members{% endblock %}
+    {% block content %}
+      <ul>
+      {% for user in users %}
+        <li><a href="{{ user.url }}">{{ user.username }}</a></li>
+      {% endfor %}
+      </ul>
+    {% endblock %}
+
+
+Links
+-----
+
+-   Website: https://palletsprojects.com/p/jinja/
+-   Documentation: https://jinja.palletsprojects.com/
+-   Releases: https://pypi.org/project/Jinja2/
+-   Code: https://github.com/pallets/jinja
+-   Issue tracker: https://github.com/pallets/jinja/issues
+-   Test status: https://dev.azure.com/pallets/jinja/_build
+-   Official chat: https://discord.gg/t6rrQZH
+
+

+ 59 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/RECORD

@@ -0,0 +1,59 @@
+Jinja2-2.11.2.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+Jinja2-2.11.2.dist-info/LICENSE.rst,sha256=O0nc7kEF6ze6wQ-vG-JgQI_oXSUrjp3y4JefweCUQ3s,1475
+Jinja2-2.11.2.dist-info/METADATA,sha256=5ZHRZoIRAMHsJPnqhlJ622_dRPsYePYJ-9EH4-Ry7yI,3535
+Jinja2-2.11.2.dist-info/RECORD,,
+Jinja2-2.11.2.dist-info/WHEEL,sha256=kGT74LWyRUZrL4VgLh6_g12IeVl_9u9ZVhadrgXZUEY,110
+Jinja2-2.11.2.dist-info/entry_points.txt,sha256=Qy_DkVo6Xj_zzOtmErrATe8lHZhOqdjpt3e4JJAGyi8,61
+Jinja2-2.11.2.dist-info/top_level.txt,sha256=PkeVWtLb3-CqjWi1fO29OCbj55EhX_chhKrCdrVe_zs,7
+jinja2/__init__.py,sha256=0QCM_jKKDM10yzSdHRVV4mQbCbDqf0GN0GirAqibn9Y,1549
+jinja2/__pycache__/__init__.cpython-35.pyc,,
+jinja2/__pycache__/_compat.cpython-35.pyc,,
+jinja2/__pycache__/_identifier.cpython-35.pyc,,
+jinja2/__pycache__/bccache.cpython-35.pyc,,
+jinja2/__pycache__/compiler.cpython-35.pyc,,
+jinja2/__pycache__/constants.cpython-35.pyc,,
+jinja2/__pycache__/debug.cpython-35.pyc,,
+jinja2/__pycache__/defaults.cpython-35.pyc,,
+jinja2/__pycache__/environment.cpython-35.pyc,,
+jinja2/__pycache__/exceptions.cpython-35.pyc,,
+jinja2/__pycache__/ext.cpython-35.pyc,,
+jinja2/__pycache__/filters.cpython-35.pyc,,
+jinja2/__pycache__/idtracking.cpython-35.pyc,,
+jinja2/__pycache__/lexer.cpython-35.pyc,,
+jinja2/__pycache__/loaders.cpython-35.pyc,,
+jinja2/__pycache__/meta.cpython-35.pyc,,
+jinja2/__pycache__/nativetypes.cpython-35.pyc,,
+jinja2/__pycache__/nodes.cpython-35.pyc,,
+jinja2/__pycache__/optimizer.cpython-35.pyc,,
+jinja2/__pycache__/parser.cpython-35.pyc,,
+jinja2/__pycache__/runtime.cpython-35.pyc,,
+jinja2/__pycache__/sandbox.cpython-35.pyc,,
+jinja2/__pycache__/tests.cpython-35.pyc,,
+jinja2/__pycache__/utils.cpython-35.pyc,,
+jinja2/__pycache__/visitor.cpython-35.pyc,,
+jinja2/_compat.py,sha256=B6Se8HjnXVpzz9-vfHejn-DV2NjaVK-Iewupc5kKlu8,3191
+jinja2/_identifier.py,sha256=EdgGJKi7O1yvr4yFlvqPNEqV6M1qHyQr8Gt8GmVTKVM,1775
+jinja2/asyncfilters.py,sha256=XJtYXTxFvcJ5xwk6SaDL4S0oNnT0wPYvXBCSzc482fI,4250
+jinja2/asyncsupport.py,sha256=ZBFsDLuq3Gtji3Ia87lcyuDbqaHZJRdtShZcqwpFnSQ,7209
+jinja2/bccache.py,sha256=3Pmp4jo65M9FQuIxdxoDBbEDFwe4acDMQf77nEJfrHA,12139
+jinja2/compiler.py,sha256=Ta9W1Lit542wItAHXlDcg0sEOsFDMirCdlFPHAurg4o,66284
+jinja2/constants.py,sha256=RR1sTzNzUmKco6aZicw4JpQpJGCuPuqm1h1YmCNUEFY,1458
+jinja2/debug.py,sha256=neR7GIGGjZH3_ILJGVUYy3eLQCCaWJMXOb7o0kGInWc,8529
+jinja2/defaults.py,sha256=85B6YUUCyWPSdrSeVhcqFVuu_bHUAQXeey--FIwSeVQ,1126
+jinja2/environment.py,sha256=XDSLKc4SqNLMOwTSq3TbWEyA5WyXfuLuVD0wAVjEFwM,50629
+jinja2/exceptions.py,sha256=VjNLawcmf2ODffqVMCQK1cRmvFaUfQWF4u8ouP3QPcE,5425
+jinja2/ext.py,sha256=AtwL5O5enT_L3HR9-oBvhGyUTdGoyaqG_ICtnR_EVd4,26441
+jinja2/filters.py,sha256=_RpPgAlgIj7ExvyDzcHAC3B36cocfWK-1TEketbNeM0,41415
+jinja2/idtracking.py,sha256=J3O4VHsrbf3wzwiBc7Cro26kHb6_5kbULeIOzocchIU,9211
+jinja2/lexer.py,sha256=nUFLRKhhKmmEWkLI65nQePgcQs7qsRdjVYZETMt_v0g,30331
+jinja2/loaders.py,sha256=C-fST_dmFjgWkp0ZuCkrgICAoOsoSIF28wfAFink0oU,17666
+jinja2/meta.py,sha256=QjyYhfNRD3QCXjBJpiPl9KgkEkGXJbAkCUq4-Ur10EQ,4131
+jinja2/nativetypes.py,sha256=Ul__gtVw4xH-0qvUvnCNHedQeNDwmEuyLJztzzSPeRg,2753
+jinja2/nodes.py,sha256=Mk1oJPVgIjnQw9WOqILvcu3rLepcFZ0ahxQm2mbwDwc,31095
+jinja2/optimizer.py,sha256=gQLlMYzvQhluhzmAIFA1tXS0cwgWYOjprN-gTRcHVsc,1457
+jinja2/parser.py,sha256=fcfdqePNTNyvosIvczbytVA332qpsURvYnCGcjDHSkA,35660
+jinja2/runtime.py,sha256=0y-BRyIEZ9ltByL2Id6GpHe1oDRQAwNeQvI0SKobNMw,30618
+jinja2/sandbox.py,sha256=knayyUvXsZ-F0mk15mO2-ehK9gsw04UhB8td-iUOtLc,17127
+jinja2/tests.py,sha256=iO_Y-9Vo60zrVe1lMpSl5sKHqAxe2leZHC08OoZ8K24,4799
+jinja2/utils.py,sha256=OoVMlQe9S2-lWT6jJbTu9tDuDvGNyWUhHDcE51i5_Do,22522
+jinja2/visitor.py,sha256=DUHupl0a4PGp7nxRtZFttUzAi1ccxzqc2hzetPYUz8U,3240

+ 6 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/WHEEL

@@ -0,0 +1,6 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.34.2)
+Root-Is-Purelib: true
+Tag: py2-none-any
+Tag: py3-none-any
+

+ 3 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/entry_points.txt

@@ -0,0 +1,3 @@
+[babel.extractors]
+jinja2 = jinja2.ext:babel_extract [i18n]
+

+ 1 - 0
CoffeeProject/venv/Lib/site-packages/Jinja2-2.11.2.dist-info/top_level.txt

@@ -0,0 +1 @@
+jinja2

+ 1 - 0
CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 28 - 0
CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/LICENSE.rst

@@ -0,0 +1,28 @@
+Copyright 2010 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1.  Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+2.  Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+3.  Neither the name of the copyright holder nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 103 - 0
CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/METADATA

@@ -0,0 +1,103 @@
+Metadata-Version: 2.1
+Name: MarkupSafe
+Version: 1.1.1
+Summary: Safely add untrusted strings to HTML/XML markup.
+Home-page: https://palletsprojects.com/p/markupsafe/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
+Maintainer: The Pallets Team
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Documentation, https://markupsafe.palletsprojects.com/
+Project-URL: Code, https://github.com/pallets/markupsafe
+Project-URL: Issue tracker, https://github.com/pallets/markupsafe/issues
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.4
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Classifier: Topic :: Text Processing :: Markup :: HTML
+Requires-Python: >=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*
+
+MarkupSafe
+==========
+
+MarkupSafe implements a text object that escapes characters so it is
+safe to use in HTML and XML. Characters that have special meanings are
+replaced so that they display as the actual characters. This mitigates
+injection attacks, meaning untrusted user input can safely be displayed
+on a page.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+    pip install -U MarkupSafe
+
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+
+Examples
+--------
+
+.. code-block:: pycon
+
+    >>> from markupsafe import Markup, escape
+    >>> # escape replaces special characters and wraps in Markup
+    >>> escape('<script>alert(document.cookie);</script>')
+    Markup(u'&lt;script&gt;alert(document.cookie);&lt;/script&gt;')
+    >>> # wrap in Markup to mark text "safe" and prevent escaping
+    >>> Markup('<strong>Hello</strong>')
+    Markup('<strong>hello</strong>')
+    >>> escape(Markup('<strong>Hello</strong>'))
+    Markup('<strong>hello</strong>')
+    >>> # Markup is a text subclass (str on Python 3, unicode on Python 2)
+    >>> # methods and operators escape their arguments
+    >>> template = Markup("Hello <em>%s</em>")
+    >>> template % '"World"'
+    Markup('Hello <em>&#34;World&#34;</em>')
+
+
+Donate
+------
+
+The Pallets organization develops and supports MarkupSafe and other
+libraries that use it. In order to grow the community of contributors
+and users, and allow the maintainers to devote more time to the
+projects, `please donate today`_.
+
+.. _please donate today: https://palletsprojects.com/donate
+
+
+Links
+-----
+
+*   Website: https://palletsprojects.com/p/markupsafe/
+*   Documentation: https://markupsafe.palletsprojects.com/
+*   License: `BSD-3-Clause <https://github.com/pallets/markupsafe/blob/master/LICENSE.rst>`_
+*   Releases: https://pypi.org/project/MarkupSafe/
+*   Code: https://github.com/pallets/markupsafe
+*   Issue tracker: https://github.com/pallets/markupsafe/issues
+*   Test status:
+
+    *   Linux, Mac: https://travis-ci.org/pallets/markupsafe
+    *   Windows: https://ci.appveyor.com/project/pallets/markupsafe
+
+*   Test coverage: https://codecov.io/gh/pallets/markupsafe
+
+

+ 15 - 0
CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/RECORD

@@ -0,0 +1,15 @@
+MarkupSafe-1.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
+MarkupSafe-1.1.1.dist-info/LICENSE.rst,sha256=SJqOEQhQntmKN7uYPhHg9-HTHwvY-Zp5yESOf_N9B-o,1475
+MarkupSafe-1.1.1.dist-info/METADATA,sha256=nJHwJ4_4ka-V39QH883jPrslj6inNdyyNASBXbYgHXQ,3570
+MarkupSafe-1.1.1.dist-info/RECORD,,
+MarkupSafe-1.1.1.dist-info/WHEEL,sha256=Q_8UIgV2becTkGqdKVgmaXdyabd83UTktF08jttIiu0,106
+MarkupSafe-1.1.1.dist-info/top_level.txt,sha256=qy0Plje5IJuvsCBjejJyhDCjEAdcDLK_2agVcex8Z6U,11
+markupsafe/__init__.py,sha256=oTblO5f9KFM-pvnq9bB0HgElnqkJyqHnFN1Nx2NIvnY,10126
+markupsafe/__pycache__/__init__.cpython-35.pyc,,
+markupsafe/__pycache__/_compat.cpython-35.pyc,,
+markupsafe/__pycache__/_constants.cpython-35.pyc,,
+markupsafe/__pycache__/_native.cpython-35.pyc,,
+markupsafe/_compat.py,sha256=uEW1ybxEjfxIiuTbRRaJpHsPFf4yQUMMKaPgYEC5XbU,558
+markupsafe/_constants.py,sha256=zo2ajfScG-l1Sb_52EP3MlDCqO7Y1BVHUXXKRsVDRNk,4690
+markupsafe/_native.py,sha256=d-8S_zzYt2y512xYcuSxq0NeG2DUUvG80wVdTn-4KI8,1873
+markupsafe/_speedups.cp35-win_amd64.pyd,sha256=Gl6I45geMZhMkY1_2_MkvzYKIwFyARHjzSKzI7ZGIFU,15360

+ 5 - 0
CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/WHEEL

@@ -0,0 +1,5 @@
+Wheel-Version: 1.0
+Generator: bdist_wheel (0.33.1)
+Root-Is-Purelib: false
+Tag: cp35-cp35m-win_amd64
+

+ 1 - 0
CoffeeProject/venv/Lib/site-packages/MarkupSafe-1.1.1.dist-info/top_level.txt

@@ -0,0 +1 @@
+markupsafe

+ 1 - 0
CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/INSTALLER

@@ -0,0 +1 @@
+pip

+ 28 - 0
CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/LICENSE.rst

@@ -0,0 +1,28 @@
+Copyright 2007 Pallets
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1.  Redistributions of source code must retain the above copyright
+    notice, this list of conditions and the following disclaimer.
+
+2.  Redistributions in binary form must reproduce the above copyright
+    notice, this list of conditions and the following disclaimer in the
+    documentation and/or other materials provided with the distribution.
+
+3.  Neither the name of the copyright holder nor the names of its
+    contributors may be used to endorse or promote products derived from
+    this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

+ 128 - 0
CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/METADATA

@@ -0,0 +1,128 @@
+Metadata-Version: 2.1
+Name: Werkzeug
+Version: 1.0.1
+Summary: The comprehensive WSGI web application library.
+Home-page: https://palletsprojects.com/p/werkzeug/
+Author: Armin Ronacher
+Author-email: armin.ronacher@active-4.com
+Maintainer: Pallets
+Maintainer-email: contact@palletsprojects.com
+License: BSD-3-Clause
+Project-URL: Documentation, https://werkzeug.palletsprojects.com/
+Project-URL: Code, https://github.com/pallets/werkzeug
+Project-URL: Issue tracker, https://github.com/pallets/werkzeug/issues
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Environment :: Web Environment
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: BSD License
+Classifier: Operating System :: OS Independent
+Classifier: Programming Language :: Python
+Classifier: Programming Language :: Python :: 2
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.5
+Classifier: Programming Language :: Python :: 3.6
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: Implementation :: CPython
+Classifier: Programming Language :: Python :: Implementation :: PyPy
+Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
+Classifier: Topic :: Internet :: WWW/HTTP :: WSGI
+Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Application
+Classifier: Topic :: Internet :: WWW/HTTP :: WSGI :: Middleware
+Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
+Classifier: Topic :: Software Development :: Libraries :: Python Modules
+Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*
+Description-Content-Type: text/x-rst
+Provides-Extra: dev
+Requires-Dist: pytest ; extra == 'dev'
+Requires-Dist: pytest-timeout ; extra == 'dev'
+Requires-Dist: coverage ; extra == 'dev'
+Requires-Dist: tox ; extra == 'dev'
+Requires-Dist: sphinx ; extra == 'dev'
+Requires-Dist: pallets-sphinx-themes ; extra == 'dev'
+Requires-Dist: sphinx-issues ; extra == 'dev'
+Provides-Extra: watchdog
+Requires-Dist: watchdog ; extra == 'watchdog'
+
+Werkzeug
+========
+
+*werkzeug* German noun: "tool". Etymology: *werk* ("work"), *zeug* ("stuff")
+
+Werkzeug is a comprehensive `WSGI`_ web application library. It began as
+a simple collection of various utilities for WSGI applications and has
+become one of the most advanced WSGI utility libraries.
+
+It includes:
+
+-   An interactive debugger that allows inspecting stack traces and
+    source code in the browser with an interactive interpreter for any
+    frame in the stack.
+-   A full-featured request object with objects to interact with
+    headers, query args, form data, files, and cookies.
+-   A response object that can wrap other WSGI applications and handle
+    streaming data.
+-   A routing system for matching URLs to endpoints and generating URLs
+    for endpoints, with an extensible system for capturing variables
+    from URLs.
+-   HTTP utilities to handle entity tags, cache control, dates, user
+    agents, cookies, files, and more.
+-   A threaded WSGI server for use while developing applications
+    locally.
+-   A test client for simulating HTTP requests during testing without
+    requiring running a server.
+
+Werkzeug is Unicode aware and doesn't enforce any dependencies. It is up
+to the developer to choose a template engine, database adapter, and even
+how to handle requests. It can be used to build all sorts of end user
+applications such as blogs, wikis, or bulletin boards.
+
+`Flask`_ wraps Werkzeug, using it to handle the details of WSGI while
+providing more structure and patterns for defining powerful
+applications.
+
+
+Installing
+----------
+
+Install and update using `pip`_:
+
+.. code-block:: text
+
+    pip install -U Werkzeug
+
+
+A Simple Example
+----------------
+
+.. code-block:: python
+
+    from werkzeug.wrappers import Request, Response
+
+    @Request.application
+    def application(request):
+        return Response('Hello, World!')
+
+    if __name__ == '__main__':
+        from werkzeug.serving import run_simple
+        run_simple('localhost', 4000, application)
+
+
+Links
+-----
+
+-   Website: https://palletsprojects.com/p/werkzeug/
+-   Documentation: https://werkzeug.palletsprojects.com/
+-   Releases: https://pypi.org/project/Werkzeug/
+-   Code: https://github.com/pallets/werkzeug
+-   Issue tracker: https://github.com/pallets/werkzeug/issues
+-   Test status: https://dev.azure.com/pallets/werkzeug/_build
+-   Official chat: https://discord.gg/t6rrQZH
+
+.. _WSGI: https://wsgi.readthedocs.io/en/latest/
+.. _Flask: https://www.palletsprojects.com/p/flask/
+.. _pip: https://pip.pypa.io/en/stable/quickstart/
+
+

+ 0 - 0
CoffeeProject/venv/Lib/site-packages/Werkzeug-1.0.1.dist-info/RECORD


Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä