commit 44635adc2b79628b39dff9e4009ceefac6f97ada Author: william Date: Mon May 31 13:52:50 2021 +0200 Initial commit diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..381e74e --- /dev/null +++ b/readme.md @@ -0,0 +1,5 @@ +# Tidsforløp fotografering i [Termux](https://termux.com/) med [Termux-camera-photo](https://wiki.termux.com/wiki/Termux-camera-photo) + +NB! Du må installere [Termux:API](https://wiki.termux.com/wiki/Termux:API)-tilleget og gi den tilstrekkelige rettigheter for at [Termux-camera-photo](https://wiki.termux.com/wiki/Termux-camera-photo) skal fungere. + +For at Termux skal kunne ta bilder mens mobilen er i dvale må du trykke på 'aquire wakelock' i Termux-økt varsel menyen. \ No newline at end of file diff --git a/run.sh b/run.sh new file mode 100644 index 0000000..0dc30a3 --- /dev/null +++ b/run.sh @@ -0,0 +1,11 @@ +#!/bin/bash +project_root=$(dirname $(realpath $0)) + +( + cd $PREFIX/tmp/ && + mkdir -p termux-timelapse && + cd termux-timelapse && + mkfifo image_buffer_pipe + + python3 "$project_root/timelapse.py" +) \ No newline at end of file diff --git a/timelapse.py b/timelapse.py new file mode 100644 index 0000000..9882a69 --- /dev/null +++ b/timelapse.py @@ -0,0 +1,84 @@ +config = { + "ssh": { + "user": "timelapse", + "host": "10.0.0.69", + "path": "~/" + }, + # Interval in seconds at which images are taken + "interval": 5, + # Amount of images allowed in buffer. If the device were to lose connection they would be kept in buffer until connected again. Max size depends on ram available + "buffer_size": 200 +} + +import datetime +import logging +import subprocess +import threading +import time + +# Images are appended to this list before being uploaded, we store them in a variable to reduce disk writes +image_buffer = [] + + +def main(): + logging.basicConfig(level=logging.DEBUG, format='[%(asctime)s] %(levelname)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S') + logging.info("Started") + + t_image_handler = threading.Thread(target=image_handler) + t_image_handler.start() + t_image_uploader = threading.Thread(target=image_uploader) + t_image_uploader.start() + + while True: + logging.debug(f"[Buffer entries: {len(image_buffer)}] [Active threads: {threading.active_count()}]") + + if len(image_buffer) >= config["buffer_size"]: + logging.error("Image buffer limit exceeded!!! Connection lost?") + else: + subprocess.Popen("termux-camera-photo -c 0 image_buffer_pipe", shell=True) + + time.sleep(config["interval"]) + + +# Appends image recieved from fifo into image_buffer +def image_handler(): + while True: + # Wait for data to arrive + with open("image_buffer_pipe", "rb") as binary_file: + binary_file = binary_file.read() + + # For each file we recieve one that is empty, idk why but we skip it + if not binary_file: + continue + + image_buffer.append( + [ + datetime.datetime.now(), + binary_file + ] + ) + +# Uploads image to remote server then removes image from image_buffer +def image_uploader(): + while True: + time.sleep(config["interval"]) + + while image_buffer: + # WARNING: I HAVE NO IDEA WHAT I'M DOING + # Here we pipe the image binary data into ssh and run a remote command. In this case, the remote command is 'cat >filename' which will copy stdin into the 'filename' file + proc = subprocess.run( + f"ssh '{config['ssh']['user']}@{config['ssh']['host']}' 'cat >{config['ssh']['path']}{image_buffer[0][0].strftime('%Y%m%d_%H%M%S_%f')}.jpg'", + stdout=subprocess.PIPE, + input=image_buffer[0][1], + encoding=None, + shell=True + ) + if proc.returncode == 0: + image_buffer.pop(0) + else: + logging.error(f"Command 'SSH' returned non-zero exit status {proc.returncode}") + break + + +if __name__ == "__main__": + main()