1st Version with a web and flask server on the device

This commit is contained in:
2024-03-20 21:32:56 +01:00
parent fcaa0d5d72
commit f9a4bf7d8d
22 changed files with 975 additions and 51 deletions

View File

@@ -21,7 +21,7 @@ Patches
Please submit any patches against the vrpmdv-webserver layer to the xxxx mailing list (xxxx@zzzz.org)
and cc: the maintainer:
Maintainer: XXX YYYYYY <xxx.yyyyyy@zzzzz.com>
Maintainer: Markus Lehr <markus@malehr.de>
Table of Contents
=================
@@ -39,3 +39,5 @@ II. Misc
========
--- replace with specific information about the vrpmdv-webserver layer ---
~/STM32MPU_workspace/STM32MP1-Ecosystem-V6.1.0/Distribution-Package-VRDevice/layers/meta-st/meta-st-openstlinux/

View File

@@ -13,7 +13,9 @@ BBFILE_PRIORITY_vrpmdv = "6"
LAYERDEPENDS_vrpmdv = "core"
LAYERSERIES_COMPAT_vrpmdv = "mickledore"
IMAGE_INSTALL += "nginx"
IMAGE_INSTALL += "python3-gunicorn"
IMAGE_INSTALL += "python3-flask"
IMAGE_INSTALL += "vrpmdv-setup-page"
#IMAGE_INSTALL += "nginx"
#IMAGE_INSTALL += "python3-gunicorn"
#IMAGE_INSTALL += "python3-flask"
#IMAGE_INSTALL += "python3-flask-cors"
#IMAGE_INSTALL += "python3-cors"
IMAGE_INSTALL += "vrpmdv-web"

View File

@@ -0,0 +1,11 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name vrpmdv-web.local;
location / {
proxy_pass http://unix:/run/vrpmdv_web.sock;
}
}

View File

@@ -0,0 +1,11 @@
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name vrpmdv-web.local;
location / {
proxy_pass http://unix:/run/vrpmdv_web.sock;
}
}

View File

@@ -4,8 +4,7 @@ FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:"
DEPENDS = "systemd"
SRC_URI += " \
file://vrpmdv.local \
file://vrpmdv-setup.local \
file://vrpmdv-web.local \
"
SYSTEMD_AUTO_ENABLE = "enable"
@@ -19,10 +18,9 @@ EXTRA_OECONF = "\
do_install:append () {
install -d ${D}${sysconfdir}/nginx/sites-available
install -D -m 644 ${WORKDIR}/vrpmdv.local ${D}${sysconfdir}/nginx/sites-available/
install -D -m 644 ${WORKDIR}/vrpmdv-setup.local ${D}${sysconfdir}/nginx/sites-available/
install -D -m 644 ${WORKDIR}/vrpmdv-web.local ${D}${sysconfdir}/nginx/sites-available/
rm -rf ${D}${systemd_unitdir}/system/nginx/sites-enabled/default_server
# rm -rf ${D}${systemd_unitdir}/system/nginx/sites-enabled/default_server
rm -rf ${D}${sysconfdir}/nginx/sites-enabled/default_server
ln -s ${sysconfdir}/nginx/sites-available/vrpmdv-setup.local ${D}${sysconfdir}/nginx/sites-enabled/
ln -s ${sysconfdir}/nginx/sites-available/vrpmdv-web.local ${D}${sysconfdir}/nginx/sites-enabled/
}

View File

@@ -0,0 +1,20 @@
[Unit]
Description=gunicorn daemon for vrpmdv_web
Requires=vrpmdv_web.socket
After=network.target
[Service]
User=root
Group=www-data
Type=notify
RuntimeDirectory=gunicorn
WorkingDirectory=/var/www/vrpmdv-web.local/
ExecStart=/usr/bin/gunicorn vrpmdvserver:app
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
TimeoutStopSec=5
PrivateTmp=true
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,9 @@
[Unit]
Description=gunicorn socket for vrpmdv_web
[Socket]
ListenStream=/run/vrpmdv_web.sock
SocketUser=www
[Install]
WantedBy=sockets.target

View File

@@ -0,0 +1,35 @@
SUMMARY = "Install and start a systemd services"
SECTION = "mlgunicorn"
LICENSE = "CLOSED"
inherit systemd
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://vrpmdv_setup_page.service"
SRC_URI += "file://vrpmdv_setup_page.socket"
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE:${PN} = "vrpmdv_setup_page.service vrpmdv_setup_page.socket "
FILES:${PN} += "${systemd_system_unitdir}"
FILES:${PN} += "${systemd_system_unitdir}/vrpmdv_setup_page.service"
FILES:${PN} += "${systemd_system_unitdir}/vrpmdv_setup_page.socket"
do_install:append () {
install -d ${D}/${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/vrpmdv_setup_page.service ${D}/${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/vrpmdv_setup_page.socket ${D}/${systemd_system_unitdir}
install -d ${D}${sysconfdir}/systemd/system/multi-user.target.wants/
install -d ${D}${sysconfdir}/systemd/system/sockets.target.wants/
ln -s ${systemd_system_unitdir}/datalogger_setup_page.socket ${D}${sysconfdir}/systemd/system/sockets.target.wants/vrpmdv_setup_page.socket
ln -s ${systemd_system_unitdir}/datalogger_setup_page.service ${D}${sysconfdir}/systemd/system/multi-user.target.wants/vrpmdv_setup_page.service
}
REQUIRED_DISTRO_FEATURES= "systemd"

View File

@@ -7,29 +7,29 @@ inherit systemd
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += "file://vrpmdv_setup_page.service"
SRC_URI += "file://vrpmdv_setup_page.socket"
SRC_URI += "file://vrpmdv_web.service"
SRC_URI += "file://vrpmdv_web.socket"
SYSTEMD_AUTO_ENABLE = "enable"
SYSTEMD_SERVICE:${PN} = "vrpmdv_setup_page.service vrpmdv_setup_page.socket "
SYSTEMD_SERVICE:${PN} = "vrpmdv_web.service vrpmdv_web.socket "
FILES:${PN} += "${systemd_system_unitdir}"
FILES:${PN} += "${systemd_system_unitdir}/vrpmdv_setup_page.service"
FILES:${PN} += "${systemd_system_unitdir}/vrpmdv_setup_page.socket"
FILES:${PN} += "${systemd_system_unitdir}/vrpmdv_web.service"
FILES:${PN} += "${systemd_system_unitdir}/vrpmdv_web.socket"
do_install:append () {
install -d ${D}/${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/vrpmdv_setup_page.service ${D}/${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/vrpmdv_setup_page.socket ${D}/${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/vrpmdv_web.service ${D}/${systemd_system_unitdir}
install -m 0644 ${WORKDIR}/vrpmdv_web.socket ${D}/${systemd_system_unitdir}
install -d ${D}${sysconfdir}/systemd/system/multi-user.target.wants/
install -d ${D}${sysconfdir}/systemd/system/sockets.target.wants/
ln -s ${systemd_system_unitdir}/datalogger_setup_page.socket ${D}${sysconfdir}/systemd/system/sockets.target.wants/vrpmdv_setup_page.socket
ln -s ${systemd_system_unitdir}/datalogger_setup_page.service ${D}${sysconfdir}/systemd/system/multi-user.target.wants/vrpmdv_setup_page.service
ln -s ${systemd_system_unitdir}/vrpmdv_web.socket ${D}${sysconfdir}/systemd/system/sockets.target.wants/vrpmdv_web.socket
ln -s ${systemd_system_unitdir}/vrpmdv_web.service ${D}${sysconfdir}/systemd/system/multi-user.target.wants/vrpmdv_web.service
}
REQUIRED_DISTRO_FEATURES= "systemd"

View File

@@ -36,8 +36,7 @@ FILES:${PN} += "${DESTINATION}"
do_install () {
install -d ${D}${DESTINATION}
install -m 0644 ${WORKDIR}/vrmpdvsetupapp.py ${D}/${DESTINATION}
install -m 0644 ${WORKDIR}/vrmpdvsetuppage.py ${D}/${DESTINATION}
install -m 0644 ${WORKDIR}/vrmpdv*.py ${D}/${DESTINATION}
}

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Markus Lehr | VR Predictive Maintenance Device."
/>
<meta
data-rh="true"
property="og:image"
content="https://refine.dev/img/refine_social.png"
/>
<meta
data-rh="true"
name="twitter:image"
content="https://refine.dev/img/refine_social.png"
/>
<title>
Markus Lehr | VR Predictive Maintenance Device.
</title>
<script type="module" crossorigin src="/assets/index-952960a4.js"></script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm dev` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

View File

@@ -0,0 +1,139 @@
from uuid import uuid4
import uuid
from flask import jsonify
import json
# from vrpmdvmonitoringschema import VRPMDV_MonitoringSchema
# from vrpmdvmonitoring import VRPMDV_Monitoring
from vrpmdvmonitoringschema import VRPMDV_MonitoringSchema
from vrpmdvmonitoring import VRPMDV_Monitoring
class VRPMDV_Data:
def __init__(self):
#self.loaded = False
self.mons = []
self.loaded = self.loadFile()
def loadFile(self):
try:
with open('./mons.json', 'r') as f:
fmons = f.read()
if not fmons:
# return no Item
return True
else:
# data = json.loads(fmons)
schema = VRPMDV_MonitoringSchema(many=True)
res = schema.loads(fmons) # data
self.mons = schema.loads(fmons) # .append(res)
return True
except:
#nothing todo
print("file not found")
def saveFile(self):
try:
with open('./mons.json', 'w') as f:
schema = VRPMDV_MonitoringSchema()
result = schema.dumps(self.mons, many=True)
f.write(result)
return True
except:
#nothing todo
print("could not write file")
def findMon(mon):
return mon
def getMonitorings(self):
# 1st time read file
if not self.loaded :
self.loaded = self.loadFile()
schema = VRPMDV_MonitoringSchema()
result = schema.dumps(self.mons, many=True)
return result
def getMonitoring(self, vrpmid):
try:
matched_obj = next(x for x in self.mons if str(x.id) == vrpmid)
except:
return "no Item found"
# we find it and we return it
schema = VRPMDV_MonitoringSchema()
return schema.dumps(matched_obj)
def setMonitoring(self, vrpmid, request):
try:
matched_obj = next(x for x in self.mons if str(x.id) == vrpmid)
matched_obj.name = request.name
matched_obj.samplerate = request.samplerate
matched_obj.sampleperiod = request.sampleperiod
matched_obj.downtime = request.downtime
self.saveFile()
except:
return "no Item found"
# we find it and we return it
schema = VRPMDV_MonitoringSchema()
return schema.dumps(matched_obj)
def createMonitoring(self, request):
#mon = VRPMDV_Monitoring(request["name"], request["samplerate"], request["sampleperiod"], request["downtime"], request["owner"])
id = uuid.uuid4()
mon = VRPMDV_Monitoring(id, request.name, request.samplerate, request.sampleperiod, request.downtime, request.owner)
if not self.loaded :
self.loaded = self.loadFile()
# create monitoring
self.mons.append(mon)
#save to file
self.saveFile()
#create result Object in json
schema = VRPMDV_MonitoringSchema()
return schema.dumps(mon)
def deleteMonitoring(self, vrpmid):
if not self.loaded :
self.loaded = self.loadFile()
# find monitoring with uuid
#result = filter(lambda mon: str(mon.uuid) == vrpmid["uuid"], self.mons)
try:
matched_obj = next(x for x in self.mons if str(x.id) == vrpmid)
except:
return "no Item found"
# we find it and now remove from list
self.mons.remove(matched_obj)
#save the list
self.saveFile()
#make result
schema = VRPMDV_MonitoringSchema()
return schema.dump(matched_obj)
def startMonitoring(self, vrpmid):
#if not self.loaded :
# self.loaded = self.loadFile()
#call the start API of the kernel treiber
return "started"
def stopMonitoring(self, vrpmid):
#if not self.loaded :
# self.loaded = self.loadFile()
#call the start API of the kernel treiber
return "stopped"

View File

@@ -0,0 +1,20 @@
import uuid
import datetime as dt
from marshmallow import Schema, fields, post_load
from vrpmdvmonreq import VRPMDV_MonReq
# class VRPMDV_MonReq:
# def __init__(self, name , samplerate, sampleperiod, downtime, owner) :
# self.name = name
# self.samplerate = samplerate
# self.sampleperiod = sampleperiod
# self.downtime = downtime
# self.owner = owner
class VRPMDV_Monitoring(VRPMDV_MonReq):
def __init__(self, id, name , samplerate, sampleperiod, downtime, owner="None", created_at=dt.datetime.now()) :
self.id = id
self.created_at = created_at
super().__init__(name, samplerate, sampleperiod, downtime, owner)

View File

@@ -0,0 +1,34 @@
import uuid
import datetime as dt
from marshmallow import Schema, fields, post_load, post_dump
from vrpmdvmonitoring import VRPMDV_Monitoring
class VRPMDV_MonitoringSchema(Schema):
#__envelope__ = {"single": None, "many": "monitorings"}
id = fields.UUID()
created_at = fields.DateTime("%m/%d/%Y, %H:%M")
name = fields.String()
samplerate = fields.Integer()
sampleperiod = fields.Integer()
downtime = fields.Integer()
owner = fields.String()
# def get_envelope_key(self, many):
# """Helper to get the envelope key."""
# key = self.__envelope__["many"] if many else self.__envelope__["single"]
# assert key is not None, "Envelope key undefined"
# return key
# @post_dump(pass_many=True)
# def wrap_with_envelope(self, data, many, **kwargs):
# key = self.get_envelope_key(many)
# return {key: data}
@post_load
def make_vrpmdv_Monitoring(self, data, **kwargs):
return VRPMDV_Monitoring(**data)

View File

@@ -0,0 +1,13 @@
import datetime as dt
class VRPMDV_MonReq:
def __init__(self, name , samplerate, sampleperiod, downtime, owner) :
self.name = name
self.samplerate = samplerate
self.sampleperiod = sampleperiod
self.downtime = downtime
self.owner = owner

View File

@@ -0,0 +1,19 @@
import uuid
import datetime as dt
from marshmallow import Schema, fields, post_load
from vrpmdvmonreq import VRPMDV_MonReq
class VRPMDV_MonReqSchema(Schema):
name = fields.String()
samplerate = fields.Integer()
sampleperiod = fields.Integer()
downtime = fields.Integer()
owner = fields.String()
@post_load
def make_vrpmdv_MonitoringReq(self, data, **kwargs):
return VRPMDV_MonReq(**data)

View File

@@ -0,0 +1,74 @@
# from vrpmdv-server/vrpmdv-main import application
import sys
import json
from flask import Flask, request , send_from_directory , Response
from flask_cors import CORS
from vrpmdvdata import VRPMDV_Data
from vrpmdvmonreqschema import VRPMDV_MonReqSchema
app = Flask(__name__, static_url_path='', static_folder='./build')
CORS(app) #comment this on deployment
vrpmdvdata = VRPMDV_Data()
@app.route("/", defaults={'path':''})
def serve(path):
return send_from_directory(app.static_folder,'index.html')
@app.route('/vrpmdvapi/1_0/monitorings', methods=['GET'])
def get_monitorings():
data = vrpmdvdata.getMonitorings()
resp = Response(data, status=200, mimetype='application/json')
return resp
@app.route('/vrpmdvapi/1_0/monitorings/<id>', methods=['GET'])
def get_monitoring(id):
data = vrpmdvdata.getMonitoring(id)
resp = Response(data, status=200, mimetype='application/json')
return resp
@app.route('/vrpmdvapi/1_0/monitorings/<id>', methods=['PATCH'])
def set_monitoring(id):
vrpmreq = VRPMDV_MonReqSchema().load(request.get_json())
data = vrpmdvdata.setMonitoring(id, vrpmreq)
resp = Response(data, status=200, mimetype='application/json')
return resp
@app.route('/vrpmdvapi/1_0/monitorings', methods=['POST'])
def create_monitoring():
vrpmreq = VRPMDV_MonReqSchema().load(request.get_json())
data = vrpmdvdata.createMonitoring(vrpmreq)
resp = Response(data, status=200, mimetype='application/json')
return resp
@app.route('/vrpmdvapi/1_0/monitorings/<id>', methods=['DELETE'])
def delete_monitoring(id):
data = vrpmdvdata.deleteMonitoring(id)
resp = Response(data, status=200, mimetype='application/json')
return resp
@app.route('/vrpmdvapi/1_0/monitorings/start', methods=['PUT'])
def start_monitoring():
vrpmid = request.get_json()
data = vrpmdvdata.startMonitoring(vrpmid)
resp = Response(data, status=200, mimetype='application/json')
return resp
@app.route('/vrpmdvapi/1_0/monitorings/stop', methods=['PUT'])
def stop_monitoring():
vrpmid = request.get_json()
data = vrpmdvdata.stopMonitoring(vrpmid)
resp = Response(data, status=200, mimetype='application/json')
return resp
if __name__ == "__main__":
app.run()

View File

@@ -0,0 +1,64 @@
SUMMARY = "vrpmdv-web recipe"
DESCRIPTION = "Recipe to add vrpmdv-setup-page to it's location."
LICENSE = "CLOSED"
inherit allarch perlnative
DEPENDS += " perl"
FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
SRC_URI += " \
file://vrpmdv/vrpmdvserver.py \
file://vrpmdv/vrpmdvmonreqschema.py \
file://vrpmdv/vrpmdvmonreq.py \
file://vrpmdv/vrpmdvmonitoringschema.py \
file://vrpmdv/vrpmdvmonitoring.py \
file://vrpmdv/vrpmdvdata.py \
file://vrpmdv/build/index.html \
file://vrpmdv/build/favicon.ico \
file://vrpmdv/build/assets/index-1aa534b8.js \
"
# SRC_URI += " \
# git://gitea.malehr.de/markus.lehr/vrmpdv.git;protocol=https;branch=master; \
# "
# SRCREV = "${AUTOREV}"
#SRC_URI += " \
# git://git@gitlab.sclabs.io:10122/vrpmdv/setup-page.git;protocol=ssh; \
#"
#SRCREV = "${AUTOREV}"
# S = "${WORKDIR}/git"
# S = "${WORKDIR}"
DESTINATION = "/var/www/vrpmdv-web.local"
FILES:${PN} += "${DESTINATION}"
do_install () {
install -d ${D}${DESTINATION}
install -d ${D}${DESTINATION}/build
install -d ${D}${DESTINATION}/build/assets
install -m 0644 ${WORKDIR}/vrpmdv/*.py ${D}/${DESTINATION}
install -m 0644 ${WORKDIR}/vrpmdv/build/index.html ${D}/${DESTINATION}/build
install -m 0644 ${WORKDIR}/vrpmdv/build/favicon.ico ${D}/${DESTINATION}/build
install -m 0644 ${WORKDIR}/vrpmdv/build/assets/index-1aa534b8.js ${D}/${DESTINATION}/build/assets
# install -m 0644 ${WORKDIR}/vrpmdv*.py ${D}/${DESTINATION}
# install -m 0644 ${WORKDIR}/build/index.html ${D}/${DESTINATION}/build
# install -m 0644 ${WORKDIR}/favicon.ico ${D}/${DESTINATION}/build
# install -m 0644 ${WORKDIR}/index-1aa534b8.js ${D}/${DESTINATION}/build/assets
}
RDEPENDS:${PN} += " perl"

View File

@@ -7,6 +7,9 @@ inherit core-image
IMAGE_INSTALL += " packagegroup-core-boot"
IMAGE_INSTALL += " packagegroup-vrpmdv-core"
IMAGE_INSTALL += " packagegroup-vrpmdv-base"
IMAGE_FEATURES += " \
debug-tweaks \
package-management \

View File

@@ -7,47 +7,25 @@ inherit packagegroup
PACKAGES = " \
packagegroup-vrpmdv-base \
vrpmdv-base-buildtools \
vrpmdv-base-python \
vrpmdv-base-connectivity \
"
RDEPENDS_${PN} = " \
vrpmdv-base-buildtools \
RDEPENDS:${PN} = " \
vrpmdv-base-python \
vrpmdv-base-connectivity \
"
SUMMARY_vrpmdv-base-buildtools = "Build utilities"
RDEPENDS_vrpmdv-base-buildtools = " \
autoconf \
automake \
binutils \
binutils-symlinks \
cpp \
cpp-symlinks \
gcc \
gcc-symlinks \
g++ \
g++-symlinks \
gettext \
make \
libstdc++ \
libtool \
pkgconfig \
"
RDEPENDS_vrpmdv-base-buildtools-dev += " \
libstdc++-dev \
"
SUMMARY_vrpmdv-base-python = "Python packages"
RDEPENDS_vrpmdv-base-python = " \
RDEPENDS:vrpmdv-base-python = " \
python3 \
libpython3 \
python3-core \
python3-flask \
python3-flask-cors \
python3-gunicorn \
python3-marshmallow \
python3-pip \
python3-requests \
python3-spidev \
@@ -57,13 +35,13 @@ RDEPENDS_vrpmdv-base-python = " \
SUMMARY_vrpmdv-base-connectivity = "Connectivity utilities"
RDEPENDS_vrpmdv-base-connectivity = " \
RDEPENDS:vrpmdv-base-connectivity = " \
curl \
dropbear \
hostapd \
kea \
nginx \
rpi-gpio \
rpio \
wpa-supplicant \
"