How AtomCam Tools Saves 12-Second Alarm Clips to NAS Using strftime Path Formatting

When motion triggers an alarm, the camera writes a 12-second MP4 to local temporary storage, then a custom rm script moves it to a CIFS-mounted NAS using a user-defined strftime pattern for directory organization.

The mnakada/atomcam_tools project modifies Wyze and Atom cameras to support direct Network Attached Storage (NAS) archiving with flexible path formatting. This open-source firmware intercepts the native alarm recording pipeline to enable strftime-based directory structures on SMB shares. Understanding how alarm recording saves 12-second clips to NAS with strftime path formatting requires examining the chain of file interception, mount automation, and shell-based transfers.

Local Alarm File Generation and Interception

The alarm recording process begins in libcallback/mp4write.c, where the firmware intercepts the camera's native MP4 writing behavior. When the MP4Write command activates alarm mode by setting mp4write_AlarmSD = 1, the mp4write_start_handler() function monitors for specific temporary file patterns to redirect storage.

Redirecting Alarm Files to Local Storage

In Wyze-compatible mode (wyze = 1), the handler detects paths starting with /tmp/alarm_ and immediately rewrites them to the SD card's temporary directory. This ensures the 12-second clip persists locally before NAS transfer:

// libcallback/mp4write.c
if (wyze && mp4write_AlarmSD && (size == 0xd7) &&
    !strcmp(format, "/tmp/alarm_record_%d.mp4")) {
    fmt = "/media/mmc/tmp/alarm_record_%d.mp4";
}

Configuring NAS Storage and strftime Patterns

Before files reach the NAS, the system reads user configuration from /tmp/hack.ini, populated through the web interface defined in web/source/vue/Setting.vue.

UI Configuration Variables

The Settings panel exposes ALARMREC_CIFS to enable NAS recording and ALARMREC_CIFS_PATH to define the strftime pattern. The default pattern %Y%m%d/%H%M%S creates date-based directories with timestamped filenames:

// web/source/vue/Setting.vue defaults
ALARMREC_CIFS: 'off',
ALARMREC_CIFS_PATH: '%Y%m%d/%H%M%S',
ALARMREC_CIFS_REMOVE: 'off',
ALARMREC_CIFS_REMOVE_DAYS: 30,

Mounting the CIFS Share

The mount_cifs.sh script checks these configuration flags and mounts the SMB share when alarm recording is enabled. It parses hack.ini for server credentials and mounts the remote storage under /atom/mnt:


# overlay_rootfs/atom_patch/system_bin/mount_cifs.sh

ALARMREC_CIFS=$(awk -F "=" '/^ALARMREC_CIFS *=/ { gsub(/^\/*/, "", $2);print $2}' $HACK_INI)

if [ "$ALARMREC_CIFS" = "on" -o "$PERIODICREC_CIFS" = "on" -o "$TIMELAPSE_CIFS" = "on" ] && [ "$STORAGE_CIFSSERVER" != "" ]; then
    mount -t cifs -ousername=$STORAGE_CIFSUSER,password=$STORAGE_CIFSPASSWD,vers=$VER,iocharset=utf8 $STORAGE_CIFSSERVER /atom/mnt
fi

Transferring Files to NAS with strftime Formatting

Once the 12-second recording completes, the system invokes a custom rm script located at overlay_rootfs/atom_patch/bin/rm. Despite its name, this script handles the critical NAS transfer logic using the ALARMREC_CIFS_PATH variable.

Dynamic Path Construction

The script captures the current timestamp in $NOW, then applies the user's strftime pattern via date -d to generate the final NAS path:


# overlay_rootfs/atom_patch/bin/rm (excerpt)

if [ "$ALARMREC_CIFS" = "on" ]; then
    CIFSFILE=`date -d $NOW +"alarm_record/$ALARMREC_CIFS_PATH.${FILE##*.}"`
    mv "$FILE" "/atom/mnt/$CIFSFILE"
fi

This command expands %Y%m%d/%H%M%S into something like alarm_record/20240307/154530.mp4, creating nested directories automatically when the file moves.

Automatic Cleanup and Retention Management

The system maintains storage hygiene through remove_old.sh, which purges expired alarm recordings based on the ALARMREC_CIFS_REMOVE_DAYS setting. It executes separate find commands for local SD card and NAS storage:


# overlay_rootfs/scripts/remove_old.sh

find /media/mmc/alarm_record -depth -type f -mtime +$ALARMREC_SDCARD_REMOVE_DAYS -delete
find /atom/mnt/$HOSTNAME/alarm_record -depth -type f -mtime +$ALARMREC_CIFS_REMOVE_DAYS -delete

Summary

  • Local Interception: The mp4write_start_handler() in libcallback/mp4write.c redirects alarm files from /tmp to /media/mmc/tmp/ to ensure temporary persistence.
  • Configuration Storage: User settings for NAS alarm recording and strftime patterns are stored in /tmp/hack.ini via overlay_rootfs/scripts/set_icamera_config.sh.
  • Mount Automation: mount_cifs.sh automatically mounts the SMB share under /atom/mnt when ALARMREC_CIFS is enabled.
  • strftime Transfer: The custom rm script uses date -d $NOW with the ALARMREC_CIFS_PATH variable to format destination paths dynamically.
  • Retention Control: remove_old.sh enforces deletion policies on both local and NAS storage using configurable day limits.

Frequently Asked Questions

What file format does the alarm recording use?

The alarm recording generates standard MP4 files. The system specifically looks for the pattern /tmp/alarm_record_%d.mp4 in the mp4write_start_handler() function, then moves these 12-second clips to the NAS while preserving the .mp4 extension through the ${FILE##*.} parameter expansion in the transfer script.

Can I customize the directory structure on the NAS?

Yes. The ALARMREC_CIFS_PATH setting in hack.ini accepts any valid strftime format string. For example, using %Y/%m/%d/%H%M%S creates a nested year/month/day hierarchy instead of the default flat %Y%m%d/%H%M%S structure. The date -d command in overlay_rootfs/atom_patch/bin/rm processes this pattern at transfer time.

How does the camera handle NAS connection failures?

If the CIFS share becomes unavailable, the mount_cifs.sh script will fail to mount or maintain the connection under /atom/mnt. However, the alarm file remains safely on the local SD card at /media/mmc/tmp/ until the transfer succeeds. The custom rm script only attempts the mv operation when ALARMREC_CIFS is explicitly set to "on" and the mount point is available.

Where is the strftime pattern stored between reboots?

The strftime pattern and all NAS settings persist in /tmp/hack.ini, written by overlay_rootfs/scripts/set_icamera_config.sh whenever you save changes through the web UI. The mount_cifs.sh and rm scripts read this file on every execution to determine current settings, ensuring the alarm recording behavior survives power cycles.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →