Add full Ignition Perspective view.json generator with bindings, scripts, and controls
Extracts all CDW5_SCADA boilerplate (zoom controls, markdown tooltip, pan/wheel events, element color/state/priority tag bindings, display filters, Start/Stop special-case bindings) into a new ignition-view.ts module. deployToIgnition() now produces the complete view.json instead of a minimal skeleton. Also adds ignitionViewPath to the store/toolbar and routes it through the deploy endpoint so views land under the correct sub-folder (e.g. DetailedView/MCM09). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
3f122d9177
commit
0f50ab27ae
@ -207,7 +207,11 @@
|
||||
<div class="section-body">
|
||||
<div class="inline-row">
|
||||
<label>Project</label>
|
||||
<input type="text" bind:value={layout.ignitionProject} placeholder="Testing_Project">
|
||||
<input type="text" bind:value={layout.ignitionProject} placeholder="CDW5_SCADA">
|
||||
</div>
|
||||
<div class="inline-row">
|
||||
<label>Path</label>
|
||||
<input type="text" bind:value={layout.ignitionViewPath} placeholder="DetailedView">
|
||||
</div>
|
||||
<div class="inline-row">
|
||||
<label>View</label>
|
||||
|
||||
@ -2,6 +2,7 @@ import { layout } from './stores/layout.svelte.js';
|
||||
import { isEpcType, isInductionType, isSpurType, isCurvedType, isRectConveyanceType, isExtendoType, isPhotoeyeType, getSymbolGroup, EPC_CONFIG, INDUCTION_CONFIG, PHOTOEYE_CONFIG, EXTENDO_CONFIG, LABEL_CONFIG, CONVEYANCE_STYLE, getCurveGeometry } from './symbols.js';
|
||||
import { serializeSymbol, deserializeSymbol } from './serialization.js';
|
||||
import { parseConveyanceLabel } from './label-utils.js';
|
||||
import { buildIgnitionViewJson } from './ignition-view.js';
|
||||
import type { PlacedSymbol } from './types.js';
|
||||
|
||||
/** Emit conveyance label text inside a <g> — inherits outer transform from group */
|
||||
@ -556,27 +557,12 @@ export async function exportIgnitionJSON() {
|
||||
/** Deploy directly to Ignition project directory */
|
||||
export async function deployToIgnition() {
|
||||
const component = await buildIgnitionComponent();
|
||||
const projectName = layout.ignitionProject || 'Testing_Project';
|
||||
const projectName = layout.ignitionProject || 'CDW5_SCADA';
|
||||
const viewName = layout.ignitionViewName || layout.currentMcm || 'MCM01';
|
||||
const viewPath = layout.ignitionViewPath || 'DetailedView';
|
||||
|
||||
const viewJson = JSON.stringify({
|
||||
custom: {},
|
||||
params: {},
|
||||
props: {
|
||||
defaultSize: { height: layout.canvasH, width: layout.canvasW },
|
||||
},
|
||||
root: {
|
||||
children: [{
|
||||
meta: { name: viewName },
|
||||
position: { width: 1, height: 1 },
|
||||
props: component.props,
|
||||
type: 'ia.shapes.svg',
|
||||
}],
|
||||
meta: { name: 'root' },
|
||||
props: { mode: 'percent' },
|
||||
type: 'ia.container.coord',
|
||||
},
|
||||
}, null, 2);
|
||||
const viewData = buildIgnitionViewJson(viewName, component);
|
||||
const viewJson = JSON.stringify(viewData, null, 2);
|
||||
|
||||
// Compute SHA-256 signature of view.json for Ignition resource integrity
|
||||
const viewBytes = new TextEncoder().encode(viewJson);
|
||||
@ -603,7 +589,7 @@ export async function deployToIgnition() {
|
||||
const resp = await fetch('/api/deploy-ignition', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ projectName, viewName, viewJson, resourceJson }),
|
||||
body: JSON.stringify({ projectName, viewName, viewPath, viewJson, resourceJson }),
|
||||
});
|
||||
const result = await resp.json();
|
||||
if (result.ok) {
|
||||
|
||||
661
svelte-app/src/lib/ignition-view.ts
Normal file
661
svelte-app/src/lib/ignition-view.ts
Normal file
File diff suppressed because one or more lines are too long
@ -26,8 +26,9 @@ class LayoutStore {
|
||||
currentMcm = $state<string>('');
|
||||
|
||||
// Ignition export settings
|
||||
ignitionProject = $state<string>('Testing_Project');
|
||||
ignitionProject = $state<string>('CDW5_SCADA');
|
||||
ignitionViewName = $state<string>('');
|
||||
ignitionViewPath = $state<string>('DetailedView');
|
||||
|
||||
// PDF state
|
||||
pdfScale = $state(1.0);
|
||||
|
||||
@ -263,9 +263,10 @@ export default defineConfig({
|
||||
req.on('data', (chunk: Buffer) => { body += chunk.toString(); });
|
||||
req.on('end', () => {
|
||||
try {
|
||||
const { projectName, viewName, viewJson, resourceJson } = JSON.parse(body);
|
||||
const { projectName, viewName, viewPath, viewJson, resourceJson } = JSON.parse(body);
|
||||
const ignitionBase = 'C:/Program Files/Inductive Automation/Ignition/data/projects';
|
||||
const viewDir = path.join(ignitionBase, projectName, 'com.inductiveautomation.perspective/views', viewName);
|
||||
const viewSubPath = viewPath ? `${viewPath}/${viewName}` : viewName;
|
||||
const viewDir = path.join(ignitionBase, projectName, 'com.inductiveautomation.perspective/views', viewSubPath);
|
||||
fs.mkdirSync(viewDir, { recursive: true });
|
||||
fs.writeFileSync(path.join(viewDir, 'view.json'), viewJson);
|
||||
fs.writeFileSync(path.join(viewDir, 'resource.json'), resourceJson);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user