diff --git a/images/no-camera.png b/images/no-camera.png new file mode 100644 index 0000000..b2eb15d Binary files /dev/null and b/images/no-camera.png differ diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..2c228c3 --- /dev/null +++ b/install.sh @@ -0,0 +1,71 @@ +echo "Updating indexes" +apt update + +echo "Installing xserver xinit openbox ufw xserver-xorg x11 unclutter make crontab cmake g++ gcc and git..." +apt install --no-install-recommends ufw xserver-xorg x11-xserver-utils xinit openbox -y || exit +apt install git gcc g++ make cmake unclutter iptables cron pigpio -y || exit +echo "Try to uninstall node and npm... (Can fail)" +apt purge node -y || true +apt purge npm -y || true + +echo "Setup xserver..." +# XServer +echo "allowed_users=anybody" >/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) });