From b8fffdb52db5ffc0a100667c1b0dff4f8e0108c3 Mon Sep 17 00:00:00 2001 From: Tobias Hopp Date: Sun, 28 May 2023 15:09:38 +0200 Subject: [PATCH] update --- images/no-camera.png | Bin 0 -> 13132 bytes install.sh | 71 +++++++++++++++++++++++++++++++++++++++++++ src/main.ts | 44 ++++----------------------- src/python_webcam.ts | 11 ++++--- src/server.ts | 28 +++++++++-------- src/utils.ts | 51 +++++++++++++++++++++++++++++++ src/web/main.ts | 11 ++++--- 7 files changed, 156 insertions(+), 60 deletions(-) create mode 100644 images/no-camera.png create mode 100644 install.sh create mode 100644 src/utils.ts diff --git a/images/no-camera.png b/images/no-camera.png new file mode 100644 index 0000000000000000000000000000000000000000..b2eb15da07158be5a95c0ecd1550163b71a4ffb0 GIT binary patch literal 13132 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/etc/X11/Xwrapper.config +#no-uncomment cp autostart.config /etc/xdg/openbox/autostart + +echo "Adding apt keys..." +# Keys and stuff --- +# Nodejs +curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash + +# Yarn +curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | gpg --dearmor | sudo tee /usr/share/keyrings/yarnkey.gpg >/dev/null +echo "deb [signed-by=/usr/share/keyrings/yarnkey.gpg] https://dl.yarnpkg.com/debian stable main" | sudo tee /etc/apt/sources.list.d/yarn.list + +echo "Updating indexes..." +# Final update +apt update +echo "Installing mongodb and yarn..." +apt install nodejs yarn mongodb-org -y +apt upgrade -y + + + +echo "Installing autostart..." +# Autostart +cat </etc/xdg/openbox/autostart + xset s off + xset s noblank + xset -dpms + setxkbmap -option terminate:ctrl_alt_bksp + + cd /home/photobox/photobox/ + ./mount.sh + yarn run start +EOT + +echo "Setting to console autologin..." +raspi-config nonint do_boot_behaviour B2 + + + echo "Installing bashrc" +echo "clear" >>/home/photobox/.bashrc +echo "[[ -z \$DISPLAY && \$XDG_VTNR -eq 1 ]] && startx -- -nocursor >/dev/null 2>&1" >>/home/photobox/.bashrc + + + echo "Setting no-logo..." +systemctl disable getty@tty1.service + + +if ! grep -w "logo.nologo" /boot/cmdline.txt; then + echo "Backing up /boot/cmdline.txt to /root/cmdline.txt.bak" + cp /boot/cmdline.txt /root/cmdline.txt.bak + sed -i '1 s_$_ loglevel=3 logo.nologo disable\_splash=1 splash quiet plymouth.ignore-serial-consoles logo.nologo vt.global\_cursor_default=0_' /boot/cmdline.txt + #cp /tmp/cmdline.txt /boot/cmdline.txt + sed -i "1 s|$| vt.global_cursor_default=0|" /boot/cmdline.txt + + sed -i 's/console=tty0/console=tty3/' /boot/cmdline.txt +fi + + +chown photobox:photobox -R /home/photobox/ \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index b032dd6..e7d7e4c 100644 --- a/src/main.ts +++ b/src/main.ts @@ -5,6 +5,7 @@ import * as process from "process"; import {GPIO} from "./gpio"; import {PythonWebcam} from "./python_webcam"; import {FileHandler} from "./file_handler"; +import {Utils} from "./utils"; function createWindow() { // Create the browser window. @@ -45,6 +46,7 @@ app.on("window-all-closed", () => { // code. You can also put them in separate files and require them here. Server.initServer().then(); + PythonWebcam.startPythonService(); /*setInterval(() => { @@ -52,16 +54,18 @@ PythonWebcam.startPythonService(); }, 1000*10);*/ - try { + Utils.load(); + // Capture button GPIO.watchForButton(10, (pin) => { - Main.capture() + Utils.capture() }); // Delete button GPIO.watchForButton(11, (pin) => { console.log("Delete fired!"); + Utils.delete_last(); }); } catch (e) { @@ -72,39 +76,3 @@ process.on("SIGINT", _ => { GPIO.unexportAll(); }); - -export class Main { - - private static port = GPIO.getPin(20, 'out') - static async delete_last() { - console.log("Delete fired!"); - - let last_shots = await FileHandler.getLastImages(); - let last = last_shots[0]; - - if(last.locked) { - Server.io.emit("deleting", false); - } - else - { - Server.io.emit("deleting", true); - await FileHandler.deleteLastImage(); - await Server.sendRecentPhotos(); - } - } - - static capture() { - console.log("Capture fired!"); - Server.io.emit("capturing", 3); - - setTimeout( async () => { - this.port.setHigh(); - }, 2300 ); - setTimeout(async () => { - let base64_string = await PythonWebcam.captureImage(); - Server.io.emit("captured", base64_string); - this.port.setLow(); - }, 3000); - } - -} \ No newline at end of file diff --git a/src/python_webcam.ts b/src/python_webcam.ts index e463dba..9fa181b 100644 --- a/src/python_webcam.ts +++ b/src/python_webcam.ts @@ -9,14 +9,13 @@ export class PythonWebcam { private static filename = __dirname + "/../capture.py"; private static waitFor = "wrote_frame"; private static calls: Function[] = []; - private static noCamera = true; + public static noCamera = true; private static process: child_process.ChildProcess; public static startPythonService() { this.process = spawn("python", [this.filename], {stdio: 'pipe'}); this.process.stdout.setEncoding('utf-8'); - console.log("spawned") this.process.stdout.on('data', (data) => { this.noCamera = false; @@ -32,10 +31,10 @@ export class PythonWebcam { this.process.on("exit", (code) => { console.log("Subprocess exited! " + code) + this.noCamera = true; if (code != 0) { - this.noCamera = true; - throw new Error("Could not open camera device/script - Code: " + code.toString()); + //throw new Error("Could not open camera device/script - Code: " + code.toString()); } }); @@ -50,13 +49,15 @@ export class PythonWebcam { this.waitForScriptFrame(() => { resolve(FileHandler.getTempPicture()); }); + setTimeout(() => resolve(""), 1000 ); }); } public static captureImage(): Promise { return new Promise(async (resolve, reject) => { let img = (await this.getImage()).toString(); - await FileHandler.saveBase64Photo(img); + if(img.length != 0 ) + await FileHandler.saveBase64Photo(img); resolve(img); await Server.sendRecentPhotos(); }); diff --git a/src/server.ts b/src/server.ts index a3f0afb..026114c 100644 --- a/src/server.ts +++ b/src/server.ts @@ -1,13 +1,13 @@ import {Socket} from "socket.io"; import {FileHandler} from "./file_handler"; import {PythonWebcam} from "./python_webcam"; -import {Main} from "./main"; + +import {Utils} from "./utils"; export class Server { private static app = require("express")(); private static server = require('http').createServer(this.app); public static io = require('socket.io')(this.server); - private static interval : NodeJS.Timer; public static initServer(): Promise { return new Promise((resolve, reject) => { @@ -18,15 +18,10 @@ export class Server { socket.on("do_shot", () => { console.log("Capture fired!"); - Server.io.emit("capturing", ""); - - setTimeout(async () => { - let base64_string = await PythonWebcam.captureImage(); - Server.io.emit("captured", base64_string); - }, 3000); + Utils.capture(); }); socket.on("do_delete", () => { - Main.delete_last(); + Utils.delete_last(); }) }); @@ -36,7 +31,7 @@ export class Server { //Webcam.startCameraStream(); this.server.listen(3000); - this.startInterval(); + this.nextInterval(); }); } @@ -49,14 +44,21 @@ export class Server { } - public static startInterval(){ + public static nextInterval(){ setTimeout(async () => { try { - this.io.emit("stream", (await PythonWebcam.getImage())); + if( PythonWebcam.noCamera ) + { + this.io.emit("no_camera"); + } else + { + this.io.emit("stream", (await PythonWebcam.getImage())); + } + } catch( e ) { } - this.startInterval(); + this.nextInterval(); }, 1000/30); } diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..9250056 --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,51 @@ +import {GPIO} from "./gpio"; +import {FileHandler} from "./file_handler"; +import {Server} from "./server"; +import {PythonWebcam} from "./python_webcam"; + +export class Utils { + private static flashlight: GPIO; + + static load() { + this.flashlight = GPIO.getPin(20, 'out'); + } + + static async delete_last() { + console.log("Delete fired!"); + + let last_shots = await FileHandler.getLastImages(); + let last = last_shots[0]; + + if (last.locked) { + Server.io.emit("deleting", false); + } else { + Server.io.emit("deleting", true); + await FileHandler.deleteLastImage(); + await Server.sendRecentPhotos(); + } + } + + public static capture() { + console.log("Capture fired!"); + Server.io.emit("capturing", 3); + + setTimeout(async () => { + try { + this.flashlight.setHigh(); + } catch (e) { + + } + }, 2500); + setTimeout(async () => { + let base64_string = await PythonWebcam.captureImage(); + Server.io.emit("captured", base64_string); + + + try { + this.flashlight.setLow(); + } catch (e) { + + } + }, 3000); + } +} \ No newline at end of file diff --git a/src/web/main.ts b/src/web/main.ts index 92635dd..4ec5861 100644 --- a/src/web/main.ts +++ b/src/web/main.ts @@ -36,11 +36,14 @@ document.addEventListener("DOMContentLoaded", () => { let socket = io("http://localhost:3000"); socket.on("stream", (data) => { - //console.log(data); if (isShowingCaptured) return; imageElement.src = data; }); + socket.on("no_camera", (data) => { + if (isShowingCaptured) return; + imageElement.src = "../images/no-camera.png"; + }); socket.on("last_shots", (data: { image: string, locked: boolean }[]) => { lastImages.innerHTML = ""; @@ -84,9 +87,9 @@ document.addEventListener("DOMContentLoaded", () => { countdown.innerText = "CHEESE!"; setTimeout(() => { flash.style.display = "block"; - }, 150); - }, 800); - }, 950); + }, 90); + }, 900); + }, 1000); }, 1000) });