Detect fall events from RTSP camera streams using the KamiClaw cloud API. No local GPU needed — all inference runs server-side.
In short: Only 8-second alarm clips are sent to the cloud for AI analysis. No continuous streaming, no audio, no full video.
WhatLocalCloudVideo stream / file✅ Processed locally❌ Never sent8-second alarm clips✅ Saved (optional)✅ Sent for AI analysisAudio❌ Not collected❌ Not collected
📄 Full details: Read our Privacy Policy for complete information on data handling, retention, and your rights.
save_alarm_clips: false to not save clips locallyfind logs/clips/ -type f -mtime +30 -deleteconfig.json to gitℹ️ AI analysis requires sending alarm clips to the cloud API. Processed clips are retained per the provider's data retention policy.
All settings are in config.json. The agent auto-fills this when you provide values in chat.
FieldDefaultDescriptionapi_key``""Required. KamiClaw API keycameras``[]Required. Array of {name, rtsp_url} entries. Single entry: name optional, defaults to "default". Two or more entries: every entry must have a unique non-empty name.save_alarm_clips``trueSave alarm video clips to logs/clips/``feishu_webhook_url``""Feishu webhook URL for alarm notificationstelegram_bot_token``""Telegram bot token for alarm notificationstelegram_chat_id``""Telegram chat ID (user or group)discord_webhook_url``""Discord webhook URL (push notifications)discord_bot_token``""Discord bot token (two-way capable)discord_channel_id``""Discord channel ID (for bot)
All cameras are declared in the cameras array. Each entry has just two fields: name and rtsp_url.
Single camera (one entry). name is optional — if omitted it defaults to "default":
json
{
"cameras": [
{ "rtsp_url": "rtsp://192.168.1.100/live/stream" }
]
}
Multiple cameras (two or more entries). Every entry must have a unique, non-empty name. Strongly recommended: pick a meaningful location label so the operator immediately knows which camera triggered.
json
{
"cameras": [
{ "name": "front_door", "rtsp_url": "rtsp://192.168.1.101/live/stream" },
{ "name": "backyard", "rtsp_url": "rtsp://192.168.1.102/live/stream" }
]
}
name is shown in every Feishu / Telegram / Discord push and tags every log line.cameras is empty, or if multiple entries are missing/sharing a name.MUST show this table to the user when configuring cameras, so they can pick a URL pattern based on their brand:
Brand keyBrandURL patternhikvisionHikvisionrtsp://{user}:{pwd}@{ip}:554/Streaming/Channels/101 ( 101 =ch1 main, 102 =ch1 sub)dahuaDahuartsp://{user}:{pwd}@{ip}:554/cam/realmonitor?channel=1&subtype=0 ( subtype=0 main, 1 sub)tplinkTP-Linkrtsp://{user}:{pwd}@{ip}:554/stream1 ( stream1 main, stream2 sub)ezvizEZVIZrtsp://admin:{verify_code}@{ip}:554/H264/ch1/main/av_stream``univiewUniviewrtsp://{user}:{pwd}@{ip}:554/media/video1``reolinkReolinkrtsp://{user}:{pwd}@{ip}:554/h264Preview_01_main
FieldDefaultDescriptionrun_time``0Max run time in seconds; 0 = unlimitedpre_seconds``3.0Seconds buffered before motion triggerpost_seconds``3.0Seconds collected after motion trigger
Tell the agent which channels you want. They'll guide you through setup.
ChannelPush OnlyTwo-Way CapableFeishuWebhook URLGroup Bot (same config)TelegramBot Token + Chat ID+ Gateway ServiceDiscordWebhook URLBot Token + Channel ID
💡 Discord: Bot token + channel ID gives you full two-way capability. Webhook is simpler for push-only.
💡 Need help? Ask OpenClaw for guidance.
bash
# With config.json (recommended)
.venv/bin/python fall_detect_cloud_skill.py
# Or override the API key on the CLI
.venv/bin/python fall_detect_cloud_skill.py \
--api_key sk_live_xxxxxxxx
Cameras are always declared in config.json under the cameras array — there is no CLI flag for the RTSP URL.
The skill runs continuously. It does NOT stop after an alarm — it resets and keeps monitoring.
Fall detected:
json
{
"alarm": true,
"type": "fall",
"camera_name": "front_door",
"fall_type": "active_falling",
"num_persons": 1,
"confidence": 0.92,
"reason": "Person collapsed from standing to floor near bed",
"frame": 87,
"source": "rtsp://192.168.1.101/live/stream",
"clip": "logs/clips/alarm_fall_20260429_143201.mp4"
}
Normal exit (run time reached):
json
{
"alarm": false,
"type": null,
"detail": "Run time limit reached, no fall detected",
"frames_processed": 3600,
"source": "rtsp://192.168.1.100/live/stream"
}
CodeMeaning0Normal exit (run time reached)1Error (invalid API key, missing config, etc.)
Click to expand technical details
detectType: FALL, detectSubType: SK_FALL_DETECTION)For agents configuring this skill:
Read config.json — check whether api_key is set and whether cameras is a non-empty array.
If api_key is empty, ask the user: "Please provide your KamiClaw API key. Register at https://kamiclaw-skill.kamihome.com".
If cameras is empty, ask: "How many RTSP cameras do you want to monitor?"
[ { "rtsp_url": "..." } ] — name will default to "default" automatically.front_door, backyard, living_room). Strongly recommend the user picks meaningful labels — they are shown in every alarm notification. Write [ { "name": "front_door", "rtsp_url": "..." }, { "name": "backyard", "rtsp_url": "..." } ].Ask: "Save alarm video clips? (yes/no, default: yes)" → set save_alarm_clips.
Ask about each notification channel (Feishu / Telegram / Discord) — guide setup if yes.
Write all values to config.json (read existing, merge, write back).
Optionally run python fall_detect_cloud_skill.py --list_cameras to confirm the resolved camera list.
Run the skill.
Never run with an empty api_key. Never run with cameras empty. When the user has multiple cameras, never accept missing/duplicate names — re-prompt until each camera has a unique label. Never ask the user to manually edit config.json.
FileContentlogs/app.logApplication log (rotates daily, keeps 30 days)logs/alarms.jsonlAll alarm events + clip analysis resultslogs/transitions.jsonlAll motion trigger events
bash
# Count alarms today
grep '"alarm"' logs/alarms.jsonl | grep "$(date +%Y-%m-%d)" | wc -l
# Transitions vs alarms (false positive rate)
wc -l logs/transitions.jsonl logs/alarms.jsonl
# Export alarms as CSV
cat logs/alarms.jsonl | python3 -c "
import sys, json
for line in sys.stdin:
obj = json.loads(line)
if obj.get('event') == 'alarm':
print(f\"{obj['_ts']},{obj.get('type','')},{obj.get('fall_type','')},{obj.get('confidence',0)},{obj.get('frame',0)}\")
"
IssueSolutionNo alarms detectedCheck RTSP stream is active; verify camera angle covers monitoring areaToo many false alarmsAdjust camera position; reduce motion sensitivity areaAPI errorsVerify API key is valid; check internet connectionStream disconnectsCheck network stability; camera may need reboot
text
kami-fall-detection/
├── SKILL.md # Documentation
├── config.json # Configuration (auto-managed by agent)
├── fall_detect_cloud_skill.py # Production entry point
├── setup.sh # Installer
└── requirements.txt # Dependencies