基于OpenClaw与iCloud构建智能物品遗忘检测系统
1. 项目概述:从“龙虾”到“记忆守护者”
“龙虾:oi!你耳机忘拿了!”——这个项目标题乍一看有点无厘头,但如果你和我一样,是个经常把AirPods、钥匙、钱包随手一放,然后花半小时满屋子“寻宝”的人,就会立刻会心一笑。这本质上是一个利用智能技术解决“丢三落四”这个古老痛点的创意项目。它的核心,是让我们的智能设备(比如手机)成为一个主动的、有“记忆”的助手,在你即将遗忘重要物品时,及时发出提醒。
最近技术圈里火热的“OpenClaw”(开源龙虾)项目,为这个想法提供了绝佳的实现土壤。OpenClaw不是一个具体的硬件产品,而是一个开源的AI智能体框架。你可以把它理解为一个高度可定制、能接入各种工具和服务的“数字大脑”。我们项目的核心思路,就是利用OpenClaw作为中枢,结合苹果生态的iCloud设备查找服务,构建一个自动化的工作流:当你的手机(作为随身核心设备)与某个被标记为“易忘物品”(如AirPods)的蓝牙设备断开连接,并且你开始移动(比如离开家或办公室)时,系统自动判断你可能遗忘了它,然后通过你最常用的通讯工具(如飞书、微信)向你发送一条像朋友提醒一样的消息:“oi!你耳机忘拿了!”
这不仅仅是简单的“断开连接即报警”,那样在办公室摘下耳机去接杯水也会误报,体验极差。真正的难点在于情境判断:如何区分“暂时放下”和“真正遗忘”?这就需要OpenClaw的AI能力介入,结合时间、地点、行为模式等多维度信息,做出更智能的推断。接下来,我将详细拆解如何从零搭建这样一个“记忆外挂”,把看似玩笑的标题,变成一个真正能提升生活效率的实用工具。
2. 核心思路与方案选型:为什么是OpenClaw + Apple生态?
要实现“拯救丢三落四”,市面上有各种思路。有纯粹的硬件方案,如Tile、AirTag这类蓝牙追踪器;也有纯软件方案,依赖手机自带的智能提醒。但我们选择OpenClaw + Apple生态的组合,是基于以下几个核心考量:
2.1 硬件方案的局限性像AirTag这样的产品,确实能解决“找不到”的问题,但它解决不了“忘记带”的问题。它需要你主动去查找,属于被动补救。而且,为每一件小物品(耳机、钥匙、工卡)都配一个追踪器,成本不低,管理也麻烦。我们的目标是预防遗忘,而非事后寻找。
2.2 纯软件方案的不足一些手机自带的“智能提醒”功能,例如基于地理围栏(Geofencing)的提醒,逻辑相对简单固定。比如“离开家时,如果耳机未连接,则提醒”。这种规则在复杂场景下容易失效:如果我在家楼下快递柜取个快递,触发“离开家”但很快回来,它也会报警,形成骚扰。我们需要更灵活、能学习的判断逻辑。
2.3 OpenClaw的核心优势:智能体与可编程性OpenClaw作为一个AI智能体框架,其最大优势是**“可编程的感知与决策”**。它可以通过插件(Skill)接入各种数据源(如iCloud设备状态、手机地理位置、日历事件),并利用大语言模型(LLM)的理解和推理能力,对这些信息进行综合判断。
- 情境理解:OpenClaw可以理解“早上8点离开家”和“下午3点离开办公室”是不同的场景。结合日历,它甚至能知道你今天是否有出差行程,从而调整判断遗忘物品的紧急程度。
- 自然交互:提醒消息可以不再是冰冷的系统通知,而是通过OpenClaw生成像朋友聊天一样的自然语言,如“嘿,赶着去开会吧?你的AirPods Pro好像还在办公桌上充电呢。”
- 无限扩展:今天提醒耳机,明天就可以通过同样的框架,接入智能家居传感器,提醒你“空调好像没关”,或者接入邮件日历,提醒你“下午的会议材料还没打印”。OpenClaw提供了一个统一的、可扩展的自动化大脑。
2.4 Apple生态的独特价值:iCloud Find My选择Apple生态,特别是iCloud的“查找”网络,是因为它提供了无感、精准的设备状态数据。AirPods、iPad、MacBook等苹果设备,只要登录同一Apple ID,其连接状态、电量、最后已知位置都会近乎实时地同步到iCloud。通过合法的API(如逆向工程后的私有API或家庭助理等第三方集成方案)获取这些数据,比从头开始用蓝牙扫描要稳定、准确得多。这是本项目能可靠运行的数据基石。
注意:直接调用苹果未公开的iCloud API存在风险,可能违反服务条款。在实际操作中,更稳妥的做法是使用像
icloudpd这样的开源工具,或通过Home Assistant的iCloud3集成来间接、安全地获取设备数据。本文后续将基于Docker容器部署的方案,这也是目前最稳定、最受社区推荐的方式。
方案总结:我们采用“OpenClaw(智能决策中枢)+ iCloud设备数据(状态输入)+ 即时通讯工具(提醒输出)”的架构。OpenClaw负责消化数据、理解情境、做出决策并触发行动,形成一个完整的自动化智能体。
3. 基础环境搭建:部署你的“数字大脑”OpenClaw
万事开头难,但OpenClaw的部署已经变得相当友好。为了避免在系统环境上耗费过多精力,我们首选Docker部署方案,它能实现环境隔离和一键启动。这里以在Ubuntu服务器或本地电脑(Windows/macOS均可,需安装Docker Desktop)上操作为例。
3.1 准备工作:安装Docker与Docker Compose如果你的系统还没有Docker,需要先安装。以Ubuntu为例:
# 更新软件包索引 sudo apt-get update # 安装依赖 sudo apt-get install ca-certificates curl # 添加Docker官方GPG密钥 sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod a+r /etc/apt/keyrings/docker.arc # 设置仓库 echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \ sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装Docker引擎 sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin # 验证安装 sudo docker run hello-world对于Windows/macOS用户,直接从Docker官网下载并安装Docker Desktop即可,它自带Docker Compose。
3.2 获取OpenClaw部署配置OpenClaw社区提供了详细的Docker Compose配置文件。我们创建一个项目目录并下载配置:
mkdir openclaw-reminder && cd openclaw-reminder # 从官方仓库获取docker-compose.yml示例文件(请以实际开源仓库地址为准) # 这里假设从Github获取,实际可能需要根据最新文档调整 wget https://raw.githubusercontent.com/openclaw-project/openclaw/main/docker-compose.yml你需要编辑这个docker-compose.yml文件。一个最简化的、用于本项目的核心服务配置可能包含以下部分:
version: '3.8' services: openclaw: image: openclaw/openclaw:latest container_name: openclaw restart: unless-stopped ports: - "3000:3000" # Web管理界面端口 environment: - OPENCLAW_MODEL_PROVIDER=ollama # 指定使用本地Ollama模型 - OPENCLAW_OLLAMA_BASE_URL=http://ollama:11434 # 连接Ollama服务 - OPENCLAW_DEFAULT_MODEL=llama3.1:8b # 默认使用的模型 - OPENCLAW_LOG_LEVEL=INFO depends_on: - ollama volumes: - ./data/openclaw:/app/data # 持久化数据 ollama: image: ollama/ollama:latest container_name: ollama restart: unless-stopped ports: - "11434:11434" volumes: - ./data/ollama:/root/.ollama # 持久化模型数据这个配置定义了两个服务:openclaw主程序和ollama大模型服务。我们使用Ollama来在本地运行开源大模型(如Llama 3.1),保证隐私和响应速度。
3.3 启动服务与下载模型配置好后,一键启动:
docker-compose up -d首次启动会拉取镜像,需要一些时间。启动后,访问http://你的服务器IP:3000即可看到OpenClaw的Web界面。 接下来,需要为Ollama下载一个大语言模型。进入Ollama容器内操作,或在宿主机上使用Ollama的CLI(如果已安装):
# 进入ollama容器 docker exec -it ollama bash # 在容器内下载模型,例如Llama 3.1 8B版本,这个模型在理解指令和情境判断上表现不错 ollama pull llama3.1:8b # 退出容器 exit模型下载完成后,OpenClaw就可以正常使用了。
实操心得:在资源有限的机器上(如家用NAS或低配VPS),首次启动和下载模型可能较慢,请耐心等待。模型选择上,
llama3.1:8b是精度和速度的较好平衡。如果机器性能更强,可以考虑qwen2.5:14b等更大模型,推理能力会更优。务必通过docker-compose logs -f openclaw查看日志,确保服务无报错启动。
4. 关键数据获取:安全接入iCloud设备状态
这是项目的关键一环,我们需要可靠地获取AirPods等苹果设备的实时连接状态。正如前文所述,我们不推荐直接破解苹果私有API。这里介绍通过Home Assistant(一个开源的智能家居平台)的iCloud3集成来间接获取数据,这是一个经过大量用户验证的稳定方案。
4.1 部署Home Assistant同样使用Docker部署Home Assistant Core:
# 在openclaw-reminder目录下,编辑docker-compose.yml,添加Home Assistant服务 # 将以下内容追加到services部分 homeassistant: image: homeassistant/home-assistant:stable container_name: homeassistant restart: unless-stopped volumes: - ./data/homeassistant:/config - /etc/localtime:/etc/localtime:ro ports: - "8123:8123" # HA Web界面端口 environment: - TZ=Asia/Shanghai然后更新并启动服务:
docker-compose up -d homeassistant访问http://你的服务器IP:8123完成Home Assistant的初始化设置。
4.2 安装并配置iCloud3集成
- 在HA的Web界面,点击左侧边栏的“设置” -> “设备与服务” -> “集成”。
- 点击右下角“添加集成”,搜索“iCloud3”。(如果官方集成列表没有,可能需要通过HACS(Home Assistant社区商店)先安装。安装HACS的教程在其官网很详细,此处不赘述。)
- 按照指引添加你的Apple ID(建议使用一个专用于此项目的、开启了两步验证的Apple ID,不要使用主力ID)。
- 配置过程中,iCloud3会要求你输入一个设备列表。你可以输入你的iPhone名称(如“张三的iPhone”)作为跟踪器,iCloud3会自动发现与此ID关联的其他设备,如AirPods、iPad等。
- 配置完成后,在HA的“概览”页面,你应该能看到代表你各个设备的实体(Entity),例如
sensor.airpods_pro_status(状态)、sensor.airpods_pro_battery(电量)等。
4.3 将设备状态暴露给OpenClawOpenClaw需要通过API读取这些状态。我们需要让HA提供API。
- 在HA中,点击你的用户名 -> “个人资料”页面最下方,创建一个“长期访问令牌”,复制下来。
- 我们需要通过HA的RESTful API将设备状态发布出去。一种简单方法是使用HA内置的“RESTful传感器”。在
configuration.yaml文件中添加(通过HA文件编辑器):
rest: - resource: http://localhost:8123/api/states/sensor.airpods_pro_status scan_interval: 30 # 每30秒更新一次 headers: Authorization: "Bearer YOUR_LONG_LIVED_ACCESS_TOKEN" Content-Type: application/json sensor: - name: "AirPods Status for OpenClaw" value_template: "{{ value_json.state }}" json_attributes: - last_updated这样,我们就创建了一个新的传感器,其状态与AirPods原状态同步。OpenClaw未来将调用这个新传感器的API。
重要注意事项:使用iCloud集成存在账号被暂时锁定的风险,特别是频繁查询时。iCloud3集成的优势在于它优化了查询逻辑,模拟了官方App的行为,比粗暴轮询更安全。务必使用独立的Apple ID,并确保该ID已开启双重认证。如果遇到“您的apple id 暂时不符合使用此应用程序的条件”这类错误,通常等待几小时或更换网络环境后可恢复。
5. 智能体技能开发:让OpenClaw学会判断与提醒
现在,我们有了大脑(OpenClaw)和数据(设备状态)。接下来要教OpenClaw学会“遗忘判断”这个技能。在OpenClaw中,技能(Skill)是通过Python脚本定义的。
5.1 创建“物品遗忘检测”技能在OpenClaw的数据目录下(我们之前挂载的./data/openclaw),通常会有skills文件夹。我们在此创建一个新文件forgetfulness_detector.py。
# forgetfulness_detector.py import asyncio import aiohttp import json from datetime import datetime, time from typing import Dict, Any from openclaw.skill import Skill, skill from openclaw.models import BaseMessage @skill class ForgetfulnessDetector(Skill): """检测用户是否可能遗忘重要物品的技能。""" def __init__(self): super().__init__() # 配置:需要监控的物品列表及其对应的HA传感器实体ID self.items_to_watch = { "airpods": "sensor.airpods_status_for_openclaw", # 对应HA中创建的传感器 # "keys": "sensor.tile_tracker_status", # 可以扩展其他蓝牙追踪器 } # 配置:家庭和工作场所的GPS坐标范围(通过HA zone或手动设定) self.home_zone = {"lat_min": 31.20, "lat_max": 31.23, "lon_min": 121.40, "lon_max": 121.43} self.office_zone = {"lat_min": 31.21, "lat_max": 31.22, "lon_min": 121.45, "lon_max": 121.46} # 配置:手机位置传感器的实体ID(也从HA获取) self.phone_location_entity = "device_tracker.your_iphone" self.ha_api_url = "http://homeassistant:8123/api/states/" self.ha_token = "YOUR_HA_LONG_LIVED_TOKEN" self.headers = { "Authorization": f"Bearer {self.ha_token}", "Content-Type": "application/json" } async def get_entity_state(self, session: aiohttp.ClientSession, entity_id: str) -> Dict[str, Any]: """从Home Assistant获取实体状态。""" try: async with session.get(f"{self.ha_api_url}{entity_id}", headers=self.headers) as resp: if resp.status == 200: return await resp.json() else: self.logger.error(f"Failed to get state for {entity_id}: {resp.status}") return {} except Exception as e: self.logger.error(f"Error fetching {entity_id}: {e}") return {} def is_in_zone(self, lat: float, lon: float, zone: Dict) -> bool: """判断给定坐标是否在指定区域内。""" return zone["lat_min"] <= lat <= zone["lat_max"] and zone["lon_min"] <= lon <= zone["lon_max"] async def execute(self, message: BaseMessage, **kwargs) -> str: """技能执行入口。""" self.logger.info("Forgetfulness Detector triggered.") async with aiohttp.ClientSession() as session: # 1. 获取手机当前位置 phone_data = await self.get_entity_state(session, self.phone_location_entity) if not phone_data or 'state' not in phone_data: return "无法获取手机位置信息。" phone_state = phone_data.get('state') # 假设状态是"home", "office", 或者具体的GPS坐标字符串 "31.22,121.42" phone_lat_lon = None if phone_state not in ['home', 'office', 'not_home']: # 尝试解析为坐标 try: lat_str, lon_str = phone_state.split(',') phone_lat_lon = (float(lat_str), float(lon_str)) except: pass # 2. 判断是否处于“离开”场景 is_leaving = False target_zone = None if phone_state == 'not_home' or (phone_lat_lon and not self.is_in_zone(phone_lat_lon[0], phone_lat_lon[1], self.home_zone)): # 简单逻辑:如果手机不在家,则认为可能离开 is_leaving = True # 这里可以更复杂:结合时间(如工作日早上8-9点)、移动速度等 # 例如,通过HA获取手机速度传感器,判断是否在快速移动(步行/驾车) if not is_leaving: return "当前未处于可能遗忘物品的离开场景。" # 3. 检查监控物品的状态 forgotten_items = [] for item_name, entity_id in self.items_to_watch.items(): item_data = await self.get_entity_state(session, entity_id) item_state = item_data.get('state', 'unknown').lower() if item_data else 'unknown' # 判断逻辑:如果物品状态为“未连接”(not_connected, disconnected)或“不在身边” # 具体状态字符串需要根据你的HA传感器实际输出调整 if item_state in ['not_connected', 'disconnected', 'away']: forgotten_items.append(item_name) # 4. 决策与触发 if forgotten_items: alert_msg = f"【提醒】你可能忘记了:{', '.join(forgotten_items)}。请检查一下!" self.logger.warning(alert_msg) # 在这里触发后续行动,例如调用飞书/webhook技能发送消息 # await self.trigger_alert(alert_msg) return alert_msg else: return "所有监控物品状态正常。" # async def trigger_alert(self, message: str): # """触发警报,例如发送到飞书。""" # # 这里可以调用另一个已经配置好的飞书消息技能 # # 或者直接发送HTTP请求到飞书机器人webhook # pass5.2 配置技能与触发器创建技能文件后,需要在OpenClaw的Web界面或配置文件中启用它。通常,需要在OpenClaw的配置文件(如config.yaml)里添加技能路径:
skills: - name: forgetfulness_detector path: /app/data/skills/forgetfulness_detector.py # Docker容器内的路径然后,我们需要设置一个触发器(Trigger),让这个技能定期自动运行。OpenClaw支持多种触发器,如定时任务(Cron)、Webhook、MQTT消息等。我们设置一个每2分钟运行一次的定时触发器: 在OpenClaw的Web管理界面,找到触发器配置部分,添加一个Cron触发器,表达式为*/2 * * * *,并关联到我们刚创建的ForgetfulnessDetector技能。
这样,一个基础的遗忘检测自动化流程就建立了:每两分钟,OpenClaw会检查一次手机是否离开“安全区”,并检查监控物品的连接状态,如果条件满足,就生成提醒消息。
6. 通知渠道集成:让提醒触手可及
生成的提醒消息需要送达给你。最直接的方式是集成到日常使用的通讯工具。这里以接入飞书机器人为例,微信、钉钉、Slack等流程类似。
6.1 创建飞书群聊与自定义机器人
- 在飞书中创建一个只有你(或需要接收提醒的成员)的群聊。
- 点击群聊设置 -> 添加机器人 -> 自定义机器人。
- 设置机器人名称,如“记忆守护者”,并获取生成的Webhook地址。这个地址格式类似
https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxxxxxx。妥善保存。
6.2 开发飞书消息发送技能在OpenClaw的skills目录下,再创建一个feishu_notifier.py文件。
# feishu_notifier.py import aiohttp import json from openclaw.skill import Skill, skill @skill class FeishuNotifier(Skill): """向飞书发送消息的技能。""" def __init__(self): super().__init__() self.webhook_url = "YOUR_FEISHU_WEBHOOK_URL_HERE" async def execute(self, message: BaseMessage, **kwargs) -> str: """发送消息到飞书。""" # message.content 是从上一个技能传递来的提醒内容 payload = { "msg_type": "text", "content": { "text": message.content } } async with aiohttp.ClientSession() as session: try: async with session.post(self.webhook_url, json=payload) as resp: if resp.status == 200: result = await resp.json() if result.get('code') == 0: return "消息已成功发送至飞书。" else: return f"飞书接口返回错误:{result}" else: return f"HTTP请求失败:{resp.status}" except Exception as e: return f"发送消息时发生异常:{e}"6.3 串联工作流:从检测到通知现在我们需要修改forgetfulness_detector.py技能,使其在检测到遗忘物品时,不是仅仅返回文本,而是自动调用FeishuNotifier技能。 在forgetfulness_detector.py的execute方法末尾,修改触发警报的部分:
if forgotten_items: alert_msg = f"🦞【龙虾提醒】oi!伙计,你是不是把 {', '.join(forgotten_items)} 落下了?赶紧看看!" self.logger.warning(alert_msg) # 创建消息对象,触发飞书通知技能 from openclaw.models import BaseMessage alert_message = BaseMessage(content=alert_msg, role="system") # 这里假设OpenClaw支持技能间调用,具体API需参考OpenClaw最新文档 # 一种常见模式是通过内置的“动作”或“调用”功能 # 例如:await self.call_skill("feishu_notifier", alert_message) # 另一种更通用的方式是,将alert_msg作为结果返回,并配置一个“规则引擎”或“后续动作”来捕获这个结果并调用飞书技能。 # 我们采用后一种:返回特定格式的结果,由OpenClaw的流程引擎处理。 return json.dumps({"action": "send_alert", "message": alert_msg})然后,在OpenClaw的流程配置中,我们可以设置一个规则:当forgetfulness_detector技能返回的结果包含"action": "send_alert"时,自动触发feishu_notifier技能,并将message字段的内容传递过去。
通过这样的串联,一个完整的“感知-判断-执行”的智能体工作流就闭环了。你的飞书会在你很可能忘记带耳机时,收到那条带着“龙虾”表情的、有点戏谑又很及时的提醒。
7. 优化、调试与扩展思路
基础功能跑通后,真正的挑战在于让系统变得可靠、智能且不扰民。以下是一些优化方向和踩坑记录。
7.1 核心优化:更精准的情境判断最初的“离开家即检测”逻辑太粗糙。我们需要多层条件过滤:
- 时间过滤:只在特定时段启用,例如工作日早7点至晚10点,周末可能放宽或禁用。
- 地点细化:不仅判断是否离开家,还要判断目的地。结合日历,如果是去健身房(耳机常用),则提醒权重增加;如果是去楼下便利店,则可能忽略。
- 物品状态深化:不仅看“是否连接”,还要看电量。如果AirPods电量低于10%且放在充电盒里,遗忘的概率极低,可以不提醒。
- 行为模式学习:可以记录每次的提醒和你的反馈(通过飞书快捷回复“已带/误报”),让OpenClaw背后的LLM微调判断逻辑,实现简单的个性化学习。
7.2 常见问题与排查
- 问题一:iCloud状态更新延迟。有时HA中设备状态会滞后几分钟。这可能是苹果服务器或网络问题。应对策略:在判断逻辑中加入“状态持续时间”判断,例如“连续3个检测周期(6分钟)状态为断开且位置已移动”,再触发提醒,避免瞬时抖动。
- 问题二:误报率高。除了上述优化,可以增加“免打扰模式”。当手机连接了家庭Wi-Fi或汽车蓝牙时,判定为短时间移动,不触发主要物品检测。
- 问题三:OpenClaw技能执行失败。首先查看OpenClaw容器日志
docker-compose logs -f openclaw。常见原因是Python依赖缺失、API token错误或网络超时。确保技能文件语法正确,且所有用到的Python包(如aiohttp)已在OpenClaw的基础镜像中或通过额外pip install安装。 - 问题四:飞书消息未发送。检查Webhook地址是否正确,网络是否通畅。飞书机器人有频率限制,过于频繁的测试可能被限流。
7.3 系统扩展:从“防忘”到“智能生活管家”这个框架的威力在于其扩展性。你可以轻松添加更多技能:
- 出门检查清单:结合天气技能,在早上第一次离开家时,提醒“今天有雨,带伞”和“记得带门禁卡”。
- 家居状态提醒:接入智能插座,判断如果晚上11点后,客厅灯还亮着且手机定位已在家,则提醒“客厅灯好像没关”。
- 日程同步提醒:读取日历,在会议开始前10分钟,若检测到耳机未连接,提醒“马上要开会了,带上耳机”。
- 多端通知:除了飞书,可以同时推送通知到Telegram、短信(通过Twilio等平台),确保重要提醒不漏。
整个系统就像你培养的一个数字伙伴,它默默观察、学习你的习惯,只在关键时刻用你喜欢的、不打扰的方式“戳”你一下。部署和维护这样一个系统需要一些技术耐心,但一旦稳定运行,它带来的那种“被默默关照”的体验,以及彻底告别因遗忘带来的小懊恼,绝对是值得的。
