Skip to content

Commit

Permalink
Added configs, updated mqtt singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
graham22 committed Mar 3, 2021
1 parent b31b56e commit 77ea773
Show file tree
Hide file tree
Showing 20 changed files with 340 additions and 188 deletions.
2 changes: 1 addition & 1 deletion code/Python/WebApp/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"python.pythonPath": "c:\\Users\\Me\\Dev\\Github\\BatteryTester\\code\\Python\\WebApp\\env\\Scripts\\python.exe"
"python.languageServer": "Pylance"
}
17 changes: 9 additions & 8 deletions code/Python/WebApp/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
FROM tiangolo/uwsgi-nginx-flask:latest

# Set the working directory to /app
WORKDIR /app
#
# # Copy the current directory contents into the container at /app
ADD requirements.txt /app
COPY ./app /app
WORKDIR /BatteryTester
ENV STATIC_URL /static
ENV STATIC_PATH /BatteryTester/app/static
ADD requirements.txt /BatteryTester
ADD main.py /BatteryTester
ADD config.py /BatteryTester
ADD uwsgi.ini /BatteryTester
COPY ./app /BatteryTester/app
# # Install the dependencies
RUN pip install -r requirements.txt

# run the command to start uWSGI
# CMD ["uwsgi", "app.ini"]
# CMD ["uwsgi", "uwsgi.ini"]
14 changes: 14 additions & 0 deletions code/Python/WebApp/Dockerfile-pi
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM crawforc3/raspberrypi-uwsgi-nginx-flask:latest
WORKDIR /BatteryTester
ENV STATIC_URL /static
ENV STATIC_PATH /BatteryTester/app/static
ADD requirements.txt /BatteryTester
ADD main.py /BatteryTester
ADD config.py /BatteryTester
ADD uwsgi.ini /BatteryTester
COPY ./app /BatteryTester/app
# # Install the dependencies
RUN pip install -r requirements.txt

# run the command to start uWSGI
# CMD ["uwsgi", "uwsgi.ini"]
179 changes: 105 additions & 74 deletions code/Python/WebApp/app/__init__.py
Original file line number Diff line number Diff line change
@@ -1,96 +1,127 @@
from flask import Flask, Response, request, url_for, render_template, jsonify, session, Config
from flask import (
Flask,
Response,
request,
url_for,
redirect,
render_template,
jsonify,
session,
Config,
g
)
from multiprocessing import Queue, Value
import json
from .settings import settings
from .firmware import firmware
from .mqtt import run, mqttPublish
from .mqtt import mqtt
from .logger import log
from .message import Message

# --------------------------------------------------------------------------- #
# --------------------------------------------------------------------------- #
# Sharing Data Between Processes Using multiprocessing Queue
# --------------------------------------------------------------------------- #
theQueue = Queue()
cellCount = Value('i', 0)
# --------------------------------------------------------------------------- #
theQueue = Queue()
testers = Value("i", 0)


def create_app(config_class=Config):
# create and configure the app
app = Flask(__name__)
app.config.from_object(config_class)
app.register_blueprint(settings, url_prefix="")
app.register_blueprint(firmware, url_prefix="")
init_app()

@app.route("/")
def render_index():
return render_template("index.html", operation = 'Monitor', cellCount = cellCount.value)

@app.route('/operation', methods=['POST'])
def operation():
current_operation = request.form.get("operation")
mqttPublish(current_operation, "operation")
return jsonify(status="success")

@app.route("/listen")
def listen():
def respond_to_client():
global theQueue
while not theQueue.empty():
theMessage = theQueue.get()
yield f"data: {theMessage.data}\nevent: {theMessage.topic}\n\n"
return Response(respond_to_client(), mimetype='text/event-stream')
return app

# --------------------------------------------------------------------------- #
# create and configure the app
app = Flask(__name__)
if app.config["ENV"] == "production":
app.config.from_object("config.ProductionConfig")
else:
app.config.from_object("config.DevelopmentConfig")
app.register_blueprint(settings, url_prefix="")
app.register_blueprint(firmware, url_prefix="")

print(app.config)
with app.app_context():
init_mqtt()
# @app.teardown_appcontext
# def teardown_mqtt(exception):
# log.debug("************teardown_mqtt************")
# mqtt = g.pop('mqtt', None)
# if mqtt is not None:
# mqtt.disconnect()
@app.route("/")
def render_index():
session["testers"] = testers.value
return render_template(
"index.html", operation="Monitor", cellCount=testers.value * 2
)

@app.route("/refresh")
def render_refresh():
testers.value = 0
con = mqtt.instance()
con.mqttPublish("", "ping")
return redirect(url_for("render_index"))

@app.route("/operation", methods=["POST"])
def operation():
current_operation = request.form.get("operation")
con = mqtt.instance()
con.mqttPublish(current_operation, "operation")
return jsonify(status="success")

@app.route("/listen")
def listen():
def respond_to_client():
global theQueue
while not theQueue.empty():
theMessage = theQueue.get()
yield f"data: {theMessage.data}\nevent: {theMessage.topic}\n\n"

return Response(respond_to_client(), mimetype="text/event-stream")

return app


# --------------------------------------------------------------------------- #
# MQTT On Message
# --------------------------------------------------------------------------- #
# --------------------------------------------------------------------------- #


def on_stat(client, userdata, message):

global theQueue
msg = message.payload.decode(encoding='UTF-8')
log.debug("Received STAT {} : {}".format(message.topic, msg))
if "monitor" in message.topic:
message = json.loads(msg)
theMessage = Message("monitor", json.dumps(message))
theQueue.put(theMessage)
elif "mode" in message.topic:
message = json.loads(msg)
theMessage = Message("mode", json.dumps(message))
theQueue.put(theMessage)
elif "result" in message.topic:
message = json.loads(msg)
theMessage = Message("result", json.dumps(message))
theQueue.put(theMessage)
global theQueue
msg = message.payload.decode(encoding="UTF-8")
log.debug("Received STAT {} : {}".format(message.topic, msg))
if "monitor" in message.topic:
theMessage = Message("monitor", json.dumps(json.loads(msg)))
theQueue.put(theMessage)
elif "mode" in message.topic:
theMessage = Message("mode", json.dumps(json.loads(msg)))
theQueue.put(theMessage)
elif "result" in message.topic:
theMessage = Message("result", json.dumps(json.loads(msg)))
theQueue.put(theMessage)


def on_tele(client, userdata, message):
global testers
msg = message.payload.decode(encoding="UTF-8").upper()
log.debug("Received TELE {} : {}".format(message.topic, msg))
if "ping" in message.topic:
pl = json.loads(msg)
tester = int(pl["TESTERNUMBER"])
if tester > testers.value:
testers.value = tester
log.debug("cellCount at on_tele {} ".format(testers.value))

global cellCount
msg = message.payload.decode(encoding='UTF-8').upper()
log.debug("Received TELE {} : {}".format(message.topic, msg))
if "ping" in message.topic:
cellCount.value += 2
log.debug("cellCount at on_tele {} ".format(cellCount.value))

def on_cmnd(client, userdata, message):

global theQueue
msg = message.payload.decode(encoding='UTF-8')
log.debug("Received CMND {} : {}".format(message.topic, msg))
if "operation" in message.topic:
theMessage = Message("operation", msg)
theQueue.put(theMessage)

def init_app():
log.info("********************************************BatteryTester init()")
cellCount.value = 0
run(on_stat, on_tele, on_cmnd)

# if __name__ == "__main__":
# log.info("BatteryTester starting up in debug mode...")
# init_app()
# app.run(host='0.0.0.0', debug=True, port=80)
global theQueue
msg = message.payload.decode(encoding="UTF-8")
log.debug("Received CMND {} : {}".format(message.topic, msg))
if "operation" in message.topic:
theMessage = Message("operation", msg)
theQueue.put(theMessage)


def init_mqtt():
testers.value = 0
con = mqtt.instance(on_stat, on_tele, on_cmnd)
log.info("************BatteryTester init_mqtt()*********")


67 changes: 54 additions & 13 deletions code/Python/WebApp/app/firmware.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,41 @@
from flask import Blueprint, request, redirect, render_template, url_for, flash, send_file
from flask import current_app
from flask import (
Blueprint,
request,
redirect,
render_template,
url_for,
flash,
send_file,
jsonify,
session,
g,
current_app
)
from .mqtt import mqtt
from werkzeug.utils import secure_filename
import os
import json
import socket

firmware = Blueprint(
"firmware", __name__, static_folder="static", template_folder="templates"
)

firmware = Blueprint("firmware", __name__, static_folder="static", template_folder="templates")
@firmware.route("/update_firmware")
def firmware_page():
return render_template("firmware.html")
global testers
return render_template("firmware.html", devices = session["testers"])


@firmware.route("/publishOta", methods=["POST"])
def operation():
data = {}
data["ServerUrl"] = "http://" + os.getenv("HostName", "localhost") + "/firmware"
json_data = json.dumps(data)
con = mqtt.instance()
con.mqttPublish(json_data,"5/flash")
return jsonify(status="success")


def allowed_file(filename):
if not "." in filename:
Expand All @@ -17,27 +46,39 @@ def allowed_file(filename):
else:
return False


@firmware.route("/upload-firmware", methods=["GET", "POST"])
def upload_firmware():
if request.method == "POST":
# check if the post request has the file part
if 'image' not in request.files:
flash('No file part')
image = request.files['image']
if "image" not in request.files:
flash("No file part")
image = request.files["image"]
# if user does not select file, browser also submit an empty part without filename
if image.filename == '':
flash('No selected file')
if image.filename == "":
flash("No selected file")
if image and allowed_file(image.filename):
filename = secure_filename(image.filename)
image.save(os.path.join(current_app.root_path, current_app.config["FIRMWARE_UPLOADS"], image.filename))
image.save(
os.path.join(
current_app.root_path,
current_app.config["FIRMWARE_UPLOADS"],
image.filename,
)
)
print("Image Saved")
return render_template("firmware.html")

@firmware.route('/firmware')

@firmware.route("/firmware")
def download_firmware():
firmware = os.path.join(current_app.root_path, current_app.config["FIRMWARE_UPLOADS"], "firmware.bin")
firmware = os.path.join(
current_app.root_path, current_app.config["FIRMWARE_UPLOADS"], "firmware.bin"
)
print("Firmware: {}".format(firmware))
if os.path.exists(firmware):
return send_file(firmware, mimetype='application/octet-stream', as_attachment=True)
return send_file(
firmware, mimetype="application/octet-stream", as_attachment=True
)
else:
firmware.errorhandler(404)
2 changes: 1 addition & 1 deletion code/Python/WebApp/app/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
log = logging.getLogger('battery_tester')
if not log.handlers:
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('(%(process)d):%(name)s:%(message)s')
formatter = logging.Formatter('[pid:%(process)d]:%(name)s:%(message)s')
handler.setFormatter(formatter)
log.addHandler(handler)
log.setLevel(os.environ.get("LOGLEVEL", "DEBUG"))
Loading

0 comments on commit 77ea773

Please sign in to comment.