update
This commit is contained in:
parent
7f52850b2e
commit
b8fffdb52d
BIN
images/no-camera.png
Normal file
BIN
images/no-camera.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
71
install.sh
Normal file
71
install.sh
Normal file
@ -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 <<EOT >/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/
|
44
src/main.ts
44
src/main.ts
@ -5,6 +5,7 @@ import * as process from "process";
|
|||||||
import {GPIO} from "./gpio";
|
import {GPIO} from "./gpio";
|
||||||
import {PythonWebcam} from "./python_webcam";
|
import {PythonWebcam} from "./python_webcam";
|
||||||
import {FileHandler} from "./file_handler";
|
import {FileHandler} from "./file_handler";
|
||||||
|
import {Utils} from "./utils";
|
||||||
|
|
||||||
function createWindow() {
|
function createWindow() {
|
||||||
// Create the browser window.
|
// 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.
|
// code. You can also put them in separate files and require them here.
|
||||||
|
|
||||||
Server.initServer().then();
|
Server.initServer().then();
|
||||||
|
|
||||||
PythonWebcam.startPythonService();
|
PythonWebcam.startPythonService();
|
||||||
|
|
||||||
/*setInterval(() => {
|
/*setInterval(() => {
|
||||||
@ -52,16 +54,18 @@ PythonWebcam.startPythonService();
|
|||||||
}, 1000*10);*/
|
}, 1000*10);*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
Utils.load();
|
||||||
|
|
||||||
// Capture button
|
// Capture button
|
||||||
GPIO.watchForButton(10, (pin) => {
|
GPIO.watchForButton(10, (pin) => {
|
||||||
Main.capture()
|
Utils.capture()
|
||||||
});
|
});
|
||||||
|
|
||||||
// Delete button
|
// Delete button
|
||||||
GPIO.watchForButton(11, (pin) => {
|
GPIO.watchForButton(11, (pin) => {
|
||||||
console.log("Delete fired!");
|
console.log("Delete fired!");
|
||||||
|
Utils.delete_last();
|
||||||
|
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -72,39 +76,3 @@ process.on("SIGINT", _ => {
|
|||||||
GPIO.unexportAll();
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -9,14 +9,13 @@ export class PythonWebcam {
|
|||||||
private static filename = __dirname + "/../capture.py";
|
private static filename = __dirname + "/../capture.py";
|
||||||
private static waitFor = "wrote_frame";
|
private static waitFor = "wrote_frame";
|
||||||
private static calls: Function[] = [];
|
private static calls: Function[] = [];
|
||||||
private static noCamera = true;
|
public static noCamera = true;
|
||||||
|
|
||||||
private static process: child_process.ChildProcess;
|
private static process: child_process.ChildProcess;
|
||||||
|
|
||||||
public static startPythonService() {
|
public static startPythonService() {
|
||||||
this.process = spawn("python", [this.filename], {stdio: 'pipe'});
|
this.process = spawn("python", [this.filename], {stdio: 'pipe'});
|
||||||
this.process.stdout.setEncoding('utf-8');
|
this.process.stdout.setEncoding('utf-8');
|
||||||
console.log("spawned")
|
|
||||||
|
|
||||||
this.process.stdout.on('data', (data) => {
|
this.process.stdout.on('data', (data) => {
|
||||||
this.noCamera = false;
|
this.noCamera = false;
|
||||||
@ -32,10 +31,10 @@ export class PythonWebcam {
|
|||||||
|
|
||||||
this.process.on("exit", (code) => {
|
this.process.on("exit", (code) => {
|
||||||
console.log("Subprocess exited! " + code)
|
console.log("Subprocess exited! " + code)
|
||||||
|
this.noCamera = true;
|
||||||
if (code != 0)
|
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(() => {
|
this.waitForScriptFrame(() => {
|
||||||
resolve(FileHandler.getTempPicture());
|
resolve(FileHandler.getTempPicture());
|
||||||
});
|
});
|
||||||
|
setTimeout(() => resolve(""), 1000 );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static captureImage(): Promise<string> {
|
public static captureImage(): Promise<string> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
let img = (await this.getImage()).toString();
|
let img = (await this.getImage()).toString();
|
||||||
await FileHandler.saveBase64Photo(img);
|
if(img.length != 0 )
|
||||||
|
await FileHandler.saveBase64Photo(img);
|
||||||
resolve(img);
|
resolve(img);
|
||||||
await Server.sendRecentPhotos();
|
await Server.sendRecentPhotos();
|
||||||
});
|
});
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
import {Socket} from "socket.io";
|
import {Socket} from "socket.io";
|
||||||
import {FileHandler} from "./file_handler";
|
import {FileHandler} from "./file_handler";
|
||||||
import {PythonWebcam} from "./python_webcam";
|
import {PythonWebcam} from "./python_webcam";
|
||||||
import {Main} from "./main";
|
|
||||||
|
import {Utils} from "./utils";
|
||||||
|
|
||||||
export class Server {
|
export class Server {
|
||||||
private static app = require("express")();
|
private static app = require("express")();
|
||||||
private static server = require('http').createServer(this.app);
|
private static server = require('http').createServer(this.app);
|
||||||
public static io = require('socket.io')(this.server);
|
public static io = require('socket.io')(this.server);
|
||||||
private static interval : NodeJS.Timer;
|
|
||||||
|
|
||||||
public static initServer(): Promise<void> {
|
public static initServer(): Promise<void> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@ -18,15 +18,10 @@ export class Server {
|
|||||||
|
|
||||||
socket.on("do_shot", () => {
|
socket.on("do_shot", () => {
|
||||||
console.log("Capture fired!");
|
console.log("Capture fired!");
|
||||||
Server.io.emit("capturing", "");
|
Utils.capture();
|
||||||
|
|
||||||
setTimeout(async () => {
|
|
||||||
let base64_string = await PythonWebcam.captureImage();
|
|
||||||
Server.io.emit("captured", base64_string);
|
|
||||||
}, 3000);
|
|
||||||
});
|
});
|
||||||
socket.on("do_delete", () => {
|
socket.on("do_delete", () => {
|
||||||
Main.delete_last();
|
Utils.delete_last();
|
||||||
})
|
})
|
||||||
|
|
||||||
});
|
});
|
||||||
@ -36,7 +31,7 @@ export class Server {
|
|||||||
//Webcam.startCameraStream();
|
//Webcam.startCameraStream();
|
||||||
this.server.listen(3000);
|
this.server.listen(3000);
|
||||||
|
|
||||||
this.startInterval();
|
this.nextInterval();
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -49,14 +44,21 @@ export class Server {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static startInterval(){
|
public static nextInterval(){
|
||||||
setTimeout(async () => {
|
setTimeout(async () => {
|
||||||
try {
|
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 )
|
} catch( e )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
this.startInterval();
|
this.nextInterval();
|
||||||
}, 1000/30);
|
}, 1000/30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
51
src/utils.ts
Normal file
51
src/utils.ts
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -36,11 +36,14 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
let socket = io("http://localhost:3000");
|
let socket = io("http://localhost:3000");
|
||||||
|
|
||||||
socket.on("stream", (data) => {
|
socket.on("stream", (data) => {
|
||||||
//console.log(data);
|
|
||||||
if (isShowingCaptured) return;
|
if (isShowingCaptured) return;
|
||||||
|
|
||||||
imageElement.src = data;
|
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 }[]) => {
|
socket.on("last_shots", (data: { image: string, locked: boolean }[]) => {
|
||||||
lastImages.innerHTML = "";
|
lastImages.innerHTML = "";
|
||||||
@ -84,9 +87,9 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||||||
countdown.innerText = "CHEESE!";
|
countdown.innerText = "CHEESE!";
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
flash.style.display = "block";
|
flash.style.display = "block";
|
||||||
}, 150);
|
}, 90);
|
||||||
}, 800);
|
}, 900);
|
||||||
}, 950);
|
}, 1000);
|
||||||
}, 1000)
|
}, 1000)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user