import { SCADA_FIELDS, type ElementType } from "../core/constants.js"; import { CliError } from "../core/errors.js"; import { emitApi } from "../core/http.js"; import { fieldsFor, optionalString, parseOptions, requiredString, requiredStringArray, validateChoice } from "../core/options.js"; import { requireNetwork, resolveScheme } from "../core/runtime.js"; import { parseTime } from "../core/time.js"; import type { HandlerMap, RuntimeContext } from "../core/types.js"; function rangeGet(ctx: RuntimeContext, argv: string[], summary: string, path: string): Promise { const { values } = parseOptions(argv); return emitApi(ctx, summary, { method: "GET", path, params: { start_time: parseTime(requiredString(values, "start-time"), "--start-time"), end_time: parseTime(requiredString(values, "end-time"), "--end-time") }, requireProject: true, }); } function realtimeByIdTime(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); return emitApi(ctx, "读取实时模拟数据成功", { method: "GET", path: "/realtime/query/by-id-time", params: { id: requiredString(values, "id"), type: validateChoice(requiredString(values, "type"), ["pipe", "junction"] as const, "--type"), query_time: parseTime(requiredString(values, "time"), "--time") }, requireProject: true, }); } function realtimeByTimeProperty(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); const type = validateChoice(requiredString(values, "type"), ["pipe", "junction"] as const, "--type"); return emitApi(ctx, "读取实时属性聚合数据成功", { method: "GET", path: "/realtime/query/by-time-property", params: { type, query_time: parseTime(requiredString(values, "time"), "--time"), property: validateChoice(requiredString(values, "property"), fieldsFor(type), "--property") }, requireProject: true, }); } function schemeLinks(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); return emitApi(ctx, "读取方案管道数据成功", { method: "GET", path: "/scheme/links", params: { scheme_name: resolveScheme(ctx, optionalString(values, "scheme"), true), scheme_type: optionalString(values, "scheme-type") || "simulation", start_time: parseTime(requiredString(values, "start-time"), "--start-time"), end_time: parseTime(requiredString(values, "end-time"), "--end-time"), }, requireProject: true, }); } function schemeNodeField(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); return emitApi(ctx, "读取方案节点字段成功", { method: "GET", path: `/scheme/nodes/${requiredString(values, "node")}/field`, params: { field: validateChoice(requiredString(values, "field"), fieldsFor("junction"), "--field"), scheme_name: resolveScheme(ctx, optionalString(values, "scheme"), true), scheme_type: optionalString(values, "scheme-type") || "simulation", start_time: parseTime(requiredString(values, "start-time"), "--start-time"), end_time: parseTime(requiredString(values, "end-time"), "--end-time"), }, requireProject: true, }); } function schemeSimulation(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); const query = validateChoice(requiredString(values, "query"), ["by-id-time", "by-scheme-time-property"] as const, "--query"); const type = validateChoice(optionalString(values, "type") || "pipe", ["pipe", "junction"] as const, "--type") as ElementType; const params: Record = { scheme_name: resolveScheme(ctx, optionalString(values, "scheme"), true), scheme_type: optionalString(values, "scheme-type") || "simulation", query_time: parseTime(requiredString(values, "time"), "--time"), type, }; if (query === "by-id-time") { params.id = requiredString(values, "id"); return emitApi(ctx, "读取方案单点模拟数据成功", { method: "GET", path: "/scheme/query/by-id-time", params, requireProject: true }); } params.property = validateChoice(requiredString(values, "property"), fieldsFor(type), "--property"); return emitApi(ctx, "读取方案属性聚合数据成功", { method: "GET", path: "/scheme/query/by-scheme-time-property", params, requireProject: true }); } function scadaQuery(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv, { "device-id": "repeat" }); const params: Record = { device_ids: requiredStringArray(values, "device-id").join(","), start_time: parseTime(requiredString(values, "start-time"), "--start-time"), end_time: parseTime(requiredString(values, "end-time"), "--end-time"), }; const field = optionalString(values, "field"); if (field) params.field = validateChoice(field, SCADA_FIELDS, "--field"); return emitApi(ctx, "读取 SCADA 时序成功", { method: "GET", path: field ? "/scada/by-ids-field-time-range" : "/scada/by-ids-time-range", params, requireProject: true }); } function composite(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv, { feature: "repeat", "use-cleaned": "boolean" }); const kind = validateChoice(requiredString(values, "kind"), ["scada-simulation", "element-simulation", "element-scada"] as const, "--kind"); const params: Record = { start_time: parseTime(requiredString(values, "start-time"), "--start-time"), end_time: parseTime(requiredString(values, "end-time"), "--end-time"), }; const schemeName = resolveScheme(ctx, optionalString(values, "scheme")); if (schemeName) Object.assign(params, { scheme_name: schemeName, scheme_type: optionalString(values, "scheme-type") || "simulation" }); if (kind === "scada-simulation") params.device_ids = requiredStringArray(values, "feature").join(","); else if (kind === "element-simulation") params.feature_infos = requiredStringArray(values, "feature").join(","); else { const feature = requiredStringArray(values, "feature"); if (feature.length !== 1) throw new CliError("CLI 参数错误", "FEATURE_REQUIRED", "element-scada requires exactly one --feature as element_id", 2); params.element_id = feature[0]; params.use_cleaned = Boolean(values["use-cleaned"]); } return emitApi(ctx, kind === "scada-simulation" ? "读取复合 SCADA-模拟数据成功" : kind === "element-simulation" ? "读取复合元素模拟数据成功" : "读取元素关联 SCADA 数据成功", { method: "GET", path: `/composite/${kind}`, params, requireProject: true }); } function pipelineHealth(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); requiredString(values, "pipe"); requiredString(values, "start-time"); return emitApi(ctx, "读取管道健康预测成功", { method: "GET", path: "/composite/pipeline-health-prediction", params: { network_name: requireNetwork(ctx), query_time: parseTime(requiredString(values, "end-time"), "--end-time") }, requireProject: true, requireNetworkCtx: true, }); } function dataScadaGet(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); validateChoice(requiredString(values, "kind"), ["info"] as const, "--kind"); return emitApi(ctx, "读取 SCADA 数据成功", { method: "GET", path: "/getscadainfo/", params: { network: requireNetwork(ctx), id: requiredString(values, "id") }, requireNetworkCtx: true }); } function dataScadaList(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); validateChoice(requiredString(values, "kind"), ["info"] as const, "--kind"); return emitApi(ctx, "读取 SCADA 列表成功", { method: "GET", path: "/getallscadainfo/", params: { network: requireNetwork(ctx) }, requireNetworkCtx: true }); } function dataSchemeGet(ctx: RuntimeContext, argv: string[]): Promise { const { values } = parseOptions(argv); return emitApi(ctx, "读取方案成功", { method: "GET", path: "/getscheme/", params: { network: requireNetwork(ctx), schema_name: requiredString(values, "name") }, requireNetworkCtx: true }); } export const dataHandlers: HandlerMap = { "data timeseries realtime links": (ctx, argv) => rangeGet(ctx, argv, "读取实时管道数据成功", "/realtime/links"), "data timeseries realtime nodes": (ctx, argv) => rangeGet(ctx, argv, "读取实时节点数据成功", "/realtime/nodes"), "data timeseries realtime simulation-by-id-time": realtimeByIdTime, "data timeseries realtime simulation-by-time-property": realtimeByTimeProperty, "data timeseries scheme links": schemeLinks, "data timeseries scheme node-field": schemeNodeField, "data timeseries scheme simulation": schemeSimulation, "data timeseries scada query": scadaQuery, "data timeseries composite": composite, "data timeseries composite pipeline-health": pipelineHealth, "data scada get": dataScadaGet, "data scada list": dataScadaList, "data scheme schema": (ctx) => emitApi(ctx, "读取方案 schema 成功", { method: "GET", path: "/getschemeschema/", params: { network: requireNetwork(ctx) }, requireNetworkCtx: true }), "data scheme get": dataSchemeGet, "data scheme list": (ctx) => emitApi(ctx, "读取方案列表成功", { method: "GET", path: "/getallschemes/", params: { network: requireNetwork(ctx) }, requireNetworkCtx: true }), };