/** 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 <stvogel@eonerc.rwth-aachen.de>
 * @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 <http://www.gnu.org/licenses/>.
 *********************************************************************************/

# 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",			# Type can be one of: socket, opal, file, gtfpga, ngsi
							# Start the server without arguments for a list of supported node types.

	### The following settings are specific to the socket node-type!! ###

		layer	= "udp",			# Layer can be one of:
							#   udp                    Send / receive UDP packets
							#   ip                     Send / receive IP packets
							#   eth                    Send / receive raw Ethernet frames (IEEE802.3)

		header	= "gtnet-skt:fake",		# Header can be one of:
							#   default | villas       Use VILLASnode protocol (see struct msg) (default)
							#   none | gtnet-skt       Use no header, send raw data as used by RTDS GTNETv2-SKT
							#   fake | gtnet-skt:fake  Same as 'none', but use first three data values as
							#                             sequence, seconds & nanoseconds timestamp
							#                             In this mode values are uint32_t not floats!

		endian = "network",			# Endianess of header and data:
							#   big | network          Use big endianess. Also know as network byte order (default)
							#   little                 Use little endianess.

		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

		vectorize = 30,				# Receive and sent 30 samples per message (combining).

		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"
	},
	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!! ###

		in = {
			uri = "logs/input.log",	# These options specify the path prefix where the the files are stored
			mode = "r",			# The mode in which files should be opened (see open(2))

			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.
		},
		out = {
			uri = "logs/output_%F_%T.log"	# The output path accepts all format tokens of (see strftime(3))
			mode = "a+"			# You might want to use "a+" to append to a file
		}
	},
	gtfpga_node = {
		type = "gtfpga",

	### The following settings are specific to the gtfpga node-type!! ###

		slot = "01:00.0",			# The PCIe slot location (see first column in 'lspci' output)
		id = "1ab8:4005",			# The PCIe vendor:device ID (see third column in 'lspci -n' output)

		rate = 1
	},
	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. See http://api.zeromq.org/2-1:zmq-connect for details.
			"tcp://localhost:1235",
			"tcp://localhost:12444"
		],
	},
	signal_node = {
		type = "signal",

		signal = "sine",			# One of "sine", "ramp", "triangle", "random", "mixed"
		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
	},
	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.
	}
};


############       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,
		samplelen = 64
	},
	{
		enabled = false,
		reverse = false,

		in = "opal_node",			# There's only a single source node allowed!
		out = [ "udp_node", "tcp_node" ],	# Multiple destination nodes are supported too.
	},
	{
		in = "socket_node",
		out = "file_node",			# This path includes all available example hooks.

		# 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
			}
		)
	}
);