Skill: allmightysauron/solax-cloud-api (version 1.0.0)

--- name: solax-summary-fetch description: Fetch inverter summary data from the Solax Cloud API using the npm package solax-cloud-api. Use when the user provides (or has configured) a Solax tokenId and inverter serial number (sn) and wants current/summary energy data returned as JSON (typed as SolaxSummary) for dashboards/automation. --- # solax-summary-fetch Fetch Solax inverter summary data as JSON. ## Setup (one-time) This skill uses Node.js and the npm package `solax-cloud-api`. Install dependencies inside the skill folder: ```bash cd /home/openclaw/.openclaw/workspace/skills/solax-summary-fetch/scripts npm install ``` (We use `npm install` instead of `npm ci` because this skill does not ship with a lockfile.) ## Inputs You need: - `tokenId` (Solax Cloud API token id) - `sn` (inverter serial number) ### Recommended: environment variables Set these in your runtime (preferred so you don’t leak secrets into shell history): - `SOLAX_TOKENID` - `SOLAX_SN` **Do not** hardcode credentials into the skill files. ### Alternate: CLI arguments Pass them explicitly as: - `--tokenId <tokenId>` - `--sn <serial>` ## Command ```bash cd /home/openclaw/.openclaw/workspace/skills/solax-summary-fetch/scripts node fetch_summary.mjs --tokenId "$SOLAX_TOKENID" --sn "$SOLAX_SN" ``` ## Output - Prints a single JSON object to stdout. - The JSON conforms to the **SolaxSummary** interface exposed by `solax-cloud-api` (see `references/solax-summary.d.ts`). - Under the hood (solax-cloud-api v0.2.0): fetches `getAPIData()` then converts via `SolaxCloudAPI.toSummary()`. ## Guardrails - Never print or log the tokenId beyond confirming whether it is set (redact it). - If the API call fails, return a structured error JSON with `ok:false` and a short `error` message.

path: scripts/fetch_summary.mjs
content: #!/usr/bin/env node
import process from "node:process";

function getArg(flag) {
  const i = process.argv.indexOf(flag);
  if (i === -1) return undefined;
  return process.argv[i + 1];
}

function redact(s) {
  if (!s) return s;
  if (s.length <= 6) return "***";
  return `${s.slice(0, 2)}…${s.slice(-2)}`;
}

const tokenId = getArg("--tokenId") || process.env.SOLAX_TOKENID;
const sn = getArg("--sn") || process.env.SOLAX_SN;

if (!tokenId || !sn) {
  console.log(
    JSON.stringify(
      {
        ok: false,
        error: "missing_input",
        missing: {
          tokenId: !tokenId,
          sn: !sn,
        },
        hint: "Provide --tokenId/--sn or set SOLAX_TOKENID and SOLAX_SN",
      },
      null,
      2
    )
  );
  process.exit(2);
}

import { createRequire } from "node:module";

let SolaxCloudAPI, INVERTER_BRAND;
try {
  // solax-cloud-api@0.2.0 ships a broken ESM entry in some builds on Node 22+.
  // Use CJS require to load the working dist/cjs bundle.
  const require = createRequire(import.meta.url);
  const mod = require("solax-cloud-api");

  SolaxCloudAPI = mod.SolaxCloudAPI || mod.default?.SolaxCloudAPI || mod.default;
  INVERTER_BRAND = mod.INVERTER_BRAND || mod.default?.INVERTER_BRAND;

  if (!SolaxCloudAPI) throw new Error("Missing SolaxCloudAPI export");
} catch (e) {
  console.log(
    JSON.stringify(
      {
        ok: false,
        error: "missing_dependency",
        detail:
          "Failed to load solax-cloud-api. Ensure it is installed (npm install in scripts/) and that the package exports are compatible.",
        message: e?.message || String(e),
      },
      null,
      2
    )
  );
  process.exit(3);
}

try {
  const brand = INVERTER_BRAND?.SOLAX ?? 0;
  const api = new SolaxCloudAPI(brand, tokenId, sn);

  const resp = await api.getAPIData();
  if (!resp || resp.success !== true) {
    throw new Error(resp?.exception || "Solax API returned success=false");
  }

  const summary = SolaxCloudAPI.toSummary(resp.result);
  console.log(JSON.stringify(summary, null, 2));
} catch (e) {
  console.log(
    JSON.stringify(
      {
        ok: false,
        error: "solax_api_error",
        message: e?.message || String(e),
        tokenId: redact(tokenId),
        sn,
      },
      null,
      2
    )
  );
  process.exit(1);
}


path: scripts/package.json
content: {
  "name": "solax-summary-fetch-scripts",
  "private": true,
  "type": "module",
  "dependencies": {
    "solax-cloud-api": "0.2.0"
  }
}


path: references/solax-summary.d.ts
content: // SolaxSummary typing reference.
//
// IMPORTANT:
// - This is a best-effort interface. The exact fields depend on the `solax-cloud-api` package version
//   and the Solax Cloud API response.
// - When you run fetch_summary.mjs, the JSON it prints should conform to the SolaxSummary shape
//   exposed by the package you installed.
//
// If you want strict typing, we can generate this from the installed package types (if present)
// or from a sample response.

export interface SolaxSummary {
  // Common fields seen in Solax summary responses (may vary)
  sn?: string;
  plantName?: string;

  // Power / energy
  acPower?: number;
  yieldToday?: number;
  yieldTotal?: number;

  // Status
  inverterStatus?: string | number;

  // Allow additional fields
  [key: string]: unknown;
}


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