I am trying to make PeopleTracker run as a service so each time the RPi is rebooting or the app crashes it will restart, the problem is that even tho the app seems like is running correctly without any error in the systemctl status, it will not count anybody that is passing by. Meanwhile if i start the app manually it works just fine, can anyone help me ?
I am using RPi Board 4b with the latest version of RasbianOS Bullseye
Here is the link to the github with the code SbSoftwareSrl/PeopleTrackerDepthAI

Hi @adrian-militaru
Could you add some logs to the code then set the log output to a file. This would show you where the pipeline halts (or whatever actually happens).

Thoughts?

    jakaskerl
    I did that after writing here and apparently the error is that the oak device is not found, but as I said it works just fine if I run it manually

    Hi @adrian-militaru
    Could you paste the log please?

    Have you tried setting the user to something other than root?
    Does this happen on reboot or also when running the service manually?

    Thanks,
    Jaka

      jakaskerl
      2024-05-31 16:39:20,835 - PeopleTrackerLogger - ERROR - An error occurred: Traceback (most recent call last):
      File "/home/PeopleCounter/PeopleTrackerDepthAI/track_script.py", line 85, in <module>
      main()
      File "/home/PeopleCounter/PeopleTrackerDepthAI/track_script.py", line 74, in main
      oak.start(blocking=True)
      File "/home/PeopleCounter/.local/lib/python3.11/site-packages/depthai_sdk/oak_camera.py", line 268, in start
      self.build() # Build the pipeline
      ^^^^^^^^^^^^
      File "/home/PeopleCounter/.local/lib/python3.11/site-packages/depthai_sdk/oak_camera.py", line 349, in build
      self._init_device()
      File "/home/PeopleCounter/.local/lib/python3.11/site-packages/depthai_sdk/oak_camera.py", line 211, in init_device
      self.
      oak.device = dai.Device(
      ^^^^^^^^^^^
      RuntimeError: Failed to find device after booting, error message: X_LINK_DEVICE_NOT_FOUND
      It literally looks like the device is not pluged.
      I did try setting the user other than root, and this happens each time I run the service it does not matter if it is turned on manually or automatically after reboot.

      Hi @adrian-militaru
      This log means the initial device is found. That is the USB2.0 device 03e7:2485. When the script starts it finds the device and boots it. What this does is it reconnects the device as USB3 (with 03e7:f63b). It is this second device that is not found.

      Could you run this command please:

      echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="03e7", MODE="0666"' | sudo tee /etc/udev/rules.d/80-movidius.rules
      sudo udevadm control --reload-rules && sudo udevadm trigger

      Thanks,
      Jaka

        jakaskerl
        Still not working, but now the error looks like this :
        File "/home/PeopleCounter/PeopleTrackerDepthAI/track_script.py", line 85, in <module>
        main()
        File "/home/PeopleCounter/PeopleTrackerDepthAI/track_script.py", line 74, in main
        oak.start(blocking=True)
        File "/home/PeopleCounter/.local/lib/python3.11/site-packages/depthai_sdk/oak_camera.py", line 268, in start
        self.build() # Build the pipeline
        ^^^^^^^^^^^^
        File "/home/PeopleCounter/.local/lib/python3.11/site-packages/depthai_sdk/oak_camera.py", line 349, in build
        self._init_device()
        File "/home/PeopleCounter/.local/lib/python3.11/site-packages/depthai_sdk/oak_camera.py", line 200, in _init_device
        raise Exception("No OAK device found to connect to!")
        Exception: No OAK device found to connect to!

        @jakaskerl
        [Unit]
        Description=People Counter
        After=network.target

        [Service]
        Environment="PYTHONPATH=/home/PeopleCounter/.local/lib/python3.11/site-packages"
        WorkingDirectory=/home/PeopleCounter/PeopleTrackerDepthAI
        User=root
        Group=root
        DeviceAllow=/dev/bus/usb/001/019 rwm
        ExecStart=/usr/bin/python3 track_script.py
        Restart=always

        [Install]
        WantedBy=multi-user.target

        this is the service file in case you think something might be wrong with it

        Hi @adrian-militaru
        The unit file looks perfectly fine. I tried locally (without te deviceAllow rule) and the script worked. One, point: You seem to be running inside an environment in base python. Could you create a custom envirnoment and install requirements there, then link it inside the unit file.
        Since you are running as root this could sometimes cause issues.

        Thanks,
        Jaka

          jakaskerl
          I did and is not working for my program, but on this one :

          import cv2
          import depthai as dai
          import logging
          from logging.handlers import TimedRotatingFileHandler
          import os
          from datetime import datetime
          import sys
          import traceback
          
          # Set up logging
          log_directory = "/home/PeopleCounter/PeopleCounterLogs"
          if not os.path.exists(log_directory):
              os.makedirs(log_directory)
          
          # Create a log file with the current date
          log_file = os.path.join(log_directory, f"people_tracker_{datetime.now().strftime('%Y-%m-%d')}.log")
          
          logger = logging.getLogger("PeopleTrackerLogger")
          logger.setLevel(logging.DEBUG)
          
          # Create a TimedRotatingFileHandler that creates a new log file at midnight
          handler = TimedRotatingFileHandler(log_file, when="midnight", interval=1, backupCount=30)
          handler.suffix = "%Y-%m-%d"
          formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
          handler.setFormatter(formatter)
          logger.addHandler(handler)
          
          # Function to log exceptions with detailed traceback
          def log_exception(exc_type, exc_value, exc_traceback):
              if issubclass(exc_type, KeyboardInterrupt):
                  sys.__excepthook__(exc_type, exc_value, exc_traceback)
                  return
              logger.error("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
              tb_lines = traceback.format_exception(exc_type, exc_value, exc_traceback)
              logger.error("".join(tb_lines))
          
          sys.excepthook = log_exception
          
          logger.info("Starting People Tracker Application")
          
          try:
              # Create pipeline
              logger.info("Creating pipeline")
              pipeline = dai.Pipeline()
          
              # Define sources and outputs
              logger.info("Defining sources and outputs")
              monoLeft = pipeline.create(dai.node.MonoCamera)
              monoRight = pipeline.create(dai.node.MonoCamera)
              xoutLeft = pipeline.create(dai.node.XLinkOut)
              xoutRight = pipeline.create(dai.node.XLinkOut)
          
              xoutLeft.setStreamName('left')
              xoutRight.setStreamName('right')
          
              # Set camera properties
              logger.info("Setting camera properties")
              monoLeft.setCamera("left")
              monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_720_P)
              monoRight.setCamera("right")
              monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_720_P)
          
              # Link nodes
              logger.info("Linking nodes")
              monoRight.out.link(xoutRight.input)
              monoLeft.out.link(xoutLeft.input)
          
              # Connect to device and start pipeline
              logger.info("Connecting to device and starting pipeline")
              with dai.Device(pipeline) as device:
                  logger.info("Pipeline started successfully")
          
                  # Output queues to get frames from the cameras
                  logger.info("Creating output queues")
                  qLeft = device.getOutputQueue(name="left", maxSize=4, blocking=False)
                  qRight = device.getOutputQueue(name="right", maxSize=4, blocking=False)
          
                  logger.info("Entering main loop")
                  while True:
                      # Get frames from the cameras
                      logger.debug("Attempting to get frames from the cameras")
                      inLeft = qLeft.tryGet()
                      inRight = qRight.tryGet()
          
                      if inLeft is not None:
                          logger.debug("Received left frame")
                          frame = inLeft.getCvFrame()
                          logger.debug("Left frame shape: %s", frame.shape)
                          cv2.imshow("left", frame)
                          logger.info("Displayed left frame")
          
                      if inRight is not None:
                          logger.debug("Received right frame")
                          frame = inRight.getCvFrame()
                          logger.debug("Right frame shape: %s", frame.shape)
                          cv2.imshow("right", frame)
                          logger.info("Displayed right frame")
          
                      # Check for exit signal
                      if cv2.waitKey(1) == ord('q'):
                          logger.info("Exit signal received, closing application")
                          break
          except Exception as e:
              logger.error("An error occurred: %s", traceback.format_exc())
          finally:
              logger.info("People Tracker Application finished")

          I don't get the "Exception("No OAK device found to connect to!")"

          Are you running the same app from the github or another app ?
          Thanks

          Hi @adrian-militaru
          Right, I ran the rgb_preview example without the image display.
          So you are saying the code you sent works, but the one in github repo doesn't? And nothing else has changed?
          I'll try to debug.

          Thanks,
          Jaka

            jakaskerl Thanks, no, nothing else has change. The only difference between those two is that the git one is using the oak_camera class, and the other one is using the pipeline directly.

            Hi @adrian-militaru
            Which SDK version are you using? with OakCamera(usbSpeed=dai.UsbSpeed.HIGH) as oak: why use USB2?

            Might be a problem as you are instantiating multiple threads (for django). Try removing django from main file. I tested with the github code (only the main file) and it worked as expected (sdk=1.12).

            Thanks,
            Jaka