import { createBoxState, createGatewayState } from "../sim/model.mjs"; import { createPatchPanelState, createWiringConfig } from "./model.mjs"; export const MVP_BOX_IDS = Object.freeze(["boxsim_alpha", "boxsim_beta"]); export const MVP_GATEWAY_IDS = Object.freeze(["gwsimu_east", "gwsimu_west"]); export const M3_BOX_IDS = Object.freeze(["boxsimu_1", "boxsimu_2"]); export const M3_GATEWAY_IDS = Object.freeze(["gwsimu_1", "gwsimu_2"]); export const M3_BOX_RESOURCES = Object.freeze(["res_boxsimu_1", "res_boxsimu_2"]); function createGatewaySessionIds(gatewayIds) { return gatewayIds.map((gatewayId) => `gws_${gatewayId}`); } export function createMvpTopology({ now = "2026-01-01T00:00:00.000Z" } = {}) { const gatewaySessionIds = createGatewaySessionIds(MVP_GATEWAY_IDS); const boxes = MVP_BOX_IDS.map((boxId, index) => createBoxState({ boxId, gatewaySessionId: gatewaySessionIds[index], ports: ["uart0", "eth0", "gpio0"], includePortDefinitions: false, now }) ); const gateways = MVP_GATEWAY_IDS.map((gatewayId, index) => createGatewayState({ gatewayId, endpoint: `http://127.0.0.1:${7101 + index}`, boxes: [boxes[index].resource.resourceId], now }) ); const wiringConfig = createWiringConfig({ gatewaySessionId: gatewaySessionIds[0], connections: [ { from: { resourceId: boxes[0].resource.resourceId, port: "uart0" }, to: { resourceId: boxes[1].resource.resourceId, port: "uart0" }, mode: "exclusive" }, { from: { resourceId: boxes[0].resource.resourceId, port: "gpio0" }, to: { resourceId: boxes[1].resource.resourceId, port: "gpio0" }, mode: "monitor" } ], now }); const patchPanel = createPatchPanelState({ gatewaySessionId: gatewaySessionIds[0], wiringConfig, now }); return { topologyId: "top_mvp_l2_l3_sim_patch", projectId: "prj_mvp_topology", environment: "dev", services: { boxes, gateways, patchPanel }, wiringConfig, constraints: { patchPanelIsOnlyCrossDeviceChannel: true, boxSimuLocalLoopbackForCrossDeviceSync: false }, dryRunHints: { cliTarget: "fixtures/mvp-topology/topology.json", expectedServices: ["hwlab-box-simu", "hwlab-gateway-simu", "hwlab-patch-panel"] } }; } export function createM3Topology({ now = "2026-05-21T00:00:00.000Z" } = {}) { const projectId = "prj_m3_hardware_loop"; const gatewaySessionIds = createGatewaySessionIds(M3_GATEWAY_IDS); const boxes = M3_BOX_IDS.map((boxId, index) => withProjectId(createBoxState({ boxId, gatewaySessionId: gatewaySessionIds[index], ports: ["DO1", "DI1"], now }), projectId) ); const gateways = M3_GATEWAY_IDS.map((gatewayId, index) => withProjectId(createGatewayState({ gatewayId, endpoint: `http://127.0.0.1:${7101 + index}`, boxes: [M3_BOX_RESOURCES[index]], now }), projectId) ); const wiringConfig = createWiringConfig({ wiringConfigId: "wir_m3_do1_di1", projectId, gatewaySessionId: gatewaySessionIds[0], name: "M3 simulated DO1 to DI1 patch wiring", connections: [ { from: { resourceId: M3_BOX_RESOURCES[0], port: "DO1" }, to: { resourceId: M3_BOX_RESOURCES[1], port: "DI1" }, mode: "exclusive" } ], now }); const patchPanel = createPatchPanelState({ patchPanelStatusId: "pps_m3_hardware_loop", gatewaySessionId: gatewaySessionIds[0], wiringConfig, metadata: { signal: "res_boxsimu_1:DO1 -> hwlab-patch-panel -> res_boxsimu_2:DI1" }, now }); return { topologyId: "top_m3_hardware_loop", projectId, environment: "dev", services: { boxes, gateways, patchPanel }, wiringConfig, constraints: { patchPanelIsOnlyCrossDeviceChannel: true, boxSimuLocalLoopbackForCrossDeviceSync: false }, dryRunHints: { cliTarget: "fixtures/mvp/m3-hardware-loop/topology.json", expectedServices: ["hwlab-box-simu", "hwlab-gateway-simu", "hwlab-patch-panel"] } }; } function withProjectId(record, projectId) { return { ...record, projectId, ...(record.resource ? { resource: { ...record.resource, projectId } } : {}), ...(record.capabilities ? { capabilities: record.capabilities.map((capability) => ({ ...capability, projectId })) } : {}), ...(record.session ? { session: { ...record.session, projectId } } : {}) }; }