/** Example configuration file for VILLASnode. * * This example includes all valid configuration options for the server. * Please note, that using all options at the same time does not really * makes sense. The purpose of this example is to serve as a reference. * * The syntax of this file is similar to JSON. * A detailed description of the format can be found here: * http://www.hyperrealm.com/libconfig/libconfig_manual.html#Configuration-Files * * @author Steffen Vogel * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC * @license GNU General Public License (version 3) * * VILLASnode * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . *********************************************************************************/ # Some global settings are used by multiple configuration files # and therefore defined in separate files @include "global.conf" @include "plugins.conf" ############ Dictionary of nodes ############ nodes = { udp_node = { # The dictionary is indexed by the name of the node. type = "socket", # For a list of available node-types run: 'villas-node -h' vectorize = 30, # Receive and sent 30 samples per message (combining). samplelen = 10 # The maximum number of samples this node can receive builtin = false, # By default, all nodes will have a few builtin hooks attached to them. # When collecting statistics or measurements these are undesired. hooks = ( { type = "stats", warmup = 100, # The first 100 samples are used to estimate bounds for the histograms format = "human", # One of: human, json, matlab bucket = 30, # The number of buckets for the histograms verbose = true # Plot histograms during shutdown } ), ### The following settings are specific to the socket node-type!! ### layer = "udp", # Layer can be one of: # - udp Send / receive L4 UDP packets # - ip Send / receive L3 IP packets # - eth Send / receive L2 Ethernet frames (IEEE802.3) format = "gtnet.fake", # For a list of available node-types run: 'villas-node -h' verify_source = true, # Check if source address of incoming packets matches the remote address. local = "127.0.0.1:12001", # This node only received messages on this IP:Port pair remote = "127.0.0.1:12000", # This node sents outgoing messages to this IP:Port pair netem = { # Network emulation settings enabled = true, # Those settings can be specified for each node invidually! delay = 100000, # Additional latency in microseconds jitter = 30000, # Jitter in uS distribution = "normal", # Distribution of delay: uniform, normal, pareto, paretonormal loss = 10 # Packet loss in percent duplicate = 10, # Duplication in percent corrupt = 10 # Corruption in percent }, multicast = { # IGMP multicast is only support for layer = (ip|udp) enabled = true, group = "224.1.2.3", # The multicast group. Must be within 224.0.0.0/4 interface = "1.2.3.4", # The IP address of the interface which should receive multicast packets. ttl = 128, # The time to live for outgoing multicast packets. loop = false, # Whether or not to loopback outgoing multicast packets to the local host. } }, ethernet_node = { type = "socket", # See above. ### The following settings are specific to the socket node-type!! ### layer = "eth", local = "12:34:56:78:90:AB%eth0:12002", remote = "12:34:56:78:90:AB%eth0:12002" }, unix_domain_node = { type = "socket", layer = "unix", # Datagram UNIX domain sockets require two endpoints local = "/var/run/villas-node/node.sock", remote = "/var/run/villas-node/client.sock" }, opal_node = { # The server can be started as an Asynchronous process type = "opal", # from within an OPAL-RT model. ### The following settings are specific to the opal node-type!! ### send_id = 1, # It's possible to have multiple send / recv Icons per model recv_id = 1, # Specify the ID here. reply = true }, file_node = { type = "file", ### The following settings are specific to the file node-type!! ### uri = "logs/input.log", # These options specify the path prefix where the the files are stored epoch_mode = "direct" # One of: direct (default), wait, relative, absolute epoch = 10 # The interpretation of this value depends on epoch_mode (default is 0). # Consult the documentation of a full explanation rate = 2.0 # A constant rate at which the lines of the input files should be read # A missing or zero value will use the timestamp in the first column # of the file to determine the pause between consecutive lines. }, ngsi_node = { type = "ngsi", ### The following settings are specific to the ngsi node-type!! ### endpoint = "http://46.101.131.212:1026",# The HTTP REST API endpoint of the FIRWARE context broker entity_id = "S3_ElectricalGrid", entity_type = "ElectricalGridMonitoring", timeout = 5, # Timeout of HTTP request in seconds (default is 1) verify_ssl = false, # Verification of SSL server certificates (default is true) mapping = [ # Format: "AttributeName(AttributeType)" "PTotalLosses(MW)", "QTotalLosses(Mvar)" ] }, websocket_node = { type = "websocket", destinations = [ "http://example.com/node-name1", "https://example.com/another-node" ] }, nanomsg_node = { type = "nanomsg", publish = [ "tcp://*:12000", # TCP socket "ipc:///tmp/test.ipc", # Interprocess communication "inproc://test" # Inprocess communication ], subscribe = [ "tcp://127.0.0.1:12000", "ipc:///tmp/test.ipc", "inproc://test" ] }, zeromq_node = { type = "zeromq", pattern = "pubsub", # The ZeroMQ pattern. One of pubsub, radiodish ipv6 = false, # Enable IPv6 support filter = "ab184", # A filter which is prefix matched curve = { # Z85 encoded Curve25519 keys enabled = true, public_key = "Veg+Q.V-c&1k>yVh663gQ^7fL($y47gybE-nZP1L", secret_key = "HPY.+mFuB[jGs@(zZr6$IZ1H1dZ7Ji*j>oi@O?Pc" } subscribe = "tcp://*:1234" # The subscribe endpoint. # See http://api.zeromq.org/2-1:zmq-bind for details. publish = [ # The publish endpoints. "tcp://localhost:1235", # See http://api.zeromq.org/2-1:zmq-connect for details. "tcp://localhost:12444" ], }, signal_node = { type = "signal", signal = "sine", # One of: sine, square, ramp, counter, constant, triangle, random, mixed, constant" values = 4, # Number of values per sample amplitude = 2.3, # Amplitude of generated signals frequency = 10, # Frequency of generated signals stddev = 2, # Standard deviation of random signals (normal distributed) rate = 10.0, # Sample rate offset = -4.5 # DC bias / Offset }, loopback_node = { type = "loopback", # A loopback node will receive exactly the same data which has been sent to it. # The internal implementation is based on queue. queuelen = 1024 # The queue length of the internal queue which buffers the samples. samplelen = 64 # Each buffered sample can contain up to 64 values. }, shmem_node = { type = "shmem", in_name = "sn1_in", # Name of shared memory segment for receiving side out_name = "sn1_in", # Name of shared memory segment for sending side queuelen = 1024, # Length of the queues polling = true, # We can busy-wait or use pthread condition variables for synchronizations # Execute an external process when starting the node which # then starts the other side of this shared memory channel # Usually we also pass the shmem names as parameters. exec = [ "villas-shmem", "sn1_in", "sn1_out" ] }, stats_node = { # The "stats" node-type streams statistics of a second node type = "stats", node = "udp_node", rate = "2" }, rtt_node = { # The "test_rtt" node-type runs a set of test cases for varying type = "test_rtt", # sending rates, number of values and generates statistics. cooldown = 2, # The cooldown time between each test case in seconds prefix = "test_rtt", # An optional prefix in the filename output = "/tmp/results/testA", # The output directory for all results # The results of each test case will be written to a seperate file. format = "villas.human", # The output format of the result files. cases = ( # The list of test cases # Each test case can specify a single or an array of rates and values # If arrays are used, we will generate multiple test cases with all # possible combinations { rates = 55.0, # The sending rate in Hz values = 5, # The number of values which should be send in each sample limit = 100 # The number of samples which should be send during this test case }, { rates = [ 5, 10, 30 ], # An array of rates in Hz values = [ 2, 10, 20 ],# An array of number of values duration = 5 # The duration of the test case in seconds (depending on the sending rate) } ) }, influxdb_node = { type = "influxdb", server = "localhost:8089", key = "villas", out = { signals = ( # The signal name will be used as fields for the InfluxDB { name = "a" }, { name = "b" }, { name = "c" }, } } }, amqp_node = { type = "amqp", format = "json", # Use 'amqps://' to enable SSL/TLS uri = "amqp://guest:guest@localhost:5672//", # Alternatively connection settings can be specified individually username = "guest", password = "guest", host = "localhost", vhost = "/", port = 5672, exchange = "mytestexchange", routing_key = "abc", ssl = { verify_hostname = true, verify_peer = true, ca_cert = "/path/to/ca.crt", client_cert = "/path/to/client.crt", client_key = "/path/to/client.key" } }, sampled_values_node = { type = "iec61850-9-2", interface = "lo", dst_address = "01:0c:cd:01:00:01", publish = { fields = [ "float32", "float64", "int8", "int32" ], svid = "test1234", smpmod = "samples_per_second", confrev = 55 }, subscribe = { fields = [ "float32", "float64", "int8", "int32" ] } }, mqtt_node = { type = "mqtt", format = "protobuf", username = "guest", password = "guest", host = "localhost", port = 1883, keepalive = 5, # Send ping every 5 seconds to keep connection alive retain = false, qos = 0, publish = "test-topic", subscribe = "test-topic", ssl = { enabled = false, insecure = true, cafile = "/etc/ssl/certs/ca-bundle.crt", certfile = "/etc/ssl/certs/my.crt", keyfile = "/etc/ssl/keys/my.key" } } }; ############ List of paths ############ paths = ( { enabled = true, # Enable this path (default: true) reverse = true, # Setup a path in the reverse direction as well (default: false) in = "acs", # Name of the node we receive messages from (see node dictionary) out = "sintef", # Name of the node we send messages to. rate = 100, # Send message over this path with a fixed (constant) rate (default: 0). # Setting this value to 0 will disable this feature. queuelen = 128, mode = "all", # When this path should be triggered # - "all": After all masked input nodes received new data # - "any": After any of the masked input nodes received new data mask = [ "acs" ], # A list of input nodes which will trigger the path rate = 10.0 # A rate at which this path will be triggered if no input node receives new data }, { enabled = false, reverse = false, in = [ # Multiple source nodes are multiplexed "opal_node.data[0-4]", "signal_node.data[0-4]" ], out = [ # Multiple destination nodes are supported too. "udp_node", # All destination nodes receive the same sample "zeromq_node" # Which gets constructed by the 'in' mapping. ] }, { in = "socket_node", out = "file_node", # This path includes all available example hooks. builtin = false, # By default, all paths will have a few builtin hooks attached to them. # When collecting statistics or measurements these are undesired. # A complete list of supported hooks hooks = ( { type = "print" output = "stdout" priority = 0 }, { type = "ts" priority = 1 }, { type = "decimate" ratio = 2 # Only forward every 2nd message }, { type = "convert" mask = 0x1 # only convert the first value mode = "fixed" # Convert all values to fixed precission. Use 'float' to convert to floating point. scale = 1.0 }, { type = "skip_first" seconds = 10 # Skip the first 10 seconds of this path # samples = 1000 # Skip the first 1000 samples }, { type = "shift" mode = "origin", # Shift origin timestam of samples by +10 seconds offset = 10 # Seconds }, { # Remap values within a sample. type = "map", # The values of the new samples are constructed # from a concatenation of the following mapping entries. map = [ "data[0]", # The first value of the original sample "data[2-5]", # Values 3-6 of the original sample "hdr.sequence", # The sequence no of the original sample "hdr.length", # The number of values of the original sample "hdr.id", # The id of the original sample "hdr.format", # A bitmask of the format of each value "ts.origin", # The timestamp as sent by the origin simulator "ts.received", # The timestamp of the arrival time of the original sample "ts.send", # The timestamp when this sample was sent (does not work) # Statistics of the current path. Allowed stats are: # owd One-way-delay (OWD) of received messages # gap_sample Inter-message timestamps (as sent by remote) # gap_received Inter-message arrival time (as seen by this instance) # reordered Reordered samples and the distance between them # skipped Skipped samples by hooks and the distance between them # For each stats the following details are available: "stats.owd.last", # The last ovserved value "stats.owd.highest", # The highest observed value "stats.owd.lowest", # The lowest observed value "stats.owd.mean", # The average observed value "stats.owd.var", # The variance of the observed value "stats.owd.stddev", # The standard deviation of the observed value "stats.owd.total" # The total number ob observed values ] } ) } );