Skill: michik1712/awekas-current (version 1.0.0)

# AWEKAS Current Weather Skill ## Name awekas-current ## Version 2.0.0 ## Stability production --- ## Description Fetches and normalizes current weather data from the AWEKAS API. --- ## Entry awekasCurrent.js --- ## Features - retry + exponential backoff - 60s in-memory caching - timeout protection (8s) - normalized weather schema - safe JSON parsing fallback - structured error output --- ## Parameters ### key (required) AWEKAS API key ### station (optional) Station ID --- ## Permissions - network --- ## Output ```json id="out" { "source": "AWEKAS", "cached": false, "station": "string", "data": { "temperature": null, "humidity": null, "pressure": null, "wind": { "speed": null, "direction": null }, "rain": null, "raw": {} } } --- ## Usage ```bash openclaw awekas-current --key YOUR_KEY --station 12345 --- # 📦 `package.json` ```json id="pkgfinal" { "name": "openclaw-awekas-current", "version": "2.0.0", "type": "module", "main": "awekasCurrent.js", "engines": { "node": ">=18" }, "keywords": [ "openclaw", "skill", "weather", "awekas" ], "dependencies": { "node-fetch": "^3.3.2" } }

path: awekasCurrent.js
content: import fetch from "node-fetch";

const CACHE_TTL = 60_000;
const cache = new Map();

const sleep = (ms) => new Promise(r => setTimeout(r, ms));

function normalize(data) {
  return {
    temperature: data?.temperature ?? data?.temp ?? null,
    humidity: data?.humidity ?? null,
    pressure: data?.pressure ?? null,
    wind: {
      speed: data?.wind_speed ?? data?.wind?.speed ?? null,
      direction: data?.wind_dir ?? data?.wind?.direction ?? null,
    },
    rain: data?.rain ?? null,
    raw: data,
  };
}

async function fetchWithRetry(url, retries = 2) {
  for (let i = 0; i <= retries; i++) {
    try {
      const controller = new AbortController();
      const timeout = setTimeout(() => controller.abort(), 8000);

      const res = await fetch(url, { signal: controller.signal });
      const text = await res.text();

      clearTimeout(timeout);

      if (!res.ok) throw new Error(`HTTP ${res.status}: ${text}`);
      return text;
    } catch (err) {
      if (i === retries) throw err;
      await sleep(500 * (i + 1));
    }
  }
}

export default {
  name: "awekas-current",

  async run(ctx, args) {
    const [REDACTED_SECRET] || process.env.AWEKAS_KEY;

    if (!apiKey) {
      throw new Error("Missing API key (key or AWEKAS_KEY)");
    }

    const station = args.station || "default";
    const cacheKey = `${station}:${apiKey}`;
    const now = Date.now();

    const cached = cache.get(cacheKey);
    if (cached && now - cached.time < CACHE_TTL) {
      return {
        source: "AWEKAS",
        cached: true,
        station,
        data: cached.data,
      };
    }

    const url = new URL("https://api.awekas.at/current.php");
    url.searchParams.set("key", apiKey);

    if (args.station) {
      url.searchParams.set("station", args.station);
    }

    try {
      const text = await fetchWithRetry(url.toString(), 2);

      let parsed;
      try {
        parsed = JSON.parse(text);
      } catch {
        parsed = { raw: text };
      }

      const normalized = normalize(parsed);

      cache.set(cacheKey, {
        time: now,
        data: normalized,
      });

      return {
        source: "AWEKAS",
        station,
        cached: false,
        data: normalized,
      };
    } catch (err) {
      const message = err?.message || String(err);

      ctx?.log?.(`AWEKAS error: ${message}`);

      throw {
        error: "AWEKAS_FETCH_FAILED",
        type:
          message.includes("HTTP") ? "api_error"
          : message.includes("abort") ? "timeout"
          : "network_error",
        message,
      };
    }
  },
};

path: package.json
content: {
  "name": "awekas-current",
  "version": "2.0.0",
  "type": "module",
  "main": "awekasCurrent.js",
  "engines": {
    "node": ">=18"
  },
  "keywords": [
    "openclaw",
    "skill",
    "weather",
    "awekas"
  ],
  "dependencies": {
    "node-fetch": "^3.3.2"
  }
}

path: README.md
content: # OpenClaw AWEKAS Current Weather Skill

Production-ready weather skill for OpenClaw.

## Install

```bash
openclaw install openclaw-awekas-current


openclaw awekas-current --key YOUR_API_KEY --station 12345

export AWEKAS_KEY="your_key"

Security scan verdicts — ClawScan: clean | static analysis: suspicious | VirusTotal: clean | SkillSpector: clean (LOW)