{ "$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" } } } ] } } }