{"id":14977906,"url":"https://github.com/dunkelstern/planticam","last_synced_at":"2026-03-06T19:02:35.136Z","repository":{"id":142590526,"uuid":"320442007","full_name":"dunkelstern/planticam","owner":"dunkelstern","description":"Timelapse camera and video streaming firmware for Raspberry Pi zero W","archived":false,"fork":false,"pushed_at":"2020-12-14T18:32:31.000Z","size":2944,"stargazers_count":1,"open_issues_count":1,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-11-30T09:30:55.554Z","etag":null,"topics":["raspberry-pi-camera","raspberry-pi-zero-w","rtmp","timelapse"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dunkelstern.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-11T02:10:41.000Z","updated_at":"2024-03-02T11:56:37.000Z","dependencies_parsed_at":null,"dependency_job_id":"2e279ede-6db5-433f-a0e8-c29b4d9cc176","html_url":"https://github.com/dunkelstern/planticam","commit_stats":{"total_commits":50,"total_committers":1,"mean_commits":50.0,"dds":0.0,"last_synced_commit":"d6efd357ea6482cd86ab8b3280b18fe9ebefa308"},"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/dunkelstern/planticam","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fplanticam","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fplanticam/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fplanticam/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fplanticam/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dunkelstern","download_url":"https://codeload.github.com/dunkelstern/planticam/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dunkelstern%2Fplanticam/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30192369,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-06T18:54:55.862Z","status":"ssl_error","status_checked_at":"2026-03-06T18:53:04.013Z","response_time":250,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["raspberry-pi-camera","raspberry-pi-zero-w","rtmp","timelapse"],"created_at":"2024-09-24T13:56:31.316Z","updated_at":"2026-03-06T19:02:35.096Z","avatar_url":"https://github.com/dunkelstern.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Planticam, open source timelapse and streaming camera for Raspberry Pi Zero W\n\nThis firmware transforms your Raspberry Pi Zero W to a timelapse or RTMP streaming camera\nusing one of the many Raspberry Pi CSI compatible cameras.\n\nThe idea is to have a stable maintenance free appliance that will not crash and burn if\nit looses power (for example because it is turned on and off by a timer switch)\n\n\u003cimg src=\"docs/images/settings.png\" width=\"400\"\u003e \u003cimg src=\"docs/images/timelapse.png\" width=\"400\"\u003e\n\n\u003cimg src=\"case/front.jpg\" width=\"400\"\u003e \u003cimg src=\"case/with_gpio_back.jpg\" width=\"400\"\u003e\n\n## Features\n\n- Simple setup via config file on boot partition or web interface on USB Gadget Ethernet\n- Automatic image capture in timelapse mode\n- Image upload to storage server, no local storage\n- RTMP video streaming (WIP)\n- Audio recording (WIP, only if hardware is available)\n- 3D printed case AMF and FreeCAD files\n- Web interface for configuration (reachable via Wifi of USB Ethernet)\n\n## Todo\n\n- RTMP video streaming\n- Make video and timelapse modes cooperate\n- Audio recording\n- Add sensor readouts on GPIO header to be added as overlay onto the image or stored in exif metadata\n- Add sensor plugin interface to allow the user to add sensor readout plugins to the boot partition\n\n## What you need\n\n- Raspberry Pi 0 W.\n- Pi 0 Camera Ribbon (for \"normal\" sized Raspberry Pi cameras like the HQ camera)\n- Raspberry Pi Camera or Raspberry Pi High-Quality Camera (or one on a flex cable directly meant for the Pi Zero)\n- A compatible lens if you use the HQ Camera sensor.\n- Micro SD card\n- Some sort of a case for the electronics (either a Raspi Zero case with camera hole or use the\n  3D printer ready AMF files in the `case` subdir)\n- The camera firmware image from the release page\n\n## How to use\n\n1. Connect the camera to the Pi Zero W\n2. Put the electronics into the case (store bought or 3D Printed)\n3. Flash the image from the release page onto the SD card (I recommend [Etcher](https://www.balena.io/etcher/) for this)\n4. Connect your Pi to a Computer using the `OTG` (middle) Port, not the power port\n5. Wait for it to boot, a new network connection will become available once it has booted\n6. Open a browser and navigate to http://10.0.77.1/\n7. Follow the setup instructions on the website\n\n## How it works\n\nWhen connected to power the Pi boots the image from the SD-Card, this image is special as it is not\nthe usual Raspberry Pi OS or even Ubuntu. This image has been build with [Buildroot](https://buildroot.org/) and\ncompressed into a read-only `squashfs` file system.\n\nOn boot the USB Ethernet Gadget mode is activated and an instance of `dnsmasq` is providing DHCP services\non that interface. When a computer connects to it, it sees a USB network card and usually runs a DHCP client\non that interface. It will get an IP address in the Range `10.0.77.50-150` while the Pi has `10.0.77.1`.\n\nOn the Pi we have the following running services:\n\n- Ethernet Gadget (which just sets some `configfs` settings to activate Ethernet mode)\n- `dnsmasq` to provide DHCP to the connected computer (if one is connected)\n- `ntpd` to synchronize the clock over the network as the Pi has no realtime clock\n- `sshd` to be able to connect, debug and monitor the device\n- `getty` on the Pi's UART on the GPIO header which provides a serial console at 115200 baud\n- `wpa_supplicant` to connect to Wifi (for more info read on)\n- `planticam_web` which is the `flask` based webinterface for setting up the device\n- `planticam_still` which is a relatively simple python script that captures still images for timelapses\n\n## How to configure (the UI way)\n\n1. Connect the Pi with the data port (not the power one) to a computer\n2. Wait a minute for it to boot\n3. Open a browser and navigate to http://10.0.77.1\n\nThe default username is `admin` and the password is `en3Eyied0mae`\n\n## How to configure (the manual way)\n\n1. Insert the flashed SD-card into a card reader/your computer\n2. Open the SD-card (on Windows it will show up as a drive, on OSX it should show\n  up in finder and on Linux it depends on your environment, if it does not show up\n  automatically, mount the first partition, the `vfat` one)\n3. Open `wpa_supplicant.conf` and enter your WiFi name and password instead of `default` and `password`.\n  Make sure to save with linux/unix line endings (LF only, nor CR LF which is default on Windows)\n4. Open `planticam.conf` in your editor and see below for a description of the options (if the names are not\n  enough)\n\n## How to configure (the cryptographically secure way)\n\nSee \"The manual way\" above first.\n\n### SSH Keys\n\nThe ssh host keys of this image are embedded and will not be re-generated as the filesystem is strictly\nread-only, however you can replace them as they are stored on the `vfat` partition of the SD-card in\nthe folder `ssh-keys`. It is strongly recommended to either build the complete image with `buildroot` yourself\nor at least change the keys if it is remotely possible the device will be accessed over the internet.\n\nTo re-generate the keys run the following commands and replace the files on the SD-card with the newly generated\nones:\n\n```bash\nssh-keygen -t rsa -f ssh_host_rsa_key -C '' -N ''\nssh-keygen -t dsa -f ssh_host_dsa_key -C '' -N ''\nssh-keygen -t ecdsa -f ssh_host_ecdsa_key -C '' -N ''\nssh-keygen -t ed25519 -f ssh_host_ed25519_key -C '' -N ''\n```\n\nOn the boot partition you will find another SSH key, the client key, directly in the root folder.\nTo re-generate this one run the following command and replace the files on the card (`id_ed25519` and `id_ed25519.pub`):\n\n```bash\nssh-keygen -t ed25519 -f id_ed25519 -C 'planticam' -N ''\n```\n\n### Random seed\n\nAs this is an embedded system with absolutely no external hardware attached to gather entropy from, we have\nto help the Pi (else every cryptographic algorithm that uses random numbers will hang on boot until enough\nentropy has been gathered.)\n\nAt build time the scripts generate a random seed. It is not strictly necessary to exchange that seed but if\nyou want to be sure nobody can guess the internal state of your device you may exchange the seed if you want.\n\nThe seed is stored as a kernel-boot-parameter in `cmdline.txt` in the parameter `systemd.random_seed`.\nTo generate a `base64` string to use as a seed run the following:\n\n```bash\nhead -c 250 /dev/urandom |base64 -w0 -\n```\n\nThis takes 250 bytes of random data from `/dev/urandom`, `base64` encodes it and prints it to the terminal.\n\n## Debugging\n\nalso known as: \"It does not work, what's wrong!\"\n\nThere are 3 methods of accessing the device, ordered from \"it mostly works\" to \"wtf is wrong\":\n\n1. If it seems to connect to Wifi, try SSH as root to `planticam.local` if you have zeroconf\n  (also known as bonjour) running.\n2. If you get something like `ssh: Could not resolve hostname planticam.local: Name or service not known`\n  either zeroconf is not working correctly or the device did not connect to Wifi, consult your router to\n  find the appropriate IP address to use with SSH.\n3. If Wifi absolutely won't connect, see if your router advertises its SSID on a channel that is probably not\n  supported by the firmware (for example: You can use 2.4GHz channel 13 in Germany, but the firmware has no\n  region set so it will not scan on that channel as it is forbidden to use in other parts of the world)\n4. If your router is fine, but it will not connect, try connecting the Pi to a computer via the USB data port and try\n  SSH to `10.0.77.1` as root user.\n5. If even the internal USB gadget ethernet won't work try using a serial console on the GPIO header. You will need\n  a USB to serial converter (or something similar) that can be used on 3.3V. **Warning:** The Pi UART is not 5V\n  compliant, you will destroy the PI if you're using a 5V device here! The Baud-rate is 115200,\n  8 bits, no parity, 1 stop bit (also known as 115200 8N1)\n\nFor console login use the `root` user and the password `Tu1boo4bee5i`\n\nYou will not have any writable filesystem by default. You can re-mount the `vfat` partition that is mounted as `/boot`\nif you just want to correct a setting though (only `vi` available on the Pi though, `i` to switch to edit mode,\nESC `:wq` to exit ;) ):\n\n```bash\nmount -o remount,rw /boot\n```\n\nBe sure to re-mount read only before disconnecting power to avoid crashed SD-cards.\n\nTo debug what went wrong, usually you can look at the following commands:\n\n- Kernel log: `dmesg`, shows any hardware failures\n- Journal: `journalctl -xe`, shows any output `systemd` or any of the running services generate, including\n  python stacktraces of any service\n\n## Building\n\n1. Create a working directory: `mkdir planticam`\n2. Checkout this repository: `git clone https://github.com/dunkelstern/planticam.git`\n3. Download a copy of buildroot: `wget https://buildroot.org/downloads/buildroot-2020.11.tar.gz`\n4. Unpack buildroot: `tar xvzf buildroot-2020.11.tar.gz`\n5. Link the buildroot directory to `buildroot` (without version number): `ln -sf buildroot-2020.11 buildroot`\n6. Switch to the build directory: `cd planticam`\n7. Run the build script: `./build-planticam.sh`\n8. Go grab a coffee, this takes some time as the complete crosscompiling toolchain is downloaded and\n  build before re-building the complete system in the image from source. (Takes about an hour on my Lenovo Yoga Slim)\n9. Go grab the image from `output/planticam/images/sdcard.img`\n\nIf you want to make changes to the planticam sources you can re-run the build process with the `clean` parameter\nto clean out the build packages before re-building: `./build-planticam.sh clean`, this will only clean out neccessary\nfiles, a rebuild should be done in about a minute usually.\n\nWhile building, the scripts generate SSH keys for the ssh daemon as well as a client ssh key, those will only be rebuilt\nif you remove the `output/planticam/images` folder, so you may experiment with new images without constantly removing\nthe keys from your `known_hosts` or replacing the public key on your image destination server.\n\nTo put the image on an SD-card you can either use etcher or any other image writer. I prefer to do it with `dd`:\n\n```bash\ndd if=output/planticam/images/sdcard.img of=/dev/sdX bs=1M oflag=sync status=progress\n```\n\nReplace `/dev/sdX` with the appropriate device name of your SD-card, make sure you may access the device file (either\nput yourself in the appropriate group for your Linux Distro or run the command as root). The `oflag=sync` skips the\nwrite cache of the SD-card so you can remove it immediately after the command finishes, the `status=progress` displays\nwrite progress, which is good as the `dd` command may appear to hang while the system is copying data.\n\n## planticam.conf\n\nExample:\n\n```ini\n[web]\nsecret_key = apAkGhEL6bve1NwB/RzQSuIEafI=\nusername = admin\npassword = sha256:50000:y1c7SCo95G8FTkY8gXsmwQ==:XrTm1s1P6qDabh1pCNAVUL84eVvvLjW-OwwbnN_yJgs=\n\n[image_settings]\nresolution_x = 2592\nresolution_y = 1944\nrotation = 0\niso = auto\nexposure_mode = auto\nexposure_compensation = 0\nmetering_mode = average\ndrc = off\nawb_mode = auto\nawb_gain_red = 0.9\nawb_gain_blue = 0.9\nbrightness = 50\ncontrast = 0\nsaturation = 0\nsharpness = 0\ndenoise = 0\n\n[timelapse]\nenable = on\ndelay = 120\nupload_mode = none\nupload_server = localhost\nupload_path = /data\nupload_auth_user = planticam\nupload_auth_password =\nupload_form_field =\nupload_cmd = SSHPASS= sftp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -q -i /boot/id_ed25519 {input_file} planticam@localhost:/data/{output_file}\nweekday_enable = off,off,off,off,off,off,off\nweekday_from = 00:00,00:00,00:00,00:00,00:00,00:00,00:00\nweekday_to = 23:59,23:59,23:59,23:59,23:59,23:59,23:59\n\n\n```\n\n### \\[timelapse\\]\n\n- `enable`: boolean value, enable the timelapse mode\n- `delay`: delay in seconds between photos\n- `upload_cmd`: (optional) command to run to upload the image somewhere, the example command uploads to a SSH server\n  which has the `id_ed25519.pub` key in their `authorized_keys`-file. Has 2 placeholders: `{input_file}` the source\n  file and `{output_file}` the output filename (usually `planticam-YYYY-MM-DD_HH-MM-SS.jpg`)\n- `post_url`: (optional) URL to upload the image to, it will send a `HTTP POST`-request with `Content-Type: image/jpeg`\n  and the JPEG binary as is in the body\n\n### \\[image_settings\\]\n\n- `resolution_x` and `resolution_y`: Image resolution, see\n  [picamera documentation](https://picamera.readthedocs.io/en/release-1.12/fov.html) for explanation what the cameras\n  can do\n- `rotation`: (optional) Rotates the image in 90 degree increments\n- `iso`: (optional) ISO to use, defaults to `auto` (one of `auto`, 100, 200, 320, 400, 500, 640, 800)\n- `exposure_mode`: (optional) Exposure mode to use (one of `off`, `auto`, `night`, `nightpreview`, `backlight`,\n  `spotlight`, `sports`, `snow`, `beach`, `verylong`, `fixedfps`, `antishake` or `fireworks`)\n- `exposure_compensation`: (optional) Adjusts the camera’s exposure compensation level. Each increment represents\n  1/6th of a stop. Range is -25 to 25, defaults to 0\n- `meter_mode`: (optional) Exposure metering mode, defaults to `average` (one of `average`, `spot`, `backlit` or\n  `matrix`)\n- `awb_mode`: (optional) White-balance mode to use (one of `off`, `auto`, `sunlight`, `cloudy`, `shade`, `tungsten`,\n  `fluorescent`, `incandescent`, `flash` or `horizon`)\n- `brightness`: (optional) Brightness from 0-100, defaults to 50\n- `contrast`: (optional) Contrast from -100-100, defaults to 0\n- `saturation`: (optional) Saturation from -100-100, defaults to 0\n- `sharpness`: (optional) Sharpness from -100-100, defaults to 0\n- `denoise`: (optional) Denoise ration from -100-100, defaults to 0\n\n\n## Credits\n\n- [Buildroot](https://buildroot.org/) the build system\n- [ShowMeWebcam](https://github.com/showmewebcam/showmewebcam), converts the Raspi Zero into a USB webcam,\n  they gave me the idea\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunkelstern%2Fplanticam","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdunkelstern%2Fplanticam","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdunkelstern%2Fplanticam/lists"}