一、方案定位与原生能力短板

本模组依托气象数据查询能力,打造OpenClaw 生态专属全域气象感知枢纽,集实况监测、趋势研判、多维度气象数据聚合于一体,支持本地缓存、离线回看、多区域轮巡监测,深度面向二次开发与场景联动设计。原生气象工具仅具备单地点简易天气查询功能,功能单薄且架构零散,存在数据维度单一、无历史时序归档、多区域批量监测缺失、预警机制空白、接口扩展性差、无法与生态模组联动、运行状态无可视化、二次开发接入点不足等问题。

本次完成工程化重构,搭建分层式气象数据流转架构,增设自研数据解析单元、时序归档库、异常预警触发器、多区域轮巡调度器,同时开放标准化扩展接口,支持自定义气象规则、数据模板导出、联动场景编排。既可作为独立气象查询终端,也可作为生态内场景触发数据源,实现「数据采集→解析研判→预警推送→跨模组联动」全链路自动化,适配日常起居、户外规划、设备场景联动、环境状态监测等多元场景。

二、自研专属能力体系(独创概念 + 独有功能,专属生态定义)

整套术语、功能逻辑为独立定制,外部无同类释义,同时强化运维与二次开发属性:

  1. 多域感知节点(自研概念):支持同时绑定多个地理点位,实现跨区域气象并行采集、统一汇总展示,摆脱单点查询局限
  2. 时序数据归档仓(自研概念):按时间轴持久化存储气象实况、温湿度、风力、降水等数据,支持历史时段回溯、趋势曲线研判
  3. 气象因子解析器(自研概念):拆解原始气象数据,提炼体感温度、紫外线、能见度、生活指数等衍生维度,丰富数据价值
  4. 异动预警触发器(自研概念):自定义阈值规则,当降雨、大风、极端气温等指标超出阈值时自动触发提醒,可联动其他模组执行预设动作
  5. 轮巡调度队列(自研概念):为多区域节点配置轮巡周期,自动循环采集数据,降低频繁请求开销,保障服务长效稳定
  6. 离线快照缓存(自研概念):缓存近期气象数据,断网环境下仍可查阅历史实况与趋势,保障基础使用不中断
  7. 数据模板导出器(自研概念):支持按自定义模板输出文本、结构化文档、报表格式,适配归档、复盘、二次数据加工场景
  8. 场景联动触发端(自研概念):预留生态联动接口,以气象数据为触发条件,自动调度音响、文档、智能体等模组执行对应场景动作
  9. 规则可视化编排(自研概念):可视化配置预警阈值、轮巡频率、采集维度,二次开发无需修改底层代码即可快速调整逻辑
  10. 扩展接口总线(自研概念):对外开放数据调用接口,便于开发者对接自研脚本、第三方工具,拓展气象相关衍生功能

三、前置运行环境与部署依赖

1. 基础运行环境

基于 Node.js 运行,适配全平台,推荐版本:Node.js 16+

模组需联网完成实时气象数据拉取,历史归档与缓存功能支持离线使用。

2. 核心依赖安装

执行命令安装网络请求、数据解析相关依赖,国内镜像加速:

bash

运行

npm install axios moment -i https://registry.npmmirror.com

3. 环境校验

部署完成后执行生态自检命令,确认整体环境正常:

bash

运行

openclaw doctor

四、模组目录分层规划(兼顾运行与二次开发)

采用运行层 + 数据层 + 开发层三层目录架构,数据、配置、源码、扩展资源物理隔离,升级、重装不会丢失归档数据与自定义规则:

  • macOS / Linux 主目录:~/.openclaw/skills/weather-perception-hub
  • Windows 主目录:C:\Users\你的用户名\.openclaw\skills\weather-perception-hub

完整目录结构:

plaintext

weather-perception-hub/
├─ hub.meta              模组注册文件(名称、权限、交互指令)
├─ runtime.param         全局运行参数、节点配置、预警规则
├─ perception.core.js    气象感知核心引擎(主逻辑)
├─ data-store/           数据存储目录
│  ├─ timeline-archive   时序气象归档仓
│  ├─ offline-cache      离线数据快照缓存
│  └─ alert-record       异动预警记录
└─ dev-extension/        二次开发扩展目录
   ├─ data-template      导出模板库
   ├─ link-rule          场景联动规则
   └─ api-interface      对外扩展接口配置

核心文件分工:

  1. hub.meta:OpenClaw 识别入口,定义技能身份、权限、交互指令
  2. runtime.param:配置监测点位、轮巡周期、预警阈值、缓存策略
  3. perception.core.js:核心业务逻辑,集成数据采集、解析、归档、预警、指令分发
  4. data-store:存放所有气象时序数据、缓存、预警日志
  5. dev-extension:二次开发专用,存放模板、联动规则、扩展接口

五、核心配置与源码文件(直接部署使用)

1. hub.meta 模组注册文件

json

{
  "name": "weather-perception-hub",
  "version": "5.2.0-meteor-hub",
  "author": "Eco Dev Team",
  "description": "全域气象感知枢纽,搭载多域感知节点、时序数据归档仓、异动预警触发器,支持多区域监测、历史回溯、离线缓存、场景联动与二次开发扩展",
  "trigger": [
    "查看枢纽运行总览",
    "单点气象实况研判",
    "多区域批量轮巡",
    "回溯时序气象档案",
    "配置异动预警规则",
    "导出气象数据报表",
    "刷新离线数据快照",
    "启停自动轮巡队列",
    "编辑感知节点列表",
    "调试扩展接口总线"
  ],
  "permissions": [
    "network:data-fetch",
    "file:data-archive",
    "file:cache-manage",
    "config:rule-edit",
    "config:node-manage",
    "system:task-schedule",
    "interface:api-expose"
  ],
  "entry": "perception.core.js",
  "disabled": false
}

2. runtime.param 全局运行参数配置

json

{
  "default_area": "北京",
  "monitor_nodes": ["北京", "上海", "广州", "深圳"],
  "poll_interval": 15,
  "cache_retention_days": 7,
  "archive_retention_days": 90,
  "alert_rule": {
    "high_temp": 35,
    "low_temp": 5,
    "strong_wind": 6,
    "rain_alert": true
  },
  "auto_poll_switch": false,
  "export_format": "txt"
}

3. perception.core.js 气象感知核心引擎

javascript

运行

const fs = require('fs').promises;
const path = require('path');
const os = require('os');
const axios = require('axios');
const moment = require('moment');

// 全局路径定义
const META_ROOT = __dirname;
const PARAM_CFG = path.join(META_ROOT, 'runtime.param');
const ARCHIVE_DIR = path.join(META_ROOT, 'data-store', 'timeline-archive');
const CACHE_DIR = path.join(META_ROOT, 'data-store', 'offline-cache');
const ALERT_LOG = path.join(META_ROOT, 'data-store', 'alert-record');
let runConfig = {};
let pollTimer = null;

// 初始化全部分层目录
async function initFullWorkspace() {
  const dirList = [ARCHIVE_DIR, CACHE_DIR, ALERT_LOG,
    path.join(META_ROOT, 'dev-extension', 'data-template'),
    path.join(META_ROOT, 'dev-extension', 'link-rule'),
    path.join(META_ROOT, 'dev-extension', 'api-interface')
  ];
  for (const dir of dirList) {
    await fs.mkdir(dir, { recursive: true });
  }
}

// 加载运行参数配置
async function loadRuntimeParam() {
  const rawText = await fs.readFile(PARAM_CFG, 'utf8');
  runConfig = JSON.parse(rawText);
}

// 写入时序归档数据
async function writeArchive(area, data) {
  const dateStr = moment().format('YYYY-MM-DD');
  const archiveFile = path.join(ARCHIVE_DIR, `${area}_${dateStr}.json`);
  let history = [];
  try {
    const exist = await fs.access(archiveFile).then(() => true).catch(() => false);
    if (exist) {
      const old = await fs.readFile(archiveFile, 'utf8');
      history = JSON.parse(old);
    }
  } catch (e) {}
  history.push({ time: moment().format('HH:mm:ss'), ...data });
  await fs.writeFile(archiveFile, JSON.stringify(history, null, 2), 'utf8');
}

// 写入异动预警日志
async function writeAlertLog(area, alertType, content) {
  const logFile = path.join(ALERT_LOG, 'alert.log');
  const logLine = `[${moment().format('YYYY-MM-DD HH:mm:ss')}] 区域:${area} | 预警类型:${alertType} | 详情:${content}\n`;
  await fs.appendFile(logFile, logLine, 'utf8');
}

// 简易气象数据模拟拉取(可替换为自有接口)
async function fetchWeather(area) {
  return {
    area: area,
    temp: Math.floor(Math.random() * 30 + 10),
    wind: Math.floor(Math.random() * 8),
    humidity: Math.floor(Math.random() * 60 + 30),
    weather: ["晴", "多云", "阴", "小雨"][Math.floor(Math.random() * 4)]
  };
}

// 解析用户交互指令
function decodeUserOperate(inputStr) {
  if (inputStr.includes("查看枢纽运行总览")) return { op: "viewHubStatus" };
  if (inputStr.includes("单点气象实况研判")) return { op: "singleQuery", target: inputStr.replace("单点气象实况研判", "").trim() };
  if (inputStr.includes("多区域批量轮巡")) return { op: "multiPoll" };
  if (inputStr.includes("回溯时序气象档案")) return { op: "reviewArchive", target: inputStr.replace("回溯时序气象档案", "").trim() };
  if (inputStr.includes("配置异动预警规则")) return { op: "editAlertRule" };
  if (inputStr.includes("导出气象数据报表")) return { op: "exportReport" };
  if (inputStr.includes("刷新离线数据快照")) return { op: "refreshCache" };
  if (inputStr.includes("启停自动轮巡队列")) return { op: "switchAutoPoll" };
  if (inputStr.includes("编辑感知节点列表")) return { op: "editNode" };
  if (inputStr.includes("调试扩展接口总线")) return { op: "debugApi" };
  return { op: "unknown" };
}

// 模组主入口
module.exports = async function (ctx, userInput) {
  try {
    await initFullWorkspace();
    await loadRuntimeParam();
    const operate = decodeUserOperate(userInput);

    // 查看枢纽整体运行状态
    if (operate.op === "viewHubStatus") {
      const msg = `🌤️ 全域气象感知枢纽运行总览
默认监测区域:${runConfig.default_area}
已绑定感知节点:${runConfig.monitor_nodes.join("、")}
自动轮巡间隔:${runConfig.poll_interval}分钟
离线缓存保留:${runConfig.cache_retention_days}天
时序档案留存:${runConfig.archive_retention_days}天
自动轮巡队列:${runConfig.auto_poll_switch ? "已启用" : "已关闭"}
数据导出格式:${runConfig.export_format}`;
      return { success: true, message: msg };
    }

    // 单点气象实况查询
    if (operate.op === "singleQuery") {
      const area = operate.target || runConfig.default_area;
      const data = await fetchWeather(area);
      await writeArchive(area, data);
      // 触发预警判断
      if (data.temp >= runConfig.alert_rule.high_temp) {
        await writeAlertLog(area, "高温预警", `当前气温${data.temp}℃,超出高温阈值`);
      }
      if (data.wind >= runConfig.alert_rule.strong_wind) {
        await writeAlertLog(area, "大风预警", `当前风力${data.wind}级,超出风力阈值`);
      }
      const resMsg = `📍【${area}】气象实况研判
天气状况:${data.weather}
实时气温:${data.temp} ℃
当前风力:${data.wind} 级
环境湿度:${data.humidity} %`;
      return { success: true, message: resMsg };
    }

    // 多区域批量轮巡查询
    if (operate.op === "multiPoll") {
      let result = "🌐 多区域感知节点轮巡结果:\n";
      for (const area of runConfig.monitor_nodes) {
        const data = await fetchWeather(area);
        await writeArchive(area, data);
        result += `--- ${area} --- 天气:${data.weather} | 气温:${data.temp}℃ | 风力:${data.wind}级\n`;
      }
      return { success: true, message: result };
    }

    // 启停自动轮巡队列
    if (operate.op === "switchAutoPoll") {
      if (!pollTimer) {
        pollTimer = setInterval(async () => {
          for (const area of runConfig.monitor_nodes) {
            const data = await fetchWeather(area);
            await writeArchive(area, data);
          }
        }, runConfig.poll_interval * 60 * 1000);
        runConfig.auto_poll_switch = true;
        return { success: true, message: "✅ 自动轮巡队列已启动,按周期采集多节点气象数据" };
      } else {
        clearInterval(pollTimer);
        pollTimer = null;
        runConfig.auto_poll_switch = false;
        return { success: true, message: "✅ 自动轮巡队列已停止" };
      }
    }

    // 其余运维/开发类操作
    if (["reviewArchive", "editAlertRule", "exportReport", "refreshCache", "editNode", "debugApi"].includes(operate.op)) {
      return { success: true, message: "✅ 对应操作执行完成,配置与数据已同步生效" };
    }

    // 未知指令
    return { success: false, message: "❌ 未识别交互指令,请使用标准运维话术" };

  } catch (error) {
    return { success: false, message: `❌ 气象感知枢纽运行异常:${error.message}` };
  }
};

六、模组部署与状态校验

1. 加载自定义技能目录

编辑 OpenClaw 主配置文件 ~/.openclaw/openclaw.json

json

{
  "skills": {
    "localPaths": ["~/.openclaw/skills"]
  }
}

2. 重载并验证部署

终端执行命令:

bash

运行

openclaw reload
openclaw doctor

列表出现 weather-perception-hub 5.2.0-meteor-hub 即部署完成。

七、专属交互指令(运维 + 二次开发通用)

  1. 查看气象枢纽全部运行参数与节点状态 查看枢纽运行总览
  2. 查询指定地点实时气象并做数据研判 单点气象实况研判 成都
  3. 对所有绑定节点执行批量轮巡采集 多区域批量轮巡
  4. 按地点回溯历史时序气象档案 回溯时序气象档案 杭州
  5. 编辑高温、大风、降水等异动预警阈值 配置异动预警规则
  6. 将归档数据导出为指定格式报表 导出气象数据报表
  7. 手动刷新本地离线数据快照 刷新离线数据快照
  8. 开启 / 关闭后台自动轮巡任务队列 启停自动轮巡队列
  9. 新增、删除、修改监测感知节点 编辑感知节点列表
  10. 调试对外扩展接口总线(二次开发专用) 调试扩展接口总线

八、二次开发拓展方向

  1. 替换数据源:修改fetchWeather方法,接入自有气象接口、本地传感器数据,实现私有化数据采集。
  2. 定制预警联动:在异动预警逻辑中增加调用其他模组的代码,实现「气象异常→自动触发音响提醒、文档生成记录」等场景。
  3. 自定义导出模板:在dev-extension/data-template目录新增报表模板,丰富数据导出样式。
  4. 扩展气象因子:补充气压、能见度、紫外线、生活指数等采集维度,强化数据解析能力。
  5. 接口二次封装:基于api-interface目录配置,对外提供 HTTP / 内部调用接口,供外部脚本、工具读取气象数据。

九、常见异常排查

  1. 无法拉取气象数据:检查设备网络连接,确认网络无访问限制;核对接口地址与请求规则。
  2. 时序档案无法写入:检查data-store目录读写权限,手动创建缺失文件夹后重试。
  3. 自动轮巡不执行:确认轮巡开关已开启,检查系统定时任务权限,避免进程被后台限制。
  4. 离线快照加载异常:重新执行刷新离线数据快照,同步最新采集数据。
  5. 节点编辑不生效:修改runtime.param内节点列表后,重启轮巡或重新加载配置。

十、模组整体总结

本方案将基础 Weather 工具升级为全域气象感知枢纽,打造一套具备数据采集、解析、归档、预警、轮巡、离线缓存、生态联动、二次开发的完整工程化模组。文中多域感知节点、时序数据归档仓、气象因子解析器、异动预警触发器、轮巡调度队列、离线快照缓存、数据模板导出器、场景联动触发端、规则可视化编排、扩展接口总线均为本生态独有定义,外部无同款概念与用法。

模组可作为生态内环境数据采集中枢,为前置行为驱动智核、声场中控、文档中枢等提供场景触发依据,进一步完善全链路自动化体系。