From 61e93883a5327901ebc807afeb0cc8517a62193a Mon Sep 17 00:00:00 2001 From: Tobias Hopp Date: Mon, 17 Apr 2023 10:40:10 +0200 Subject: [PATCH] fix updater Took 58 minutes --- getSerialList.js | 81 ------------------------ public/stylesheets/style.css | 13 ++-- src/AppMaintenance.ts | 89 +++++++++++++++++++++++++++ src/main.ts | 10 +++ src/maintenance/main.ts | 0 src/routes/indexRouter.ts | 4 +- src/routes/maintenance/indexRouter.ts | 11 ++++ src/web/main.ts | 4 ++ update.sh | 3 +- views/index.pug | 7 ++- webpack.config.js | 1 + 11 files changed, 130 insertions(+), 93 deletions(-) delete mode 100644 getSerialList.js create mode 100644 src/AppMaintenance.ts create mode 100644 src/maintenance/main.ts create mode 100644 src/routes/maintenance/indexRouter.ts diff --git a/getSerialList.js b/getSerialList.js deleted file mode 100644 index 447cf4d..0000000 --- a/getSerialList.js +++ /dev/null @@ -1,81 +0,0 @@ -const { SerialPort } = require('serialport'); -const { ReadlineParser } = require('@serialport/parser-readline'); - -( async( ) => { - console.log( await SerialPort.list() ); - - - let port = new SerialPort( { path: '/dev/ttyS11', baudRate: 9600 } ); - - /*port.on('data', function (data) { - console.log('Data:', data.toString()) - - })*/ - - port.close() - - let callbacks = {}; - - function request() - { - return new Promise((resolve, reject) => { - let id = makeid(8); - console.log(id); - - let req = { - id: id, - type: "REQUEST", - data: "1,2" - } - - callbacks[req.id] = resolve; - - let done = false; - - setTimeout( () => { - if( !done ) - reject("Request with id " + id + " timed out"); - }, 15000 ); - - port.write(JSON.stringify(req) + "\r", "utf-8"); - }); - - } - - const parser = port.pipe(new ReadlineParser({ delimiter: '\r' })) - - parser.on('data', (data) => { - /*let req = { - id: id, - type: "ACK", - data: "1,2" - }*/ - - data = data.toString().trim(); - let json = JSON.parse(data); - - console.log("GOT: " + data ); - callbacks[json.id](); - - }); - - try { - await request(); - console.log("FUNCTION RESOLVED YAY!"); - } catch( e ) - { - console.error(e); - } -} )(); - -function makeid(length) { - var result = ''; - var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - var charactersLength = characters.length; - for ( var i = 0; i < length; i++ ) { - result += characters.charAt(Math.floor(Math.random() * charactersLength)); - } - return result; -} - - diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css index 4186d86..e54d6e2 100644 --- a/public/stylesheets/style.css +++ b/public/stylesheets/style.css @@ -155,6 +155,7 @@ h2 { height: 9%; background-color: #167FCC; box-shadow: inset 11px -45px 50px 3px rgba(223, 12, 42, 0.66); + overflow: visible; } @@ -193,6 +194,7 @@ h2 { grid-template-rows: 100%; grid-column-gap: 1.5%; padding: 1% 2% 0.2%; + overflow: auto; } @@ -224,8 +226,7 @@ h2 { .pane { height: 100%; padding: 1% 2%; - overflow: auto; - ms-overflow-style: none; /* IE and Edge */ + overflow: visible; scrollbar-width: none; /* Firefox */ scroll-behavior: smooth; color: white; @@ -284,23 +285,25 @@ h2 { .tooltip { position: relative; display: inline-block; + overflow: visible; } .tooltip .tooltiptext { opacity: 0; - width: 110px; + background-color: #214B74; color: #FFFFFF; text-align: center; - border-radius: 8px; + border-radius: 9px; padding: 5px 0; /* Position the tooltip */ position: absolute; z-index: 1; - bottom: 40%; + bottom: -55%; left: 50%; margin-left: -80px; + } diff --git a/src/AppMaintenance.ts b/src/AppMaintenance.ts new file mode 100644 index 0000000..a9beee4 --- /dev/null +++ b/src/AppMaintenance.ts @@ -0,0 +1,89 @@ +import express from 'express'; +import path from "path"; +import morgan from "morgan"; +import cookieParser from "cookie-parser"; +import debug from "debug"; +import * as http from "http"; + +export class AppMaintenance { + get app(): express.Application { + return this._app; + } + + private readonly _app: express.Application; + private readonly _server; + + static port = 80; + + private log = debug("itender:maintenance"); + + constructor() { + this._app = express(); + this._server = http.createServer(this._app); + + this._app.set('views', path.join(__dirname, '../views/maintenance')); + this._app.set('view engine', 'pug'); + + this._app.use(morgan('dev')); + this._app.use(express.json()); + this._app.use(express.urlencoded({extended: false})); + this._app.use(cookieParser()); + this._app.use(express.static(path.join(__dirname, "../public"))); + this._app.use('/web.js', express.static(path.join(__dirname, "../dist/maintenance.bundle.js"))); + + + + this._app.use( (req, res, next) => { + next(); + } ) + this._app.use((err, req, res, next) => { + + res.locals.message = err.message; + res.locals.error = err; + + res.status(err.status || 500); + res.render('error'); + this.log("Error " + err); + }); + this.loadRoutes(); + } + + public loadRoutes( ) : void + { + this._app.use( "/", require("./routes/maintenance/indexRouter") ); + + } + + public listen(): Promise { + return new Promise((resolve, reject) => { + this._server.on('error', (error) => { + if (error.syscall != 'listen') { + reject(); + return; + } + + let bind = 'Port ' + AppMaintenance.port; + + // handle specific listen errors with friendly messages + switch (error.code) { + case 'EACCES': + reject(bind + ' requires elevated privileges'); + break; + case 'EADDRINUSE': + reject(bind + ' is already in use'); + break; + default: + reject(); + } + + }); + this._server.on('listening', () => { + let addr = this._server.address(); + this.log("Listening on " + addr.port); + resolve(); + }) + this._server.listen(AppMaintenance.port); + }); + } +} + diff --git a/src/main.ts b/src/main.ts index a7c7542..eefa3a7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -13,10 +13,12 @@ import {ArduinoProxy} from "./ArduinoProxy"; import path from "path"; import {ErrorHandler, InternalError} from "./ErrorHandler"; import {LEDHandler} from "./LEDHandler"; +import {AppMaintenance} from "./AppMaintenance"; const log = debug("itender:server"); +const maintenance = new AppMaintenance(); const app = new App(); const wsApp = new WebsocketApp(); @@ -51,6 +53,14 @@ process.on("unhandledRejection", (reason, promise) => { } } //await test(); + try { + await maintenance.listen(); + } catch( e ) + { + log("Could not start maintenance web app"); + console.error(e); + } + await app.listen(); await wsApp.listen(); diff --git a/src/maintenance/main.ts b/src/maintenance/main.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/routes/indexRouter.ts b/src/routes/indexRouter.ts index b0785de..d8885a2 100644 --- a/src/routes/indexRouter.ts +++ b/src/routes/indexRouter.ts @@ -4,11 +4,11 @@ const router = express.Router(); /* GET home page. */ router.get('/', function (req, res, next) { - res.render('index', {title: 'Express'}); + res.render('index'); }); router.get('/status', (req, res) => { - res.status(200).send("ok"); + res.status(200).json({status: "ok", code: 200}); }) module.exports = router; diff --git a/src/routes/maintenance/indexRouter.ts b/src/routes/maintenance/indexRouter.ts new file mode 100644 index 0000000..20ee146 --- /dev/null +++ b/src/routes/maintenance/indexRouter.ts @@ -0,0 +1,11 @@ +import express from "express"; + +const router = express.Router(); + +/* GET home page. */ +router.get('/', function (req, res, next) { + res.render('index'); +}); + + +module.exports = router; diff --git a/src/web/main.ts b/src/web/main.ts index be3a112..40df541 100644 --- a/src/web/main.ts +++ b/src/web/main.ts @@ -38,13 +38,17 @@ document.addEventListener("DOMContentLoaded", async () => { }, 1000); + let eins = false; WebWebSocketHandler.registerForEvent(WebSocketEvent.CONTAINERS, (payload) => { + if( eins) return; + eins = true; let container: IContainer; let bottomContainers = document.getElementById("menuContainers") as HTMLDivElement; bottomContainers.innerHTML = ""; let containers = payload.data as IContainer[]; containers = containers.reverse(); + for (container of containers) { let containerDiv = document.createElement("div") as HTMLDivElement; containerDiv.classList.add("container"); diff --git a/update.sh b/update.sh index 008ed9a..65a7104 100755 --- a/update.sh +++ b/update.sh @@ -9,10 +9,9 @@ else yarn run compile cd ./arduino/itender/ arduino-cli compile --fqbn arduino:avr:mega itender.ino || true - sudo systemctl stop itender sleep 1 timeout 30 arduino-cli upload --port /dev/ttyACM0 --fqbn arduino:avr:mega itender.ino sleep 1 - sudo systemctl start itender + sudo sh -c "systemctl restart itender &" fi exit 0 diff --git a/views/index.pug b/views/index.pug index 6079b9d..372b02f 100644 --- a/views/index.pug +++ b/views/index.pug @@ -18,9 +18,9 @@ block setup div.inputGroup label(onclick="document.getElementById('allowRemoteCheckbox').checked = !document.getElementById('allowRemoteCheckbox').checked;") Remote-Verbindungen erlauben input#allowRemoteCheckbox.input(type="checkbox") - div.inputGroup - label(onclick="document.getElementById('hotspotCheckbox').checked = !document.getElementById('hotspotCheckbox').checked;") Ohne WiFi Hotspot aktivieren - input#hotspotCheckbox.input(type="checkbox") + //div.inputGroup + // label(onclick="document.getElementById('hotspotCheckbox').checked = !document.getElementById('hotspotCheckbox').checked;") Ohne WiFi Hotspot aktivieren + // input#hotspotCheckbox.input(type="checkbox") div.inputGroup label() Arduino Mega als Proxy erlauben input#proxyCheckbox.input(type="checkbox") @@ -57,6 +57,7 @@ block settings button.btn.btn-primary#settings_refreshDrinks Datenbank aktualisieren button.btn.btn-primary#settings_deleteDrinks Datenbank leeren button.btn.btn-primary#settings_reload Oberfläche neu starten + button.btn.btn-primary#settings_hotspot Hotspot Einstellungen button.btn.btn-primary#settings_getInfo Systeminformationen button.btn.btn-primary#settings_update System aktualisieren button.btn.btn-primary#settings_restart(disabled="disabled") iTender neu starten diff --git a/webpack.config.js b/webpack.config.js index 99ac5ea..8e03e84 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -5,6 +5,7 @@ module.exports = { devtool: "inline-source-map", entry: { web: "./src/web/main.ts", + maintenance: "./src/maintenance/main.ts" }, module: { rules: [