Skip to content

Instantly share code, notes, and snippets.

@DonaldKellett
Last active February 16, 2023 02:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DonaldKellett/93d5fa1323e2e5f950a61f72c8d6ba82 to your computer and use it in GitHub Desktop.
Save DonaldKellett/93d5fa1323e2e5f950a61f72c8d6ba82 to your computer and use it in GitHub Desktop.
Disable autofocus and specify absolute focus for Logitech c930e with udev and systemd (Fedora 35 Workstation)
KERNEL=="video[0-9]*", SUBSYSTEM=="video4linux", ATTRS{idVendor}=="046d", ATTRS{idProduct}=="0843", TAG+="systemd", ENV{SYSTEMD_WANTS}="logitech-c930e@$env{MINOR}.service"

Logitech c930e initialization rule

The Logitech c930e has autofocus enabled by default, which fails to focus on objects close to the camera after relaxing the focus to distant objects. This is usually not much of a problem in video meetings, but for use cases such as online proctored exams where the invigilator requests an identity document to be presented close to the camera, this lack of focus can render the text on the identity document unreadable, making the camera useless for such exams.

This gist corrects the issue by disabling autofocus and manually setting the focus so that close-up text can be seen clearly, yet distant objects do not appear too blurry.

This solution has been tested on Fedora 35 Workstation, though it can probably be used on many other Linux distributions as well with minimal modification. In particular, for Ubuntu 20.04, replace focus_automatic_continuous with focus_auto.

Prerequisites

Ensure the v4l-utils package is installed.

Usage

  1. Place the file 90-logitech-c930e.rules under /etc/udev/rules.d

  2. Place the file logitech-c930e@.service under /etc/systemd/system

  3. Place the file logitech-c930e.sh under /root and mark it executable

  4. Restart systemd-udevd.service and reload systemd:

    $ sudo systemctl restart systemd-udevd.service
    $ sudo systemctl daemon-reload
  5. Unplug and re-plug your Logitech c930e webcam. The rules should now be effective. Enjoy ;-)

References

Related questions

License

CC0 (public domain)

#!/bin/bash
if [[ $# -ne 1 ]]; then
echo "Expected minor device number as sole argument" 1>&2
exit 1
fi
while true; do
v4l2-ctl -d $1 --set-ctrl focus_automatic_continuous=0
v4l2-ctl -d $1 --set-ctrl focus_absolute=75
sleep 5
done
[Unit]
Description=Disable autofocus and set absolute focus for Logitech c930e
[Service]
ExecStart=/bin/bash -c "/root/logitech-c930e.sh %I"
[Install]
WantedBy=multi-user.target
@markstos
Copy link

Thanks for this. I've taken the idea and packaged it as an Ansible role: https://gitlab.com/markstos/ansible-video4linux-webcam-config-role

The role takes care of installing v4l-utils and all the files mentioned above, and also turns the web make model and exact configs set into settable variables.

@DonaldKellett
Copy link
Author

Thanks for this. I've taken the idea and packaged it as an Ansible role: https://gitlab.com/markstos/ansible-video4linux-webcam-config-role

The role takes care of installing v4l-utils and all the files mentioned above, and also turns the web make model and exact configs set into settable variables.

You're welcome, and glad to hear you've organized it in a format that's more readily usable and customizable 👍

It's also a pleasant coincidence that I've been looking into leveraging Ansible for automating the user-facing IT infrastructure at my workplace recently. Great minds think alike 😄

@markstos
Copy link

I pushed some updates to the role this morning:

  • The above approach requires a permanent bash process that mostly sleeping-- actually two because the camera is detected as two different video devices and udev launches the systemd service for both, even if the second device doesn't understand the configs. Also, the approach wakes up the the CPU every 5 seconds, which is bad for battery life if you don't need the webcam focus fixed so rapidly. I addressed both by using a systemd timer to do the restart and not having the service be persistent. This consumes negligible persistent memory. Also, I changed the restart time to 30 seconds and made it configurable. (Although, may my approach is worse for resources due to the cost of launching bash every 30 seconds... I could probably drop the need for bash at all and just have systemd make the v4l-ctl calls directly each time.

@markstos
Copy link

I've been slowing rolling out Ansible at work and it's been a great experience. My team likes the tool and it can be introduced organically without an all at once push. We are getting closer to completely defining servers with Ansible. Ansible has also been useful to help junior developers make proposed DevOps changes as Ansible playbooks, with a senior developer reviewing them because our server definitions get updated.

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