7a0648088c
Merge PR #159 after Code Queue rebase and validation. Runner verified M3 cardinality, hardware-loop smoke, patch-panel runtime smoke, m3 readonly contract, and git diff check. This is source/config blocker removal only; it does not claim DEV-LIVE M3 pass.
194 lines
4.8 KiB
JavaScript
194 lines
4.8 KiB
JavaScript
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
|
|
}
|
|
}
|
|
: {})
|
|
};
|
|
}
|