Skip to content

Instantly share code, notes, and snippets.

@enegaard
Last active July 24, 2024 16:58
Show Gist options
  • Save enegaard/a57af286205914bd912270c89650fb1b to your computer and use it in GitHub Desktop.
Save enegaard/a57af286205914bd912270c89650fb1b to your computer and use it in GitHub Desktop.
Getting the Raspberry Pi Camera to Work on HASSOS

Getting the Raspberry Pi Camera to Work on HASSOS

Enabling the Raspberry Pi camera on HASSOS installations is unfortunately not as simple as connecting the camera and configuring Home Assistant as described at https://www.home-assistant.io/integrations/rpi_camera.

For the camera to work at all, an alternate firmware needs to be loaded when the Raspberry Pi boots. On Raspberry Pi OS (and many others), the alternate firmware is included with the OS installation image, and switching to the alternate firmware is accomplished by running raspi-config and selecting "Enable Camera" from the menu. HASSOS does not include either the alternate firmware or the raspi-config program, so all of the steps need to be done manually.

The steps below attempt to describe the steps that need to be performed. They have worked for me on a Raspberry Pi 3B+ running HASSOS 4.11 through 4.15. If you have a different setup your mileage may vary (but hopefully you'll get enough hints from the below to get it working).

As of HASSOS 6.0, as mentioned in the closing notes of home-assistant/operating-system#947 on June 17th 2021, the alternate firmware files are automatically included in the builds. Therefore much of this guide is obsolete - only the last two sections need to be followed (enable the camera in config.txt and reboot).

Shortly after HASSOS 6.0 was released, some code change between Home Assistant Core 2021.7.4 and Home Assistant Core 2021.8.1 broke the camera support on HASSOS platforms. A fix was applied and core versions 2021.11.3 and later work once again, so avoid core versions 2021.8.0 through 2021.11.2 to retain a working rpi_camera.

The high-level overview of what needs to be done is:

  • Find the alternate firmware files compatible with the version of HASSOS that you are running or are going to be running after the next reboot.
  • Place the firmware files on a machine that your HASSOS box has scp/sftp access to.
  • Copy the firmware files to the HASSOS addon_core_ssh container.
  • Copy the firmware files to the HASSOS /mnt/boot partition.
  • Edit the HASSOS /mnt/boot/config.txt file to enable the alternate firmware and make other camera related changes.
  • Reboot HASSOS, then configure the camera as documented elsewhere.

Find the correct start_x.elf and fixup_x.dat firmware files

(skip this step on HASSOS 6.0 and later)

Find your HASSOS version if you don't already know it. There are many ways to do this, like looking at the host system information information in the Home Assistant client you use. Another way is to run the following from an SSH connection to Home Assistant:

ha info | grep hassos:

E.g. 4.13

Go to https://github.com/home-assistant/operating-system/blob/HASSOS-VERSION/buildroot/package/rpi-firmware/rpi-firmware.mk

(NOTE: replace HASSOS-VERSION with your version of HASSOS, e.g. https://github.com/home-assistant/operating-system/blob/4.13/buildroot/package/rpi-firmware/rpi-firmware.mk)

The firmware hash is the value of the make variable RPI_FIRMWARE_VERSION

In this example, the firmware hash is: 7caead9416f64b2d33361c703fb243b8e157eba4

Go to https://github.com/raspberrypi/firmware/commit/FIRMWARE-HASH

E.g. https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4

And download the start_x.elf and fixup_x.dat files from there. If start_x.elf and fixup_x.dat are NOT in that commit, click on "Browse Files (at this point in history)", navigate to boot/, and download the firmware files from there.

Save both firmware files on a system that your HASSOS box will be able to access with scp or sftp.

Operating System Firmware Hash Firmware Link
4.13 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.14 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.15 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.16 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.17 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.18 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.19 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
4.20 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
5.0 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
5.1 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
5.2 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
5.3 7caead9416f64b2d33361c703fb243b8e157eba4 https://github.com/raspberrypi/firmware/commit/7caead9416f64b2d33361c703fb243b8e157eba4
5.4 2b41f509710d99758a5b8efa88d95dd0e9169c0a https://github.com/raspberrypi/firmware/commit/2b41f509710d99758a5b8efa88d95dd0e9169c0a
5.5 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.6 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.7 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.8 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.9 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.10 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.11 2ba11f2a07760588546821aed578010252c9ecb3 https://github.com/raspberrypi/firmware/commit/2ba11f2a07760588546821aed578010252c9ecb3
5.12 0d458874a89921fbe460e422b239695e1e101e2b https://github.com/raspberrypi/firmware/commit/0d458874a89921fbe460e422b239695e1e101e2b
5.13 0d458874a89921fbe460e422b239695e1e101e2b https://github.com/raspberrypi/firmware/commit/0d458874a89921fbe460e422b239695e1e101e2b

Copy the firmware files to the HASSOS host

(skip this step on HASSOS 6.0 and later)

This is a two-step process, since the HASSOS host does not have any support for copying remote files directly to the host. Therefore the concept is to copy the firmware files to a container that does have support for remote file transfer, then copy those files to the host using the docker cp command.

Enable camera in config.txt

Connect to the HASSOS host on port 22222, and edit (with "vi") the /mnt/boot/config.txt file as follows.

The camera needs more GPU memory than the default setting provides. Increase the GPU memory to 128 MB where possible by adding the following lines. See https://www.raspberrypi.org/documentation/raspbian/applications/camera.md and https://www.raspberrypi.org/documentation/configuration/config-txt/memory.md for reference.

gpu_mem=128
gpu_mem_256=64
gpu_mem_512=128
gpu_mem_1024=128

Enable the alternate firmware:

# Setting start_x to 1 does exactly the same
# thing as the following 2 lines that are commented
# out, but with reduced risk for errors due to typos
start_x=1
#start_file=start_x.elf
#fixup_file=fixup_x.dat
# The next line is optional, if you don't want the
# red LED on the camera to light while the camera
# is active
disable_camera_led=1

Reboot the HASSOS host and start using the camera

After all of the steps above have been completed, reboot the HASSOS host and continue configuring the camera as documented in https://www.home-assistant.io/integrations/rpi_camera.

@TheLazyHatGuy
Copy link

TheLazyHatGuy commented Jul 24, 2024

Some more logs

# docker exec -it addon_a0d7b954_motioneye bash
root@a0d7b954-motioneye:/$ apk add libcamera-tools
(1/7) Installing libcamera-ipa (0.1.0-r1)
(2/7) Installing libunwind (1.7.2-r1)
(3/7) Installing yaml (0.2.5-r2)
(4/7) Installing libcamera (0.1.0-r1)
(5/7) Installing libevent (2.1.12-r7)
(6/7) Installing gtest (1.14.0-r1)
(7/7) Installing libcamera-tools (0.1.0-r1)
Executing busybox-1.36.1-r15.trigger
OK: 207 MiB in 184 packages
root@a0d7b954-motioneye:/$ cam -l
[0:14:00.070772133] [478]  INFO Camera camera_manager.cpp:284 libcamera v0.1.0
Available cameras:
root@a0d7b954-motioneye:/$ exit
# docker exec -it addon_a0d7b954_motioneye bash
root@a0d7b954-motioneye:/$ v4l2-ctl  --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
	/dev/video10
	/dev/video11
	/dev/video12
	/dev/video18
	/dev/video31
	/dev/media1

bcm2835-isp (platform:bcm2835-isp):
	/dev/video13
	/dev/video14
	/dev/video15
	/dev/video16
	/dev/video20
	/dev/video21
	/dev/video22
	/dev/video23
	/dev/media2
	/dev/media3

mmal service 16.1 (platform:bcm2835_v4l2-0):
	/dev/video0

rpivid (platform:rpivid):
	/dev/video19
	/dev/media0

Using Raspbian

@raspberrypi:~ $ cam -l
[0:05:59.413619094] [2697]  INFO Camera camera_manager.cpp:313 libcamera v0.3.0+65-6ddd79b5
[0:05:59.539846389] [2702]  WARN RPiSdn sdn.cpp:40 Using legacy SDN tuning - please consider moving SDN inside rpi.denoise
[0:05:59.542320415] [2702]  INFO RPI vc4.cpp:446 Registered camera /base/soc/i2c0mux/i2c@1/imx708@1a to Unicam device /dev/media1 and ISP device /dev/media0
Available cameras:
1: 'imx708' (/base/soc/i2c0mux/i2c@1/imx708@1a)
@raspberrypi:~ $ v4l2-ctl  --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
	/dev/video10
	/dev/video11
	/dev/video12
	/dev/video18
	/dev/video31
	/dev/media4

bcm2835-isp (platform:bcm2835-isp):
	/dev/video13
	/dev/video14
	/dev/video15
	/dev/video16
	/dev/video20
	/dev/video21
	/dev/video22
	/dev/video23
	/dev/media0
	/dev/media2

unicam (platform:fe801000.csi):
	/dev/video0
	/dev/video1
	/dev/media1

rpivid (platform:rpivid):
	/dev/video19
	/dev/media3
@raspberrypi:~ $ for i in /dev/video* /dev/media*; do echo ====== $i ======; v4l2-ctl -ld $i; done
====== /dev/video0 ======
====== /dev/video1 ======
====== /dev/video10 ======

User Controls

  min_number_of_capture_buffers 0x00980927 (int)    : min=1 max=1 step=1 default=1 value=1 flags=read-only

Codec Controls

                     h264_level 0x00990a67 (menu)   : min=0 max=13 default=11 value=11 (4) flags=read-only
                   h264_profile 0x00990a6b (menu)   : min=0 max=4 default=4 value=4 (High) flags=read-only
====== /dev/video11 ======

Codec Controls

                 video_b_frames 0x009909ca (int)    : min=0 max=0 step=1 default=0 value=0 flags=update
                 video_gop_size 0x009909cb (int)    : min=0 max=2147483647 step=1 default=60 value=60
             video_bitrate_mode 0x009909ce (menu)   : min=0 max=1 default=0 value=0 (Variable Bitrate) flags=update
                  video_bitrate 0x009909cf (int)    : min=25000 max=25000000 step=25000 default=10000000 value=10000000
           sequence_header_mode 0x009909d8 (menu)   : min=0 max=1 default=1 value=1 (Joined With 1st Frame)
         repeat_sequence_header 0x009909e2 (bool)   : default=0 value=0
                force_key_frame 0x009909e5 (button) : value=0 flags=write-only, execute-on-write
          h264_minimum_qp_value 0x00990a61 (int)    : min=0 max=51 step=1 default=20 value=20
          h264_maximum_qp_value 0x00990a62 (int)    : min=0 max=51 step=1 default=51 value=51
            h264_i_frame_period 0x00990a66 (int)    : min=0 max=2147483647 step=1 default=60 value=60
                     h264_level 0x00990a67 (menu)   : min=0 max=15 default=11 value=11 (4)
                   h264_profile 0x00990a6b (menu)   : min=0 max=4 default=4 value=4 (High)
====== /dev/video12 ======

User Controls

                horizontal_flip 0x00980914 (bool)   : default=0 value=0
                  vertical_flip 0x00980915 (bool)   : default=0 value=0
====== /dev/video13 ======

User Controls

                    red_balance 0x0098090e (int)    : min=1 max=65535 step=1 default=1000 value=1000 flags=slider
                   blue_balance 0x0098090f (int)    : min=1 max=65535 step=1 default=1000 value=1000 flags=slider
       colour_correction_matrix 0x009819e1 (u8)     : min=0 max=255 step=1 default=0 dims=[88] flags=has-payload
                   lens_shading 0x009819e2 (u8)     : min=0 max=255 step=1 default=0 dims=[36] flags=has-payload, execute-on-write
                    black_level 0x009819e3 (u8)     : min=0 max=255 step=1 default=0 dims=[12] flags=has-payload
             green_equalisation 0x009819e4 (u8)     : min=0 max=255 step=1 default=0 dims=[16] flags=has-payload
                          gamma 0x009819e5 (u8)     : min=0 max=255 step=1 default=0 dims=[136] flags=has-payload
                        denoise 0x009819e6 (u8)     : min=0 max=255 step=1 default=0 dims=[24] flags=has-payload
                        sharpen 0x009819e7 (u8)     : min=0 max=255 step=1 default=0 dims=[28] flags=has-payload
     defective_pixel_correction 0x009819e8 (u8)     : min=0 max=255 step=1 default=0 dims=[8] flags=has-payload
                 colour_denoise 0x009819e9 (u8)     : min=0 max=255 step=1 default=0 dims=[8] flags=has-payload

Image Processing Controls

                   digital_gain 0x009f0905 (int)    : min=1 max=65535 step=1 default=1000 value=1000
====== /dev/video14 ======
====== /dev/video15 ======
====== /dev/video16 ======
====== /dev/video18 ======
====== /dev/video19 ======

Stateless Codec Controls

    hevc_sequence_parameter_set 0x00a40a90 (unknown): type=270 value=unsupported payload type flags=has-payload
     hevc_picture_parameter_set 0x00a40a91 (unknown): type=271 value=unsupported payload type flags=has-payload
              slice_param_array 0x00a40a92 (unknown): type=272 dims=[4096] flags=has-payload, 0x00000800
            hevc_scaling_matrix 0x00a40a93 (unknown): type=273 value=unsupported payload type flags=has-payload
         hevc_decode_parameters 0x00a40a94 (unknown): type=274 value=unsupported payload type flags=has-payload
               hevc_decode_mode 0x00a40a95 (menu)   : min=0 max=0 default=0 value=0 (Slice-Based)
                hevc_start_code 0x00a40a96 (menu)   : min=0 max=1 default=0 value=0 (No Start Code)
====== /dev/video20 ======

User Controls

                    red_balance 0x0098090e (int)    : min=1 max=65535 step=1 default=1000 value=1000 flags=slider
                   blue_balance 0x0098090f (int)    : min=1 max=65535 step=1 default=1000 value=1000 flags=slider
       colour_correction_matrix 0x009819e1 (u8)     : min=0 max=255 step=1 default=0 dims=[88] flags=has-payload
                   lens_shading 0x009819e2 (u8)     : min=0 max=255 step=1 default=0 dims=[36] flags=has-payload, execute-on-write
                    black_level 0x009819e3 (u8)     : min=0 max=255 step=1 default=0 dims=[12] flags=has-payload
             green_equalisation 0x009819e4 (u8)     : min=0 max=255 step=1 default=0 dims=[16] flags=has-payload
                          gamma 0x009819e5 (u8)     : min=0 max=255 step=1 default=0 dims=[136] flags=has-payload
                        denoise 0x009819e6 (u8)     : min=0 max=255 step=1 default=0 dims=[24] flags=has-payload
                        sharpen 0x009819e7 (u8)     : min=0 max=255 step=1 default=0 dims=[28] flags=has-payload
     defective_pixel_correction 0x009819e8 (u8)     : min=0 max=255 step=1 default=0 dims=[8] flags=has-payload
                 colour_denoise 0x009819e9 (u8)     : min=0 max=255 step=1 default=0 dims=[8] flags=has-payload

Image Processing Controls

                   digital_gain 0x009f0905 (int)    : min=1 max=65535 step=1 default=1000 value=1000
====== /dev/video21 ======
====== /dev/video22 ======
====== /dev/video23 ======
====== /dev/video31 ======

JPEG Compression Controls

            compression_quality 0x009d0903 (int)    : min=1 max=100 step=1 default=80 value=80
====== /dev/media0 ======
Unable to detect what device /dev/media0 is, exiting.
====== /dev/media1 ======
Unable to detect what device /dev/media1 is, exiting.
====== /dev/media2 ======
Unable to detect what device /dev/media2 is, exiting.
====== /dev/media3 ======
Unable to detect what device /dev/media3 is, exiting.
====== /dev/media4 ======
Unable to detect what device /dev/media4 is, exiting.

@TheLazyHatGuy
Copy link

TheLazyHatGuy commented Jul 24, 2024

Looks like the issues I am having is a known issue with motionEye motioneye-project/motioneye#2683

Solution for running locally: motioneye-project/motioneye#2812 (comment)

@denics
Copy link

denics commented Jul 24, 2024

Looks like the issues I am having is a known issue with motionEye motioneye-project/motioneye#2683

I confirm. This is why I am trying to install rasbianos buster to be able to use the legacy camera framework

@TheLazyHatGuy
Copy link

Not sure if it is possible to change the entrypoint of the motionEye addon without building a brand new image

@denics
Copy link

denics commented Jul 24, 2024

Not sure if it is possible to change the entrypoint of the motionEye addon without building a brand new image

you could build your own addon, or, as I am trying to do, I use the motionEye addon in HomeAssistant connected with rpi0w running motioneyeOS in mode Fast Network Camera

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