termux-timelapse/timelapse.py

85 lines
2.8 KiB
Python

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()