PortDic
Document-based application development platform with visual equipment model editor and integrated message broker for device communication.

📦 Repository: https://github.com/portget/portdic_vs_extension
🐛 Issues: https://github.com/portget/portdic_vs_extension/issues
🌐 Marketplace: https://marketplace.visualstudio.com/items?itemName=portroconn.portdic
About PortDic
PortDic enables users to easily develop applications using document files alone, offering an in-memory database that eliminates the need for queries. With the motto "Documents Made Simple. Applications Built Fast", PortDic empowers users to implement OPC UA, SECS, MQTT, REST APIs, and script-based flow control through straightforward document creation.
Features
🏭 Equipment Model Editor (SEMI E120/E126)
- Visual tree editor for equipment hierarchy
- SEMI E120 compliance (Equipment → Module → Subsystem → IODevice/LogicalElement)
- E126 Health & Maintenance data tracking
- Real-time XML synchronization
📊 FA Document Editor (Factory Automation)
- Excel-like spreadsheet interface for 8 SECS/GEM data types:
- DVID - Data Value ID
- SVID - Status Variable ID
- ECID - Equipment Constant ID
- RPTID - Report ID
- CEID - Collection Event ID
- RCMD - Remote Command
- ALID - Alarm ID
- DATAITEM - Generic Data Item
- Auto-complete for relational data (RPTID → SVID, CEID → RPTID)
- Excel export (.xlsx)
- XML file format for version control
📡 Message Broker & Device Communication
- TCP/IP, RS232, RS485 protocol support
- SECS/GEM message simulation
- Python script integration (RustPython)
- Scenario-based testing with breakpoints
- Real-time message logging
Installation
From VSCode Marketplace
- Open VSCode
- Press
Ctrl+Shift+X to open Extensions
- Search for "PortDic"
- Click Install
From VSIX File
code --install-extension portdic-0.1.0.vsix
Quick Start
Get started with PortDic in 5 minutes! This guide shows you how to create an equipment model and test device communication.
Option 1: Equipment Model Editor (Visual Tree Editor)
Step 1: Create Equipment Model File
- Press
Ctrl+Shift+P (Command Palette)
- Type "PortDic: New EQ File"
- Enter filename:
my-equipment.eq
- Visual tree editor opens automatically
Step 2: Build Equipment Hierarchy
- Click + button on root "Equipment" node
- Select Module → Enter name: "EFEM"
- Click + on "EFEM" module → Select Subsystem → Name: "Robot"
- Click + on "Robot" → Select IODevice → Name: "Sensor1"
Result: You now have a complete E120 hierarchy:
Equipment (root)
└─ EFEM (Module)
└─ Robot (Subsystem)
└─ Sensor1 (IODevice)
Step 3: Add Health & Maintenance Data
- Select "Robot" subsystem in tree
- In property panel (right side), scroll to Health & Maintenance:
- Last Maintenance:
2024-01-15
- Maintenance Interval:
90 days
- Health Score:
95
- Maintenance State:
Operational
- Press
Ctrl+S to save
Step 4: View XML Output
- Press
Ctrl+Shift+P → "View XML Source" to see generated E120/E126 XML
Option 2: Device Communication (Message Broker)
Step 1: Create Device File
- Right-click any folder in Explorer
- Select "New Device File (.device)"
- Enter filename:
test-device.device
Step 2: Configure Connection
Copy this complete example into test-device.device:
<?xml version="1.0" encoding="UTF-8"?>
<Message id="demo-device" name="Quick Start Demo">
<Protocol>TCP</Protocol>
<Description>Simple TCP echo test for Quick Start</Description>
<Connection>
<Type>TCP</Type>
<Host>localhost</Host>
<Port>5000</Port>
<Timeout>3000</Timeout>
</Connection>
<Data>
<!-- Message to send -->
<Message key="msg-hello">
Hello World[CR][LF]
</Message>
<!-- Expected response -->
<Message key="msg-echo">
Hello World[CR][LF]
</Message>
<!-- Rhai script (optional) -->
<Script>
fn getCurrentTime() {
"2024-01-15 12:00:00"
}
</Script>
<!-- Test scenario -->
<Scenario key="scenario-1" name="Echo Test" repeat="1">
<Send message="msg-hello"/>
<Recv message="msg-echo" timeout="5000" timeout-message="No response from server"/>
</Scenario>
</Data>
</Message>
Step 3: Run the Test
- Open PortDic Files view (sidebar icon)
- Find your
test-device.device file
- Click Connect icon (🔌) on the device
- Expand device → Data → Click Play icon (▶️) on "scenario-1"
- Watch results in Console view:
✅ Step 1 (send): Sent 13 bytes
HEX: 48 65 6C 6C 6F 20 57 6F 72 6C 64 0D 0A
ASCII: 'Hello World..'
✅ Step 2 (recv): Received 13 bytes (matched)
Step 4: Send Individual Messages (Alternative)
- Expand device → Data → Message nodes
- Click Send icon (📤) on "msg-hello" to send without scenario
Next Steps
Equipment Model:
- Add more modules and subsystems
- Experiment with drag & drop to reorganize nodes
- Export equipment data for OPC UA or SECS/GEM integration
Device Communication:
- Try RS232 protocol (see Serial Example)
- Add Rhai scripts for dynamic message generation
- Use
{:} placeholders with value="5,3" for parameterized messages
- Chain multiple Send/Recv steps in scenarios
Learn More:
Usage
Equipment Model Editing
Creating Files
Command Palette (Ctrl+Shift+P):
- "PortDic: New equipment model file (.eq)"
- Enter filename ending with
.eq
Explorer Context Menu:
- Right-click folder → "New EQ File"
PortDic Files View:
Editing Hierarchy
- Open
.eq file → Visual editor opens automatically
- Add nodes: Click + button on parent node
- Edit properties: Select node → Edit in property panel
- Reorganize: Drag & drop nodes (follows E120 rules)
- Delete: Right-click node → Delete
- Rename: Select node → Edit name in property panel
FA Document Editor
The FA Document Editor provides an Excel-like spreadsheet interface for editing SECS/GEM Factory Automation data. Perfect for managing equipment data values, status variables, events, and commands.
Creating FA Documents
From FA Folder (Recommended):
- Navigate to "PortDic Files" view in sidebar
- Click + button on FA folder
- Select FA document type (DVID, SVID, ECID, RPTID, CEID, RCMD, ALID, DATAITEM)
- Enter filename (extension added automatically)
Command Palette:
- Press
Ctrl+Shift+P
- "PortDic: New FA Document"
- Select type → Enter filename
FA Document Types
| Type |
Extension |
Description |
Use Case |
| DVID |
.dvid |
Data Value ID |
Equipment data values (temperature, pressure, etc.) |
| SVID |
.svid |
Status Variable ID |
Equipment status variables (voltage, current, etc.) |
| ECID |
.ecid |
Equipment Constant ID |
Equipment constants and configuration parameters |
| RPTID |
.rptid |
Report ID |
Data collection reports (references SVIDs) |
| CEID |
.ceid |
Collection Event ID |
Equipment events (references RPTIDs and SVIDs) |
| RCMD |
.rcmd |
Remote Command |
Equipment remote commands |
| ALID |
.alid |
Alarm ID |
Equipment alarms and error codes |
| DATAITEM |
.dataitem |
Data Item |
Generic data items |
Editing FA Documents
Grid Interface:
- Double-click cell to edit
- Tab/Enter to navigate
- Right-click row number → Insert/Delete row
- All changes auto-save to XML
Auto-Complete (RPTID & CEID):
- Dropdown automatically populated from workspace
.svid and .rptid files
- Select ID → Name field auto-fills
- Example: RPTID "1" → SVID dropdown shows all SVIDs → Select "1" → SVIDName auto-fills "Voltage"
Excel Export:
- Click Export Excel button (top-right)
- Downloads
.xlsx file with formatted headers and borders
- Filename:
{TYPE}_{DATE}.xlsx (e.g., SVID_2024-01-15.xlsx)
Example: Creating SVID Document
Step 1: Create File
FA folder → + button → Select "SVID" → Name: "equipment-status.svid"
Step 2: Edit Grid
| SVID | Name | Desc | Format | Size | Units | Min | Max |
|------|------|------|--------|------|-------|-----|-----|
| 1 | Voltage | Supply voltage | F4 | 4 | V | 0 | 24 |
| 2 | Current | Supply current | F4 | 4 | A | 0 | 10 |
Step 3: Save & Export
- Auto-saves to XML:
Ctrl+S
- Export Excel: Click Export Excel button
XML Output (equipment-status.svid):
<?xml version="1.0" encoding="UTF-8"?>
<FADocument type="SVID">
<Row SVID="1" Name="Voltage" Desc="Supply voltage" Format="F4" Size="4" Units="V" Min="0" Max="24"/>
<Row SVID="2" Name="Current" Desc="Supply current" Format="F4" Size="4" Units="A" Min="0" Max="10"/>
</FADocument>
Relational Data Example (RPTID)
When creating RPTID documents, the editor auto-populates SVID dropdowns from existing .svid files:
- Create
equipment-status.svid with SVID 1 (Voltage), SVID 2 (Current)
- Create new RPTID file
- In SVID column, dropdown shows:
1 - Voltage
2 - Current
- Select "1" → SVIDName automatically fills "Voltage"
Result:
| RPTID | Name | SVID | SVIDName | Desc |
|-------|------|------|----------|------|
| 100 | StatusReport | 1 | Voltage | Equipment status monitoring |
Message Broker
Creating Device Files
- Right-click folder → "New Device File (.device)"
- All device types use
.device extension
- Protocol is specified inside the file (RS232/RS485/TCP/SECS)
Serial (RS232/RS485) Example
<Message id="serial1" name="Serial Test">
<Protocol>RS232</Protocol>
<Connection>
<Type>RS232</Type>
<Port>COM3</Port>
<BaudRate>9600</BaudRate>
<DataBits>8</DataBits>
<StopBits>1</StopBits>
<Parity>None</Parity>
</Connection>
<Data>
<Message key="msg-send">
{'addNum({:},{:})'}HELLO[CR][LF]
</Message>
<Message key="msg-recv">
OK[CR][LF]
</Message>
<Script>
fn addNum(n1, n2) {
n1 + n2
}
</Script>
<Scenario key="scenario-1" name="Test Scenario" repeat="1">
<Send message="msg-send" value="5,3"/>
<Recv message="msg-recv" timeout="5000" timeout-message="No response from device"/>
</Scenario>
</Data>
</Message>
Send: '8'HELLO\r\n → 0x38 0x48 0x45 0x4C 0x4C 0x4F 0x0D 0x0A
Receive: Waits for OK\r\n with 5 second timeout
TCP/IP Example
<Message id="tcp1" name="TCP Test">
<Protocol>TCP</Protocol>
<Connection>
<Type>TCP</Type>
<Host>192.168.1.100</Host>
<Port>5000</Port>
</Connection>
<Data>
<Message key="msg-calculate">
{multiplyNum({:},{:})}[0x00][0xFF]
</Message>
<Message key="msg-response">
ACK[CR][LF]
</Message>
<Script>
fn multiplyNum(a, b) {
a * b
}
</Script>
<Scenario key="scenario-1" name="Calculate Test" repeat="1">
<Send message="msg-calculate" value="10,20"/>
<Recv message="msg-response" timeout="3000" timeout-message="Server timeout"/>
</Scenario>
</Data>
</Message>
Send: 200[0x00][0xFF] → 0xC8 0x00 0xFF (raw byte mode)
Receive: Waits for ACK\r\n with 3 second timeout
Message Syntax
| Syntax |
Description |
Example |
{:} |
Placeholder for value |
value="5,3" → replaces first {:} with 5, second with 3 |
{func()} |
Raw byte mode |
{addNum(1,2)} → 0x03 (single byte) |
{'func()'} |
String mode |
{'addNum(1,2)'} → 0x33 (ASCII '3') |
{script-key.func()} |
Script reference |
{script-1.Test()} → calls Test() from Script with key="script-1" |
[CR] |
Carriage return |
0x0D |
[LF] |
Line feed |
0x0A |
[0xHH] |
Hex byte |
[0x1B] → 0x1B |
Script Reference Example:
<Data>
<Message key="msg-hello">
{script-1.Test()}Hello[CR][LF]
</Message>
<Message key="msg-version">
{'script-2.GetVersion()'}[CR][LF]
</Message>
<Script key="script-1" name="Test Script">
fn Test() {
return 1; // Returns number
}
</Script>
<Script key="script-2" name="Version Script">
fn GetVersion() {
return "v1.0"; // Returns string
}
</Script>
</Data>
Script Return Values:
{script-1.Test()} → Returns 1 → Converts to raw byte 0x01
{'script-2.GetVersion()'} → Returns "v1.0" → Inserts as string v1.0 (ASCII bytes)
Note: Script functions can return both numbers and strings:
- Numbers:
return 1; or return 42;
- Strings:
return "hello"; or return "v1.0";
- In raw byte mode
{func()}, numeric values or numeric strings are converted to bytes (0-255)
- In string mode
{'func()'}, all return values are inserted as ASCII text
Scenario Elements
| Element |
Attributes |
Description |
<Scenario> |
key, name, repeat |
Defines a test scenario with send/receive sequence |
<Send> |
message, value |
Sends a message (references Message key) |
<Recv> |
message, timeout, timeout-message |
Receives and validates a message with timeout |
Device File Structure in FILES View
When you open a device file (.device) in the PortDic Files view, it shows a structured tree:
📁 MyDevice.device
└─ 📂 Data
├─ 📬 msg-send (Message)
├─ 📬 msg-recv (Message)
├─ 💻 Script
└─ ▶️ scenario-1 (Scenario)
- Message nodes: Click Send icon (📤) to send individual messages
- Scenario nodes: Click Play icon (▶️) to run full test sequence
- Script nodes: Contains Rhai functions used by messages
Running Scenarios
- Open device file in PortDic Files view
- Click Connect icon (🔌) on device file to establish connection
- Expand device file → Data node to see structure
- Expand Data to see Scenario nodes
- Click Play icon (▶️) on Scenario node to execute the full sequence
- While running, the Play icon changes to Stop icon (⏹️)
- Click Stop icon to cancel the running scenario
- Watch step-by-step execution in Console view:
- ✅ Step 1 (send): Message sent successfully
- ✅ Step 2 (recv): Response received
- Or ❌ with timeout message if device doesn't respond
- Each step shows hex data, ASCII representation, and connection info
Sending Individual Messages
- Expand device file → Data section
- Expand Data to see Message nodes
- Click Send icon (📤) on individual Message node
- View results in Console view
Equipment Model (.eq)
<?xml version="1.0" encoding="UTF-8"?>
<Equipment id="eq-001" name="Semiconductor Tool">
<Module id="mod-001" name="EFEM">
<Subsystem id="sub-001" name="Robot"
lastMaintenance="2024-01-15"
maintenanceInterval="90"
healthScore="95"
maintenanceState="Operational">
<IODevice id="io-001" name="Sensor1" />
</Subsystem>
</Module>
</Equipment>
E120 Hierarchy Rules
Strict parent-child relationships are enforced:
| Parent |
Allowed Children |
| Equipment (root) |
Module |
| Module |
Subsystem |
| Subsystem |
IODevice, LogicalElement |
| IODevice |
None (terminal node) |
| LogicalElement |
None (terminal node) |
Node Descriptions:
- Equipment: Root node representing the entire system
- Module: Independent functional unit (e.g., EFEM, Process Chamber)
- Subsystem: Sub-device within a module (e.g., Robot, Load Port, Gas Box)
- IODevice: Physical I/O device (sensors, actuators)
- LogicalElement: Logical software module or control logic
E126 Health & Maintenance
Optional properties on any node:
- Last Maintenance: Date of last maintenance (ISO 8601)
- Maintenance Interval: Days between maintenance (number)
- Health Score: 0-100 (number)
- Maintenance State: Operational | Maintenance | Degraded | Failed
Keyboard Shortcuts
| Shortcut |
Action |
Context |
F2 |
Rename file |
PortDic Files view |
Requirements
- VSCode: 1.78.0 or higher
- OS: Windows, Linux, macOS
- Serial Communication: Serial port access for RS232/RS485
Supported File Types
| Extension |
Description |
Editor Type |
Auto-association |
.eq |
Equipment model file |
Visual tree editor |
XML syntax |
.device |
Device communication file (RS232/RS485/TCP/SECS) |
Text editor |
XML syntax |
.dvid |
Data Value ID (FA document) |
Spreadsheet grid |
XML syntax |
.svid |
Status Variable ID (FA document) |
Spreadsheet grid |
XML syntax |
.ecid |
Equipment Constant ID (FA document) |
Spreadsheet grid |
XML syntax |
.rptid |
Report ID (FA document) |
Spreadsheet grid |
XML syntax |
.ceid |
Collection Event ID (FA document) |
Spreadsheet grid |
XML syntax |
.rcmd |
Remote Command (FA document) |
Spreadsheet grid |
XML syntax |
.alid |
Alarm ID (FA document) |
Spreadsheet grid |
XML syntax |
.dataitem |
Data Item (FA document) |
Spreadsheet grid |
XML syntax |
Known Issues
- Large equipment models (>1000 nodes) may experience slower rendering
- Serial port names must be exact:
- Windows:
COM3, COM4, etc.
- Linux:
/dev/ttyUSB0, /dev/ttyS0, etc.
- macOS:
/dev/tty.usbserial-*
- Rhai scripts have limited standard library (no file I/O, network access)
Troubleshooting
Message not sending
- Check connection settings (port name, baud rate)
- Verify port is not in use by another application
- Check Rhai script syntax (use
fn name() { } not Python syntax)
Script syntax errors
Serial port timeout
- Normal behavior when no data received (logged at DEBUG level)
- Only errors (not timeouts) are shown by default
Visual editor not opening
- Ensure file extension is exactly
.eq
- Try closing and reopening the file
- Check VSCode Output panel for errors
Release Notes
See CHANGELOG.md for version history.
Technologies
- Extension: TypeScript, VSCode Extension API, LSP (Language Server Protocol)
- Webview: React 18, Vite, Zustand, react-arborist, Tailwind CSS
- Message Broker: Rust, Tower-LSP, Rhai scripting engine, tokio async runtime
Development
For development setup and contribution guidelines, see CLAUDE.md.
License
MIT License - see LICENSE file for details
Support
For support, bug reports, or feature requests:
- PortDic - Core document-based application development platform
- PortDic SECS Autocomplete - SECS/GEM message autocomplete and documentation
Enjoy using PortDic! 🚀