351 lines
13 KiB
JSON
351 lines
13 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"title": "ICS-SimLab configuration.json (observed from examples)",
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": [
|
|
"ui",
|
|
"hmis",
|
|
"plcs",
|
|
"sensors",
|
|
"actuators",
|
|
"hils",
|
|
"serial_networks",
|
|
"ip_networks"
|
|
],
|
|
"properties": {
|
|
"ui": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["network"],
|
|
"properties": {
|
|
"network": { "$ref": "#/$defs/network_ui" }
|
|
}
|
|
},
|
|
"hmis": { "type": "array", "items": { "$ref": "#/$defs/hmi" } },
|
|
"plcs": { "type": "array", "items": { "$ref": "#/$defs/plc" } },
|
|
"sensors": { "type": "array", "items": { "$ref": "#/$defs/sensor" } },
|
|
"actuators": { "type": "array", "items": { "$ref": "#/$defs/actuator" } },
|
|
"hils": { "type": "array", "items": { "$ref": "#/$defs/hil" } },
|
|
"serial_networks": { "type": "array", "items": { "$ref": "#/$defs/serial_network" } },
|
|
"ip_networks": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": { "$ref": "#/$defs/ip_network" }
|
|
}
|
|
},
|
|
"$defs": {
|
|
"docker_safe_name": {
|
|
"type": "string",
|
|
"pattern": "^[a-z0-9_]+$"
|
|
},
|
|
"ipv4": {
|
|
"type": "string",
|
|
"pattern": "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$"
|
|
},
|
|
"cidr": {
|
|
"type": "string",
|
|
"pattern": "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}\\/[0-9]{1,2}$"
|
|
},
|
|
|
|
"network": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["ip", "docker_network"],
|
|
"properties": {
|
|
"ip": { "$ref": "#/$defs/ipv4" },
|
|
"docker_network": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
"network_ui": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["ip", "port", "docker_network"],
|
|
"properties": {
|
|
"ip": { "$ref": "#/$defs/ipv4" },
|
|
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
|
|
"docker_network": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
|
|
"ip_network": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["docker_name", "name", "subnet"],
|
|
"properties": {
|
|
"docker_name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"subnet": { "$ref": "#/$defs/cidr" }
|
|
}
|
|
},
|
|
|
|
"serial_network": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["src", "dest"],
|
|
"properties": {
|
|
"src": { "type": "string" },
|
|
"dest": { "type": "string" }
|
|
}
|
|
},
|
|
|
|
"connection_inbound": {
|
|
"anyOf": [
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "ip", "port"],
|
|
"properties": {
|
|
"type": { "type": "string", "const": "tcp" },
|
|
"ip": { "$ref": "#/$defs/ipv4" },
|
|
"port": { "type": "integer", "minimum": 1, "maximum": 65535 }
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "slave_id", "comm_port"],
|
|
"properties": {
|
|
"type": { "type": "string", "const": "rtu" },
|
|
"slave_id": { "type": "integer", "minimum": 1 },
|
|
"comm_port": { "type": "string" }
|
|
}
|
|
}
|
|
]
|
|
},
|
|
|
|
"connection_outbound": {
|
|
"anyOf": [
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "ip", "port", "id"],
|
|
"properties": {
|
|
"type": { "type": "string", "const": "tcp" },
|
|
"ip": { "$ref": "#/$defs/ipv4" },
|
|
"port": { "type": "integer", "minimum": 1, "maximum": 65535 },
|
|
"id": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["type", "comm_port", "id"],
|
|
"properties": {
|
|
"type": { "type": "string", "const": "rtu" },
|
|
"comm_port": { "type": "string" },
|
|
"id": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
}
|
|
]
|
|
},
|
|
|
|
"reg_plc_entry": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["address", "count", "io", "id"],
|
|
"properties": {
|
|
"address": { "type": "integer", "minimum": 0 },
|
|
"count": { "type": "integer", "minimum": 1 },
|
|
"io": { "type": "string", "enum": ["input", "output"] },
|
|
"id": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
"reg_hmi_entry": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["address", "count", "id"],
|
|
"properties": {
|
|
"address": { "type": "integer", "minimum": 0 },
|
|
"count": { "type": "integer", "minimum": 1 },
|
|
"id": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
"reg_field_entry": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["address", "count", "physical_value"],
|
|
"properties": {
|
|
"address": { "type": "integer", "minimum": 0 },
|
|
"count": { "type": "integer", "minimum": 1 },
|
|
"physical_value": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
|
|
"registers_plc": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["coil", "discrete_input", "holding_register", "input_register"],
|
|
"properties": {
|
|
"coil": { "type": "array", "items": { "$ref": "#/$defs/reg_plc_entry" } },
|
|
"discrete_input": { "type": "array", "items": { "$ref": "#/$defs/reg_plc_entry" } },
|
|
"holding_register": { "type": "array", "items": { "$ref": "#/$defs/reg_plc_entry" } },
|
|
"input_register": { "type": "array", "items": { "$ref": "#/$defs/reg_plc_entry" } }
|
|
}
|
|
},
|
|
"registers_hmi": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["coil", "discrete_input", "holding_register", "input_register"],
|
|
"properties": {
|
|
"coil": { "type": "array", "items": { "$ref": "#/$defs/reg_hmi_entry" } },
|
|
"discrete_input": { "type": "array", "items": { "$ref": "#/$defs/reg_hmi_entry" } },
|
|
"holding_register": { "type": "array", "items": { "$ref": "#/$defs/reg_hmi_entry" } },
|
|
"input_register": { "type": "array", "items": { "$ref": "#/$defs/reg_hmi_entry" } }
|
|
}
|
|
},
|
|
"registers_field": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["coil", "discrete_input", "holding_register", "input_register"],
|
|
"properties": {
|
|
"coil": { "type": "array", "items": { "$ref": "#/$defs/reg_field_entry" } },
|
|
"discrete_input": { "type": "array", "items": { "$ref": "#/$defs/reg_field_entry" } },
|
|
"holding_register": { "type": "array", "items": { "$ref": "#/$defs/reg_field_entry" } },
|
|
"input_register": { "type": "array", "items": { "$ref": "#/$defs/reg_field_entry" } }
|
|
}
|
|
},
|
|
|
|
"monitor": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["outbound_connection_id", "id", "value_type", "address", "count", "interval", "slave_id"],
|
|
"properties": {
|
|
"outbound_connection_id": { "$ref": "#/$defs/docker_safe_name" },
|
|
"id": { "$ref": "#/$defs/docker_safe_name" },
|
|
"value_type": {
|
|
"type": "string",
|
|
"enum": ["coil", "discrete_input", "holding_register", "input_register"]
|
|
},
|
|
"address": { "type": "integer", "minimum": 0 },
|
|
"count": { "type": "integer", "minimum": 1 },
|
|
"interval": { "type": "number", "exclusiveMinimum": 0 },
|
|
"slave_id": { "type": "integer", "minimum": 1 }
|
|
}
|
|
},
|
|
|
|
"controller": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["outbound_connection_id", "id", "value_type", "address", "count", "interval", "slave_id"],
|
|
"properties": {
|
|
"outbound_connection_id": { "$ref": "#/$defs/docker_safe_name" },
|
|
"id": { "$ref": "#/$defs/docker_safe_name" },
|
|
"value_type": { "type": "string", "enum": ["coil", "holding_register"] },
|
|
"address": { "type": "integer", "minimum": 0 },
|
|
"count": { "type": "integer", "minimum": 1 },
|
|
"interval": { "type": "number", "exclusiveMinimum": 0 },
|
|
"slave_id": { "type": "integer", "minimum": 1 }
|
|
}
|
|
},
|
|
|
|
"hil_physical_value": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "io"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"io": { "type": "string", "enum": ["input", "output"] }
|
|
}
|
|
},
|
|
"hil": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "logic", "physical_values"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"logic": { "type": "string", "pattern": "^[^/\\\\]+\\.py$" },
|
|
"physical_values": {
|
|
"type": "array",
|
|
"minItems": 1,
|
|
"items": { "$ref": "#/$defs/hil_physical_value" }
|
|
}
|
|
}
|
|
},
|
|
|
|
"plc": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "logic", "network", "inbound_connections", "outbound_connections", "registers", "monitors", "controllers"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"logic": { "type": "string", "pattern": "^[^/\\\\]+\\.py$" },
|
|
"network": { "$ref": "#/$defs/network" },
|
|
"inbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_inbound" } },
|
|
"outbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_outbound" } },
|
|
"registers": { "$ref": "#/$defs/registers_plc" },
|
|
"monitors": { "type": "array", "items": { "$ref": "#/$defs/monitor" } },
|
|
"controllers": { "type": "array", "items": { "$ref": "#/$defs/controller" } }
|
|
}
|
|
},
|
|
|
|
"hmi": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "network", "inbound_connections", "outbound_connections", "registers", "monitors", "controllers"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"network": { "$ref": "#/$defs/network" },
|
|
"inbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_inbound" } },
|
|
"outbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_outbound" } },
|
|
"registers": { "$ref": "#/$defs/registers_hmi" },
|
|
"monitors": { "type": "array", "items": { "$ref": "#/$defs/monitor" } },
|
|
"controllers": { "type": "array", "items": { "$ref": "#/$defs/controller" } }
|
|
}
|
|
},
|
|
|
|
"sensor": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "hil", "network", "inbound_connections", "registers"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"hil": { "$ref": "#/$defs/docker_safe_name" },
|
|
"network": { "$ref": "#/$defs/network" },
|
|
"inbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_inbound" } },
|
|
"registers": { "$ref": "#/$defs/registers_field" }
|
|
}
|
|
},
|
|
|
|
"actuator_physical_value_ref": {
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" }
|
|
}
|
|
},
|
|
|
|
"actuator": {
|
|
"anyOf": [
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "hil", "network", "inbound_connections", "registers"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"hil": { "$ref": "#/$defs/docker_safe_name" },
|
|
"network": { "$ref": "#/$defs/network" },
|
|
"inbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_inbound" } },
|
|
"registers": { "$ref": "#/$defs/registers_field" }
|
|
}
|
|
},
|
|
{
|
|
"type": "object",
|
|
"additionalProperties": false,
|
|
"required": ["name", "hil", "logic", "physical_values", "network", "inbound_connections", "registers"],
|
|
"properties": {
|
|
"name": { "$ref": "#/$defs/docker_safe_name" },
|
|
"hil": { "$ref": "#/$defs/docker_safe_name" },
|
|
"logic": { "type": "string", "pattern": "^[^/\\\\]+\\.py$" },
|
|
"physical_values": { "type": "array", "items": { "$ref": "#/$defs/actuator_physical_value_ref" } },
|
|
"network": { "$ref": "#/$defs/network" },
|
|
"inbound_connections": { "type": "array", "items": { "$ref": "#/$defs/connection_inbound" } },
|
|
"registers": { "$ref": "#/$defs/registers_field" }
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
}
|