Skip to content

Instantly share code, notes, and snippets.

@cannikin
Forked from p123ad/README.md
Last active May 10, 2024 22:17
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save cannikin/4954d050b72ff61ef0719c42922464e5 to your computer and use it in GitHub Desktop.
Save cannikin/4954d050b72ff61ef0719c42922464e5 to your computer and use it in GitHub Desktop.
Use Raspberry Pi Camera with Prusa Connect

Use Raspberry Pi and Pi Cam for Prusa Connect

I couldn't get the script from p123ad to work on my Pi Zero W 2 with Camera Module 3 (all kinds of ffmpeg errors). There are several built-in tools for working with the camera now, so I tried to figure out if I could use one of those instead.

Behold this version, which uses the built-in libcamera-still tool to actually interact with the camera and save a JPEG. That image is then uploaded to Prusa Connect, same as the original script.

Instructions

  1. Go to the Cameras section at https://connect.prusa3d.com
  2. Add a new camera "Add new other camera"
  3. Copy the generated Token
  4. Set up your Pi Zero W 2 with Raspian OS Lite (32-bit) (this may work with other combinations of Pi and OS but I haven't tested)
  5. Create a shell script /usr/local/bin/prusaconnect_upload_cam.sh swapping out connect-token-here with your actual token
  6. Change ownership of the script to the user you log into your pi with, for example if your user is pi then run: sudo chown pi:pi /usr/local/bin/prusaconnect_upload_cam.sh
  7. Make the script executable: chmod +x /usr/local/bin/prusaconnect_upload_cam.sh.
  8. Start the script with /usr/local/bin/prusaconnect_upload_cam.sh

If it works you should see no error messages, and a new image appearing in Prusa Connect every 10 seconds.

Create Autostart Service

To run the script in the background and start it automatically.

  1. Create /etc/systemd/system/prusaconnect_upload_cam.service and paste the content from below.
  2. Start the service: sudo systemctl start prusaconnect_upload_cam.service.
  3. Check if the service is running with sudo systemctl status prusaconnect_upload_cam.service.
  4. Enable the service: sudo systemctl enable prusaconnect_upload_cam.service.
[Unit]
Description=Raspi Cam to Prusa Connect
[Service]
ExecStart=/usr/local/bin/prusaconnect_upload_cam.sh
[Install]
WantedBy=multi-user.target
#!/bin/bash
# Set default values for environment variables
: "${HTTP_URL:=https://connect.prusa3d.com/c/snapshot}"
: "${DELAY_SECONDS:=10}"
: "${LONG_DELAY_SECONDS:=60}"
# FINGERPRINT can be a random string with at least 16 characters
: "${FINGERPRINT:=123456789012345678}"
# CAMERA_TOKEN generated by the Connect server
: "${CAMERA_TOKEN:=connect-token-here}"
while true; do
# Grab a frame from libcamera-still with the highest resolution
# that is displayed on Prusa Connect: 1704 x 1278 for a 4:3 image
# Setting the quality to 80 saves almost 50% in file size for
# very little decrease in quality. Set to taste!
# If you need to rotate the image 180° add --rotate 180
libcamera-still -v 0 --immediate --width 2274 --height 1280 -q 80 -o output.jpg
# If no error, upload it.
if [ $? -eq 0 ]; then
# POST the image to the HTTP URL using curl
curl -X PUT "$HTTP_URL" \
-H "accept: */*" \
-H "content-type: image/jpg" \
-H "fingerprint: $FINGERPRINT" \
-H "token: $CAMERA_TOKEN" \
--data-binary "@output.jpg" \
--no-progress-meter \
--compressed
# Reset delay to the normal value
DELAY=$DELAY_SECONDS
else
echo "libcamera-still returned an error, retrying after ${LONG_DELAY_SECONDS}s..."
# Set delay to the longer value
DELAY=$LONG_DELAY_SECONDS
fi
sleep "$DELAY"
done
@cannikin
Copy link
Author

@fergymcferguson You’re welcome!

@codemonkey2k5
Copy link

Will this interfere if picamera2 is also running a live stream?

@cannikin
Copy link
Author

@codemonkey2k5 I don't know how picamera2 works, sorry 😬 It might lock the stream from the camera and no one else can use it, but maybe not!

You could try running libcamera-still -v 0 --immediate -o output.jpg while picamera2 is running and see if you end up with an image (and if picamera2 gets interrupted in the process)...

@codemonkey2k5
Copy link

Thank you, I will give that a try.

@ydu57120
Copy link

Hi @ydu57120 You should have a utility named nano installed which is a text editor that works right in the terminal. As long as you're connected to the Pi you can create and edit the file at the same time with:

sudo nano /usr/local/bin/prusaconnect_upload_cam.sh

Now you can paste in the script from above. When you're done editing, press Ctrl-X and then press y to save your changes and exit nano.

Now the file exists, but it's owned by the root user. To make it owned by the same user you're logged in as (probably pi), that's what step 6 is for:

sudo chown pi:pi /usr/local/bin/prusaconnect_upload_cam.sh

See if that works!

Capture d'écran 2024-04-15 140801
I done the step 5 but when i try the step 6 i have this error message. Do you have a soluce to fix that ?

@cannikin
Copy link
Author

@ydu57120 It sounds like the file isn't being created/saved by nano...is there any message at the bottom of the screen after you press Ctrl-X and then y? Anything about not being able to save?

@ydu57120
Copy link

after doing ctrl + x they ask me if i want to save modified buffer, then I press Y and at the bottom of the screen it is written: File Name to write: /usr/local/bin/prusaconnect_upload_cam.sh

@cannikin
Copy link
Author

That sure makes it sounds like the file was created...if you list the files in that directory, do you see it listed in the output?

ls -la /usr/local/bin

When I run that, I see:

$ ls -la
total 12
drwxr-xr-x  2 root root 4096 Feb 27 18:33 .
drwxr-xr-x 10 root root 4096 Dec  4 18:36 ..
-rwxr-xr-x  1 pi   pi   1426 Feb 27 23:47 prusaconnect_upload_cam.sh

@barcik75
Copy link

Hi,
Thank you very much for the script. Works as it should. I took the liberty of making small corrections, because from what I read and checked, if the printer is turned off and marked as OFFLINE in PrusaConnect, you cannot send screenshots from the camera. Additionally, the image size is probably also checked.

Sorry, I'm not very active on github and I don't know how to format the text to make it visible as code :/

#!/bin/bash

Set default values for environment variables

: "${HTTP_URL:=https://connect.prusa3d.com/c/snapshot}"
: "${DELAY_SECONDS:=10}"
: "${LONG_DELAY_SECONDS:=60}"

FINGERPRINT can be a random string with at least 16 characters

: "${FINGERPRINT:=123456789012345678}"

CAMERA_TOKEN generated by the Connect server

: "${CAMERA_TOKEN:=connect-token-here}"

Device IP for ping check

DEVICE_IP="x.x.x.x" # Replace x.x.x.x with the actual IP address of the Prusa3D

while true; do

Check if the device is reachable

if ping -c 1 -W 1 "$DEVICE_IP" >/dev/null 2>&1; then
# Device is reachable, proceed with capturing image

   # Grab a frame from libcamera-still with the highest resolution
   # that is displayed on Prusa Connect: 1704 x 1278 for a 4:3 image
   # Setting the quality to 80 saves almost 50% in file size for
   # very little decrease in quality. Set to taste!
   # If you need to rotate the image 180° add --rotate 180
   libcamera-still -v 0 --immediate --width 2274 --height 1280 -q 80 -o /dev/shm/output.jpg

   IMAGE_SIZE=$(stat -c %s /dev/shm/output.jpg)

   # If no error, upload it.
   if [ $? -eq 0 ]; then
       # POST the image to the HTTP URL using curl
       curl -X PUT "$HTTP_URL" \
           -H "accept: */*" \
           -H "content-type: image/jpg" \
           -H "content-length: $IMAGE_SIZE" \
           -H "fingerprint: $FINGERPRINT" \
           -H "token: $CAMERA_TOKEN" \
           --data-binary "@/dev/shm/output.jpg" \
           --no-progress-meter \
           --compressed

       # Reset delay to the normal value
       DELAY=$DELAY_SECONDS
   else
       echo "libcamera-still returned an error, retrying after ${LONG_DELAY_SECONDS}s..."

       # Set delay to the longer value
       DELAY=$LONG_DELAY_SECONDS
   fi

else
echo "Device is not reachable. Retrying after $LONG_DELAY_SECONDS seconds..."
DELAY=$LONG_DELAY_SECONDS
fi

sleep "$DELAY"
done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment